개발/OpenGL / / 2022. 3. 15. 12:06

OpenGL 공부일지 - OpenGL Super Bible 텍스처 - 5

반응형

Synchronizing Access to Images

glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BIT);

버퍼와 어토믹 카운터와 같이 위 함수를 통해서 메모리 접근을 동기화할 수 있다.

Texture Compression

텍스처는 공간차지가 상당히 크다. 모든 데이터를 GPU에 로딩할 수는 없으므로, 압축하여 저장해야할 것이다.

텍스처를 압축하는 것은 이미지 데이터에서 요구하는 저장 공간을 줄일 수 있고, 그래픽스 프로세서가 압축 텍스처로부터 fetching할 때 더 적은 데이터만 읽어도 되므로 더 적은 메모리 대역폭을 필요로 한다.

위처럼 opengl에서 지원하는 압축 텍스처 포맷은 많다. opengl 드라이버의 어떤 압축 매커니즘을 사용하느냐에 따라 다르다.

대표적으로 몇 가지만 보자.

RGTC(Red-Green Texture Compression) 포멧의 경우 텍스처를 4 x 4텍셀 블록으로 분할 후 일련의 코드로 블록 내에서 채널별로 압축한다.

BPTC(Block Partitioned Texture Compression)도 마찬가지로 텍스처를 4 x 4 텍셀 블록으로 분할하고, 각 블록은 128비트의 메모리 데이터를 차지한다.

저대역폭 포멧인 ETC2, EAC 등도 있고, 필요에 따라 다른 포멧을 사용하기도 한다. 포멧을 사용할 때는 opengl에서 해당 포멧을 지원하는지 확인하도록 하자.

Using Compression

텍스처 로딩 시 opengl에 특정 포맷으로의 압축을 요청할 수 있지만, 직접 텍스처를 압축해서 파일로 저장하는 것이 더 좋다. .KTX 포맷의 경우 압축 데이터를 저장할 수 있다.

Glint imageSize = 0;
glGetTextureParameteriv(GL_TEXTURE_2D,
	GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
	&imageSize);
void *data = malloc(imageSize);
glGetCompressedTextureImage(GL_TEXTURE_2D, 0, data);

위 코드에서는 비일반 압축 내부 포맷을 사용하는 텍스처를 로딩하여 glGetCompressedTextImage()로 압축 이미지를 다시 받았다. glGetTexParameteriv()를 통해 이미지 크기를 확인하여 전체 surface를 위한 공간이 충분한지 확인한다.

Shared Exponents

공유지수 텍스처는 부동소수점 텍스처 데이터를 사용하는 경우 저장 공간을 절약할 수 있다. 공유 지수 포맷은 전체 텍셀에 대해 RGB 각각 저장하는 대신 동일한 지수를 사용한다. 공유 지수를 사용하기 위해서는 콘텐츠 저장 도구를 사용해서 텍스처 데이터를 이 포맷으로 저장하거나, 부동 소수점 RGB값을 공유 지수 포맷으로 변환하는 변환 툴을 직접 작성한다.

Texture Views

텍스처를 사용할 때, 텍스처 포맷이나 사용할 용도를 알아야 쉐이더에서 가져오는 데이터와 매칭할 수 있다. 

2D 배열 텍스처로부터 읽는 쉐이더의 경우 샘플러 유니폼을 sampler2DArray로 해야한다. 마찬가지로 정수 포맷 텍스처로부터 읽을 쉐이더는 isampler2D로 선언해야한다.

 하지만 그렇지 않고 쉐이더와 매칭되지 않는 텍스처로 로딩하는 경우도 있는데, 텍스처 뷰를 사용하면 객체간 텍스처 데이터 재사용이 가능하다.

  •  텍스처 뷰를 특정 타입의 텍스처가 다른 텍스처 타입의 텍스처인 것처럼 '위장'하는데 사용할 수 있다. 예를 들어 2D텍스처를 받아서 뷰를 만들면 한 레이어만 존재하는 2D배열 텍스처인 것처럼 사용할 수 있다.
  •  텍스처 뷰를 텍스처 객체의 데이터가 메모리상에 저장된 것과 다른 포맷인 것처럼 위장하는데 사용할 수 있다.

위 두 개념을 동시에 적용할 수도 있다. 

Creating Texture Views

void glTextureView(GLuint texture,
    GLenum target,
    GLuint origtexture,
    GLenum internalformat,
    GLuint minlevel,
    GLuint numlevels,
    GLuint minlayer,
    GLuint numlayers);

위 함수를 사용해서 텍스처 뷰를 만들 수 있다. texture는 텍스처 객체의 이름, target은 텍스처 타입, origtexture는 지정한 텍스처 타입과 호환되어야하는 타입이다. 

매개변수 중 internalformat이 있는데, 이는 새로운 텍스처 뷰의 내부 포맷을 결정한다. 원본 텍스처와 새로운 텍스처 뷰의 내부 포맷은 서로 호환되어야한다.

텍스처 뷰를 생성하면 새오누 타입의 다른 텍스처처럼 사용할 수 있다. 2D 배열 텍스처를 가지고 있을 때, 그 레이어 중 하나에 대한 2D 비배열 텍스처 뷰를 생성했다면, glTexSubImage2D()를 호출해서 데이터를 뷰에 넣을 수 있다.

또 배열 텍스처의 해당 레이어에도 동일한 데이터가 들어있을 것이다. 다른 예로, 2D 배열 텍스처의 단일 레이어에 대한 2D 비배열 텍스처 뷰를 생성해서 쉐이더에서 sampler2D 유니폼으로 액세스 가능하다. 2D 비배열 텍스처에 대한 단일 레이어 2D 배열 텍스처 뷰를 생성해서 쉐이더에서 sampler2DArray유니폼으로도 액세스 할 수 있다.

 

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유