텍스처 적용(4) - 샘플러 / 텍스처 출력

WanJu Kim·2022년 12월 30일

Direct3D

목록 보기
25/29

이번에 배울 내용은 샘플러(sampler)다. 샘플러는 여러 가지 방식을 한다.

샘플러를 파이프라인에 묶는 방법은 다음과 같다.

  1. D3D11_SAMPLER_DESC 구조체를 채운다.
  2. CreateSamplerState 함수를 이용해 samplerstate를 생성한다.
  3. ID3D11DeviceContext::PSSetSamplers함수를 통해 GPU로 넘겨준다.
  4. GPU에서 전달 받아 출력 코드를 작성한다.

먼저 D3D11_SAMPLER_DESC 구조체를 채워보자.

typedef struct D3D11_SAMPLER_DESC
    {
    D3D11_FILTER Filter;
    D3D11_TEXTURE_ADDRESS_MODE AddressU;
    D3D11_TEXTURE_ADDRESS_MODE AddressV;
    D3D11_TEXTURE_ADDRESS_MODE AddressW;
    FLOAT MipLODBias;
    UINT MaxAnisotropy;
    D3D11_COMPARISON_FUNC ComparisonFunc;
    FLOAT BorderColor[ 4 ];
    FLOAT MinLOD;
    FLOAT MaxLOD;
    } 	D3D11_SAMPLER_DESC;
  1. Filter : 전 포스팅에서 배웠던 필터링이다. 여러 가지 옵션들이 있으니 열거자를 확인하고 궁금하면 SDK 문서를 참고하면 된다. 링크

(23.1.6 추가)
그중에 두 개만 비교해보자. 다음 두 열거자들이다.

D3D11_FILTER_MIN_MAG_MIP_POINT;	// 축소, 확대, 밉 레벨을 상수 보간으로 한다.
D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;	// 축소, 확대, 밉 레벨을 선형 보간으로 한다.

일반적으로는 선형 보간이 자주 쓰인다.(그런가?) 하지만 이 경우에는 달랐다.

이 텍스처를 출력하려고 했다. 배경을 제외하고 말이다. 선형 보간을 사용했을 땐 다음과 같다.

마젠타 색이 좀 남는다. 왜? 록맨 테두리 부분에서 선형 보간이 일어난 것이다. 반면 상수 보간은 이렇다.

아주 깔끔하게 제거된다.


다음 4개의 매개변수들은, 텍스처 좌표를 1이상으로 늘렸을 때 나머지를 어떻게 채울 거냐에 대한 매개변수들이다. 그러니까 uv 좌표를

vertices[0].uv = D3DXVECTOR2(0.0f, 2.0f);
vertices[1].uv = D3DXVECTOR2(0.0f, 0.0f);
vertices[2].uv = D3DXVECTOR2(2.0f, 2.0f);
vertices[3].uv = D3DXVECTOR2(2.0f, 0.0f);

이런식으로 바꾸었다.

      1. AddressU / AddressV / AddressW: 텍스처의 u / v / w 방향으로 어떻게 채울건지에 대한 변수이다. w는 대각선 방향이다. 다음과 같은 선택지가 있다.
        (a) D3D11_TEXTURE_ADDRESS_WRAP : 텍스처를 반복시킴.
        (b) D3D11_TEXTURE_ADDRESS_MIRROR : 텍스처가 반전돼보임.
        (c) D3D11_TEXTURE_ADDRESS_CLAMP : 텍스처의 마지막 픽셀을 늘린 모습.
        (d) D3D11_TEXTURE_ADDRESS_BORDER : 텍스처를 색으로 지정함.
        여기서 (d)는 또다시 8번째 매개변수, BorderColor 변수와 연관된다. 저 변수로 색깔을 지정하기 때문이다. 예시를 보겠다.

(a) D3D11_TEXTURE_ADDRESS_WRAP를 사용했을 경우.

(b) D3D11_TEXTURE_ADDRESS_MIRROR를 사용했을 경우.

(c) D3D11_TEXTURE_ADDRESS_CLAMP를 사용했을 경우.

(d) D3D11_TEXTURE_ADDRESS_BORDER를 사용했을 경우.(색깔은 따로 정한다.)

  1. MipLODBias : 계산된 밉맵 레벨의 편차. 만약 밉맵 레벨이 3이고 이 변수가 2이면, 텍스처는 밉맵 레벨 5로 샘플링 된다.
  2. MaxAnisotropy : 비등방성 필터링. 1 ~ 16의 범위를 가진다.
  3. ComparisonFunc : 사진이 겹치면 그 겹치는 부분을 어떻게 할거냐에 대한 플래그. 맨처음께 나올 수도 있고 맨 뒤에 것이 나올 수도 있다.
  4. BorderColor[4] : 2,3,4의 매개변수중 하나 이상이D3D11_TEXTURE_ADDRESS_BORDER일 때 사용한다. 0 ~ 1 범위로 값을 주면 그에 맞는 색깔을 샘플링한다.
  5. MinLOD : 밉맵 레벨의 최소 수준 제한 값.
  6. MaxLOD : 밉맵 레벨의 최대 수준 제한 값.

이렇게 구조체를 작성했다면, samplerstate를 생성할 수 있다.

md3dDevice->CreateSamplerState(&desc, &samplerState);
assert(SUCCEEDED(hr));

생성했으니, 파이프라인에 묶을 수 있다.

md3dImmediateContext->PSSetSamplers(0, 1, &samplerState)

여기서 매개변수는 전에 했던 PSSetShaderResources와 비슷하다.

그러고 나면 GPU에서 이 자원을 받을 수 있어야 한다. 텍스처를 받았을 때와 비슷하게 한다. 샘플러는 SamplerState 객체에 저장한다.

SamplerState samp : register(s0);

register은 텍스처와 비슷하다. 차이점은 sampler의 s를 쓴다는 것.

그럼 드디어 GPU에 텍스처와 샘플러의 자원을 넘긴 것이다. 이를 통해 텍스처를 샘플링할 수 있다. 코드는 텍스처 적용(2) 포스팅에서 한거랑 같다.

float4 PS(PixelInput input) : SV_Target	
{
    float4 color = sourceTex.Sample(samp, input.uv);
    return color;
}
profile
Question, Think, Select

0개의 댓글