개발하는 리프터 꽃게맨입니다.

[DX11 물방울책 공부록] Chapter 8: Texturing 본문

컴퓨터 그래픽스/DirectX 11

[DX11 물방울책 공부록] Chapter 8: Texturing

파워꽃게맨 2024. 10. 5. 02:17

실제 세계의 물체는 보통 버텍스 단위의 색상만으로는 포착할 수 없는 더 많은 세부 사항을 가고 있다.

텍스처 매핑은 삼각형 위에 이미지 데이터를 매핑할 수 있는 기법으로, 이를 통해 장면의 세부 사항과 사실감을 크게 향상시킬 수 있다.

 

예를 들어, 육면체를 만들고 각 면에 상자 텍스처를 매핑하여 상자처럼 보이게 만들 수 있다.

 

텍스처와 리소스 복습

우리는 앞서 이미 텍스처를 사용해왔다. 

특히, 깊이 버퍼와 백 버퍼는 ID3D11Texture2D 인터페이스로 표현되는 2D 텍스처 객체이다.

 

2D 텍스처는 데이터 요소들의 행렬이다. 2D 텍스처는 많은 용도로 사용될 수 있으며, 그 중 한가지 용도는 픽셀의 색상을 저장하는 것이다.

 

이 때 텍스처는 2D 이미지 데이터를 저장한다.

 

그러나 이것이 유일한 용도는 아니다. 예를 들어, 노멀 매핑이라는 고급 기술에서는 각 텍스처 요소가 색상 대신 3D 벡터를 저장한다.

 

따라서 텍스처가 이미지 데이터를 저장한다고 흔히 생각되지만, 실은 그보다 더 범용적이다.

 

ID3D11Texure1D 는 1차원 배열과 같으며, 3D 텍스처는 3차원 배열과 같다.

 

1D, 2D, 3D 텍스처 인터페이스는 모두 ID3D11Resource로부터 상속된다.

 

이 장에서 나중에 논의하겠지만, 텍스처는 단순한 데이터 배열의 이상이다. 텍스처는 밉맵 레벨을 가질 수 있으며, GPU는 필터 적용, 멀티샘플링 등의 특별한 연산을 수행할 수 있다.

 

그러나 텍스처는 임의의 데이터 덩어리가 아니다. DXGI_FORMAT 열거형으로 설명되는 특정 데이터 형식만을 저장할 수 있다.

 

DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_UINT 등.. 이 존재한다.

 

여기서 등장하는 R, G, B, A는 각각 빨간색, 녹색, 파란색, 알파를 나타낸다.

그러나 앞서 언급했듯이 텍스처는 색상 정보를 저장할 필요는 없다.

DXGI_FORMAT_R32G32B32_FLOAT 이 포맷은 그저 3개의 부동소수점을 구성 요소로 가지고 있다. 따라서 색상 벡터가 아닌 부동소수점 좌표로 된 3D 벡터를 저장할 수 있다.

 

또한, 형식이 지정되지 않은 형식도 있는데, 이를 TYPELESS 라고 한다.

먼저 메모리를 예약한 후, 텍스처가 렌더링 파이프라인에 연결될 때 데이터를 어떻게 재해석할지 나중에 지정하는 방식이다.

 

텍스처는 렌더링 파이프라인의 다양한 단계에 바인딩될 수 있다. 흔한 예로는 텍스처를 렌더 타겟 및 쉐이더 리소스로 사용하는 것이다.

 

렌더 타겟에 사용될 텍스처는 D3D11_BIND_RENDER_TARGET

쉐이더에 사용될 텍스처는 D3D11_BIND_SHADER_RESOURCE

라는 바인드 플래그를 사용한다.

 

사실, 리소스는 직접적으로 파이프라인 단계에 바인딩되지 않고, 대신 관련된 리소스 뷰가 각각의 파이프라인 단계에 바인딩된다. 그래서 텍스처를 사용할 때는, 해당 텍스처의 리소스 뷰를 생성해야 한다.

 

이는 대부분 성능 효율을 위해서이며, SDK 문서는 "이렇게 하면 뷰 생성 시 런타임 및 드라이버에서 유효성 검사와 매핑이 이루어져, 바인드 시점의 현식 검사 최소화가 가능하다." 라고 말한다.

 

따라서 텍스처를 렌더 타겟 및 쉐이더 리소스로 사용하는 경우, 렌더 타겟 뷰, 쉐이더 리소스 뷰 2가지 뷰를 생성해야 한다.

 

리소스 뷰는 Direct3D에게 리소스가 어떻게 사용될지 

즉, 파이프라인의 어느 단게에 리소스를 바인딩할 지 알려준다.

 

추가적으로 리소스 형식이 Typeless인 경우 리소스뷰를 통해 그 값을 해석할 수 있게된다.

리소스뷰에 의해서 텍스처 요소는 한 파이프라인 단계에서는 부동소수점 값으로, 다른 단계에서는 정수로 해석될 수 있다.

 

그러나, 형식이 명시적으로 지정되어야 리소스에 대한 런타임 접근이 최적화되기 때문에, 정말로 필요한 경우에만 형식이 지정되지 않은 리소스를 생성하도록 하자. 대부분의 경우 명시적으로 형식을 지정하여 리소스를 생성해야 한다.

 

리소스에 대한 특정 뷰를 생성하려면, 리소스가 해당 특정 바인드 플래그로 생성되어야 한다.

예를 들어, 리소스가 D3D11_BIND_SHADER_RESOURCE 바인드 플래그를 가지지 않는다면, 해당 리소스에 대한 ID3D11ShaderResourceView를 생성할 수 없다.

 

이 장에서는 주로 픽셀 쉐이더가 텍스처를 샘플링하고 이를 통해 픽셀을 색칠할 수 있도록 텍스처를 쉐이더 리소스로 바인딩하는 것에 초점을 맞출 것이다.

 

텍스처 좌표

Direct3D는 u축이 이미지의 수평 방향, v축이 이미지의 수직 방향으로 구성된 텍스처 좌표 시스템을 사용한다.

좌표는 (u, v) 로 표현되며, 각각은 [0, 1] 의 범위를 가지고 있다.

 

uv 좌표계가 정규화된 좌표 구간을 사용하면서 Direct3D는 차원에 독립적인 범위를 사용할 수 있게 된다.

 

 

각 3D 삼각형에 대해, 해당 3D 삼각형에 매핑될 텍스처 상의 대응되는 삼각형을 정의하고자 한다.

p0, p1, p2 를 각각 텍스처 좌표 q0, q1, q2를 가지는 3D 삼각형의 정점이라고 하자.

 

3D 삼각형 상의 임의의 점 (x, y, z) 의 텍스처 좌표 (u, v)는 동일한 s, t 매개변수를 통해 3D 삼각형 전체에서 정점 텍스처 좌표를 선형 보간하여 찾을 수 있다.

 

(간단설명, 컨벡스 결합식을 이용하여 무게중심 보간이라고 이해할 수 있음)

 

이 방식으로, 삼각형의 모든 점은 대응되는 텍스처 좌표를 가진다.

 

이를 구현하기 위해서 Vertex 구조를 다시 수정하여 텍스처의 한 점을 식별하는 텍스처 좌표 쌍을 추가한다.

이제 모든 3D 정점은 대응되는 2D 텍스처 정점을 가진다.

 

따라서 세 개의 정점으로 정의된 모든 3D 삼각형은 텍스처 공간에서의 2D 삼각형도 정의한다.

즉, 모든 3D 삼각형에 대해 2D 텍스처 삼각형을 연관시킨 것이다.

 

 

인풋 레이아웃

 

2D 텍스처 삼각형이 3D 삼각형과 매우 다른 "이상한" 텍스처 매핑을 만들 수 있다. 따라서 2D 텍스처가 3D 삼각형에 매핑되며 많은 왜곡과 변형이 발생하여 결과가 좋지 않게 보인다.

 

예를 들어, 예각 삼각형을 직각 삼각형에 매핑하려면 늘림이 필요하다.

일반적으로 텍스처 왜곡은 텍스처 아티스트가 왜곡된 외형을 의도하지 않는 한 최소화되어야 한다.

 

 

위 그림에서 우리는 텍스처 이미지를 큐브의 각 면에 전체적으로 매핑한 것을 볼 수 있다. 이것이 반드시 필요한 것은 아니다. 우리는 텍스처의 일부분만 기하 도형에 매핑할 수 있다.

실제로 여러 개의 관련 없는 이미지를 하나의 큰 텍스처 맵에 넣고, 이를 여러 다른 객체에 사용할 수 있다.

이를 텍스처 아틀라스라고 부른다.

 

텍스처 생성 및 활성화

텍스처 데이터는 보통 디스크에 저장된 이미지 파일에서 읽어들여 ID3D11Texture2D 객체로 로드된다. 그러나 텍스처 리소스는 렌더링 파이프라인에 직접 바인딩되지 않는다. 대신, 텍스처에 대한 쉐이더 리소스 뷰를 생성한 후, 그 뷰를 파이프라인에 바인딩한다.

 

따라서 두 가지 단계가 필요하다.

 

1. D3DX11CreateTextureFromFile 함수를 호출하여 디스크에 저장된 이미지 파일에서 ID3D11Texture2D 객체를 생성한다.

2. ID3D11Device::CreateShaderResourceView 함수를 호출하여 해당 텍스처에 대한 쉐이더 리소스 뷰를 생성한다.

 

그러나 D3DX 라이브러리는 더 이상지원되지 않는다고 한다.

 

DirectXTK 에서는 CreateDDSTextureFromFile이라는 매우 편리하게 텍스처에 대한 쉐이더 리소스 뷰를 생성할 수 있도록 해준다.

 

텍스처가 로드된 후에는 픽셀 쉐이더에서 사용할 수 있도록 이 텍스처를 effect 변수에 지정해야한다.

그러나 현재는 effect 또한 없으므로.. 

 

나중에

 

필터

 

1. 확대

텍스처 맵의 요소들은 색상 샘플 정도로 생각해야지, 면적을 가진 사각형으로 생각해서는 안 된다.

 

만약, 텍스처 좌표 (u, v)가 텍셀 중 하나와 일치하지 않을 경우 어떻게 될까?

 

이러한 상황은 다음과 같이 발생할 수 있다. 플레이어가 장면에서 벽을 확대하여 벽이 화면 전체를 덮도록 한다고 가정하자. 예를 들어, 모니터 해상도가 1024 x 1024이고 벽의 텍스처 해상도가 256 x 256 이라고 가정하자.

 

이것은 텍스처 확대를 나타낸다. 즉, 몇 개의 텍셀로 많은 픽셀을 덮으려는 것이다.

 

우리의 예에서, 각 텍셀 점 사이에는 4개의 픽셀이 존재한다.

 

정점 텍스처좌표가 삼각형을 가로질러 보간될 떄 각 픽셀은 고유한 텍스처 좌표 쌍을 가지게 된다.

따라서 텍셀 점과 일치하지 않는 텍스처 좌표를 가진 픽셀이 생기게 된다.

 

텍셀에서의 색상을 기준으로, 보간을 통해 텍셀 간의 색상을 추정할 수 있다.

그래픽 하드웨어가 지원하는 보간 방법은 두 가지가 있다.

 

상수 보간과 선형 보간이다.

실제로는 선형 보간이 거의 항상 사용된다.

 

위 그림은 상수보간과 선형보간이 수를 예측하는 차이를 보여준다.

 

 

해당 그림은 256개의 샘플을 가진 1D 텍스처이다.

보간된 텍스처 좌표 u = 0.126484375가 있다고 가정하자.

 

이 정규화된 텍스처 좌표는 0.126484375 * 256 = 32.38 텍셀을 나타낸다.

이 값은 어떤 두 텍셀 샘플 사이에 있으므로 보간을 사용하여 값을 추정해야 한다.

 

2D 선형 보간은 Bilinear 보간이라고 하며, 위 그림으로 설명할 수 있다.

네 개의 텍셀 사이에 있는 텍스처 좌표 쌍을 기준으로 u방향에서 두 번의 1D 선형 보간을 수행한 후, v 방향에서 한 번의 1D 보간을 수행한다.

 

 

위 그림은 상수 보간과 선형 보간의 차이를 보여준다.

보다시피, 상수 보간은 블록처럼 보이는 이미지를 만들고

선형 보간은 더 부드러운 이미지를 만들어낸다.

 

그러나 선형 보간의 결과 역시 보간을 통해 도출된 데이터이기 때문에 여전히 완벽한 이미지를 제공하지는 못한다.

여기서 주의할 점은, 3D 프로그램에서 확대 문제를 완전히 피할 방법이 없다는 것이다.

 

어느 정도 거리에선 텍스처가 훌륭해 보일 수 있지만, 시점이 너무 가까워지면 텍스처가 깨지기 시작할 것이다.

 

그래서 일부 게임은 과도한 확대를 피하기 위해 가상 시점이 표면에 너무 가까이 다가가지 못하도록 제한한다.

 

더 높은 해상도의 텍스처를 사용하는 것이 도움이 될 수 있다.

텍스처링의 맥락에서, 텍셀 사이의 텍스처 좌표에 대한 텍스처 값을 찾기 위해 상수 보간을 사용한느 것을 포인트 필터링이라고도 한다. 또한 텍셀 사이의 텍스처 좌표에 대한 텍스처 값을 찾기 위해 선형 보간을 사용하는 것을 선형 필터링이라고 한다.

 

포인트 필터링과 선형 필터링은 Direct3D에서 사용하는 용어이다.

 

2. 축소

밉맵 체인, 최종적으로 1x1 크기까지 축소된다.

축소는 확대의 반대 개념이다. 축소에서는 너무 많은 텍셀이 너무 적은 픽셀에 매핑되는 문제가 발생한다.

 

예를 들어, 256x256 크기의 텍스처가 매핑된 벽이 있다고 가정하자.

시점이 벽을 바라보며 계속 뒤로 물러나서, 벽이 점점 작아져 화면에서 64x64 픽셀만을 차지하게 된다.

 

이제 256x256 텍셀이 64x64 화면 픽셀에 매핑된 상황이 된다.

 

이 상황에서도 픽셀의 텍스처 좌표는 여전히 텍스처 맵의 텍셀과 일치하지 않으므로, 상수 및 선형 보간 필터가 축소에도 적용된다.

 

그러나 축소에서는 추가로 할 수 있는 일이 있다.

직관적으로 256x256 텍셀을 평균적으로 다운샘플링하여 64x64 로 줄여야 한다.

 

밉맵 기법은 추가 메모리 비용을 들여 효율적인 근사값을 제공한다.

초기화 시점 혹은 에셋 생성 시점에 이미지를 다운샘플리하여 텍스처의 작은 버전을 생성하고, 이를 밉맵 체인으로 만든다.

따라서 밉맵 크기에 대한 평균 작업이 미리 계산된다.

 

런타임 시 그래픽 하드웨어는 프로그래머가 지정한 밉맵 설정에 따라 두 가지 다른 작업을 수행한다.

 

1) 텍스처링을 위한 화면 지오메트리 해상도에 가장 적합한 밉맵 레벨을 선택하고, 필요에 따라 상수 또는 선형 보간을 적용한다.

 

2) 화면 지오메트리 해상도에 가장 적합한 두 개의 인접한 밉맵 레벨을 선택한다. (하나는 화면 지오메트리 해상도보다 크고, 다른 하나는 더 작다.)

 

그런 다음, 이 두 밉맵 레벨에 상수 또는 선형 필터링을 적용하여 각각의 텍스처 생상을 생성한다. 마지막으로, 이 두 텍스처 색상 결과를 보간한다.

이것을 밉맵에 대한 선형 필터링이라고 하며, 이는 선형 보간과 유사하다.

즉, 두 인접한 밉맵 레벨 간에 선형 보간을 수행하는 것이다.

 

밉맵 체인에서 가장 적합한 텍스처 레벨의 세부 정보를 선택함으로써 축소의 양이 크게 줄어든다.

 

[밉맵 생성]

밉맵 레벨은 아티스트가 직접 생성할 수도 있고, 필터링 알고리즘에 의해 생성될 수도 있다.

.DDS(DirectDraw Surface)와 같은 일부 이미지 파일 형식은 데이터 파일에 밉맵 레벨을 직접 저장할 수 있다. 이 경우, 데이터를 단순히 읽기만 하면 되며, 런타임에서 밉맵 레벨을 알고리즘적으로 계산할 필요가 없다.

 

DirectX Texture Tool은 텍스처에 대해 밉맵 체인을 생성하고 이를 .DDS 파일로 내보낼 수 있다.

 

이미지 파일에 완전한 밉맵 체인이 포함되지 않은 경우, D3DX11CreateShaderResourceViewFromFile 또는 D3DX11CreateTextureFromFile 함수가 지정된 필터링 알고리즘을 사용하여 밉맵 체인을 생성해준다.

 

따라서 밉매핑은 본직적으로 자동이라는 것을 알 수 있다.

 

D3DX11 함수는 소스 파일에 밉맵 체인이 포함되어 있지 않으면 자동으로 밉맵 체인을 생성해준다.

(현재 대체하여 사용중인 CreateDDSTextureFromFile은 밉맵 체인을 자동으로 생성해주지 않음)

(device context에서 자동 밉맵 생성 함수를 제공하고 있다.)

 

밉매핑이 활성화된 한, 하드웨어는 런타임에 적절한 밉맵 레벨을 선태갛여 사용한다.

때때로 범용 필터링 알고리즘은 다운샘플링 시 원하는 세부 사항을 유지하지 못할 수 있다. 

예를 들어, 위 그림 상자에 쓰인 Direct 3D 라는 텍스트는 더 낮은 밉 레벨에서는 흐려진다.

 

이것이 용납되지 않는다면, 아티스트가 언제든지 중요한 세부 사항을 유지하기 위해 밉 레벨을 수동으로 생성하거나 조정할 수 있다.

 

[Anisotropic Filtering]

사용할 수 있는 또 다른 필터는 이방성 필터링 혹은 양방성 필터링(Anisotropic Filtering) 이라고 한다.

이 필터는 다각형의 법선 벡터와 카메라의 시선 벡터 사이의 각도가 클 때 발생하는 왜곡을 완화하는데 도움을 준다.

 

이 필터는 가장 비용이 많이 들지만, 왜곡 아티팩트를 수정하는 데 있어 그 비용을 지불할 가치가 있다.

 

 

오른쪽이 이방성 필터링이 적용된 예시이다.

선형 필터링의 경우 상자의 윗면이 흐려지는 것을 알 수 있다.

 

텍스처 샘플링

텍스처와 관련된 또 다른 객체가 있는데, 이것은 SamplerState 객체이다.

샘플러 객체는 텍스처에 사용할 필터를 정의하는 곳이다.

 

샘플러 스테이트는 여러가지 옵션을 설정할 수 있다.

MaxAnisotropy 라는 변수의 값을 설정해서 최대 이방성을 지정할 수 있다.

1~16까지의 값을 대입할 수 있고, 값이 클수록 비용이 더 많이 들지만, 더 나은 결과를 제공할 수 있다.

 

자세한 것은 D3D11_FILTER 열거형을 문서에서 확인해보도록 하자.

 

픽셀 쉐이더에서 픽셀에 대한 텍스처 좌표 쌍이 주어졌을 떄, 다음 문법을 사용하여 텍스처를 샘플링한다.

 

보다시피, 텍스처를 샘플링하기 위해 Texture2D::Sample 메서드를 사용한다.

 

첫 번째 매개변수로 SamplerState 객체를 전달하고, 두 번째 매개변수로 픽셀의 uv 텍스처 좌표를 전달한다.

 

이 메서드는 SampelrState 객체에 의해 지정된 필터링 방법을 사용하여, 지정된 (u, v) 지점에서 텍스처 맵의 보간된 색상을 반환한다.

 

HLSL 타입 SamplerState 는 ID3D11SamplerState 인터페이스를 반영한다.

RenderState 와 마찬가지로, SamplerState 도 초기화 시점에 생성되어야 한다.

 

텍스처를 머테리얼/조명 시스템에 통합할 때, 텍스처 생상을 Ambient와 Diffuse 과 함께 변조하고 Specular는 변조하지 않는 것이 일반적이다.

 

그러므로 최종적인 SV_TARGET 는 다음과 같은 꼴을 가진다.

 

이 수정은 픽셀마다 Diffuse과 Specular 조명의 재질 값을 제공하는데, 이는 객체 전체에 동일한 재질 값을 적용하는 것보다 더 세밀한 표현을 가능하게 해준다. 그 이유는, 하나의 삼각형에 많은 텍셀이 덮여서, 더 세밀한 조명 효과를 표현할 수 있기 때문이다.

 

즉, 각 픽셀은 텍스처 좌표 (u, v)를 보간하여 계산하고, 그 좌표를 사용해 텍스처에서 색상을 가져온다. 이 색상은 그 픽셀이 어떤 재질을 갖고 있는지를 나타내는 데 기여한다. 이렇게 하면, 픽셀마다 다른 색상과 조명 효과를 부여할 수 있게 되어 장면이 더 사실적으로 표현된다.

 

주소 모드

텍스처는 상수 또는 선형 보간과 결합하여 벡터 값 함수 T(u, v) = (r, g, b, a) 를 정의한다.

즉, 텍스처 좌표 (u, v) [0, 1] 가 주어지면 텍스처 함수 T는 색상 (r,g,b,a)를 반환한다.

 

Direct3D는 이 함수의 정의 영역을 네 가지 방식으로 확장할 수 있게 한다.

 

1. wrap

이미지가 정수 교차점마다 반복되도록 텍스처 함수를 확장한다.

 

2. border color

해당 모드는 범위를 벗어난 경우 프로그래머가 지정한 색상으로 매핑하여 텍스처 함수를 확장한다.

 

3. clamp

 

해당 모드는 (u, v)에 가장 가까운 지점의 색상으로 매핑하여 텍스처 함수를 확장한다.

 

4. mirror

이미지가 정수 교차점마다 반사되도록 텍스처 함수를 확장한다.

 

주소 모드는 항상 지정되며, 기본값은 wrap 모드이다.

따라서 주소 모드 덕에 [0, 1] 범위를 벗어난 텍스처 좌표도 항상 정의된다.

 

wrap 주소 모드는 아마도 가장 자주 사용되는 방식일 것이다.

이 모드는 텍스처를 표면 위에 반복적으로 타일링할 수 있게 한다.

 

이 방식은 추가적인 데이터 없이도 텍스처 해상도를 높이는 효과를 제공한다.

(물론 그 해상도는 반복적이긴 하다.)

 

타일링을 사용할 때는 텍스처가 이음새 없이 매끄러운 것이 중요하다.

 

예를 들어, 상자 텍스처는 이음새가 없지 않아 반복이 명확히 보이지만, 위 벽돌 텍스처는 2x3으로 반복된 자연스러운 예시를 보여준다.

 

주소 모드는 샘플러 객체에서 지정된다.

 

이 코드로 알 수 있는 건, U와 V에 대한 주소 모드를 독립적으로 정할 수 있다는 것이다.

 

텍스처 변환

텍스처 좌표는 텍스처 평면에서 2D 좌표를 나타낸다. 따라서 다른 좌표와 마찬가지로 텍스처 좌표를 평행 이동, 회전, 확장할 수 잇다.

 

텍스처 변환의 사용 예시는 다음과 같다.

 

1. 벽돌 텍스처가 벽을 따라 늘어져 있다. 현재 벽의 정점은 [0, 1] 범위 내에서 텍스처 좌표를 가지고 있다. 이 텍스처 좌표를 4배로 확장하여 [0, 4] 범위로 변환하면 텍스처가 벽을 따라 네 번 반복된다.

 

2. 구름 텍스처가 맑은 하늘에 걸쳐져 있다. 시작에 따라 텍스처 좌표를 평행 이동하면 구름이 한르 위에서 움직이는 애니메이션이 된다.

 

3. 텍스처 회전은 입자 효과에 유용할 수 있다. 예를 들어, 시간에 따라 파이어볼 텍스처를 회전시키는 경우가 있다.

 

텍스처 좌표 변환은 일반적인 변환과 마찬가지로 수행된다. 변환 행렬을 지정하고, 텍스처 좌표 벡터에 이를 곱하면 된다.

 

우리가 작업하는 것은 2D 텍스처 좌표이므로, 첫 두 좌표에 대한 변환만 신경 쓰면 된다.

예를 들어, 텍스처 행렬이 z좌표를 평행 이동시키더라도, 이는 결과적인 텍스처 좌표에는 아무런 영향을 미치지 않는다.

 

텍스처 압축

가상 세계가 수백 개의 텍스처로 확장되면 GPU의 메모리 요구 사항이 급격히 증가한다.

모든 텍스처를 빠르게 적용하기 위해 GPU 메모리에 보관해야 한다는 점을 기억하자.

 

이러한 메모리 요구 사항을 완화하기 위해 Direct3D는 BC1 ~ BC7 과 같은 압축 텍스처 형식을 지원한다.

각각의 포맷마다 압축 성능과 성격이 다르며, BC7은 뛰어난 압축력을 보임과 동시에 품질도 고수준으로 유지하기에 가장 자주 사용되는 포맷이다.

 

무손실 압축 BC1, 손실 압축 BC3 역시 자주 사용된다.

 

압축된 텍스처는 렌더링 파이프라인의 쉐이더 단계에서만 입력으로 사용할 수 있다.

 

DirectX 에서 사용되는 압축 방식은 블록 압축(BC, Block Compression) 이다.

블록 압축 알고리즘은 4x4 픽셀 블록을 사용하기 떄문에, 텍스처의 크기는 4의 배수여야 한다.

 

이 형식들의 장점은 텍스처가 GPU 메모리에 압축된 상태로 저장되어야 한다는 것이다.

 

그러면 텍스처를 압축된 상태로 만들 수 있어야하는데, 공식적으로 압축을 하는 함수는 지원하지 않고 DirectXTex라는 DirectX용 텍스처 처리 라이브러리로 텍스처 압축을 사전 처리하여 저장할 수 있다.

 

자세한 것은 문서를 참고하도록 한다.