Search
Duplicate

샘플러(Sampler) , Texture Coordinate(UV) 좌표계

텍스처 샘플링은 3D 그래픽에서 텍스처를 프리미티브(다각형 등의 기본 형태)에 매핑할 때 사용되는 작업입니다. 이 작업은 텍스처의 크기와 프리미티브의 크기가 다를 때 발생하며, 픽셀에 맞게 텍스처의 텍셀 값을 정해주고 처리해야 합니다
대표적으로 사용되는 샘플링 방법은 3가지 방법으로 나눌 수 있습니다.
1.
포인트 필터링 (point filtering)
포인트 필터링은 축소되거나 확대된 픽셀을 샘플링 할 때 가까운 이웃 픽셀을 보간해서 픽셀을 가져옵니다. 영어로는 Nearest neighbor interpolation이라고 하는데 일단은 보간이 뭔지부터 알아봐야 합니다. 보간은 한자인데 “간격을 돕는다.”라는 의미가 됩니다.
좀더 보충해서 해석하면 보간이란 ‘두개의 위치가 존재 하였을 때 두 위치를 기반으로 사이에 있는 위취(점)들을 계산하는 것” 입니다.
2.
선형 필터링 (linear filltering)
선형 필터링은 포인트 필터링에서 보간을 사용합니다.
해당 픽셀 근처의 픽셀을 조사해서 여러픽셀사이의 값들을 보간연산을 통해서 얻은 값으로 채워줍니다. 선형 보간, 쌍선형 보간, 삼성현 보간이 있고 각각 2개, 4개, 8개의 픽셀을 인접조사합니다.
3.
비등방성 필터링(Anisotropic)
비등방성이란 물체의 물리적 성질이 방향에 따라 다른 성질을 가지는 것입니다.
기존의 point, linear필터링은 회전으로 인한 왜곡을 따지지 않는 필터링입니다.
따라서 결과가 제대로 나오지 않을수 있습니다. 하지만 비등방성 필터링은 이런 부분까지도 깔끔하게 렌더링 됩니다.
텍스처 필터링 문서를 참조하자. 밉매핑의 기반은 텍스처가 축소되는 정도에 따라 미리 다운스케일된 밉맵을 사용해 안티에일리어싱 의 효과를 얻는 것이다. 그러나 3D 그래픽에서는 텍스처가 시선에 항상 수직인 것이 아니므로, 비스듬하게 위치한 텍스처의 경우 가로축과 세로축이 축소된 정도가 달라질 수밖에 없다. 이중선형 필터링이나 삼선형 필터링에서는 이런 경우에도 하나의 값만을 이용해서 밉맵을 사용하지만, 그러지 않고 가로축과 세로축 각각에 대해 밉맵을 따로 만들어두는 것이 비등방성 필터링이다.
예를 들어 원 텍스처의 크기가 1024x1024라고 하면, 보통의 밉맵은 512x512, 256x256, 128x128, ... 이런 식으로 만들어진다. 따라서 가로축과 세로축이 1/2배로 축소된 경우에는 512x512 밉맵을 쓸 것이고 아무 문제가 없다. 그러나 가로축은 그대로인데 세로축만 1/4로 축소된 경우(멀리 있는 바닥 텍스처 등)에는 512x512 밉맵이나 256x256 밉맵을 써야만 하며, 어느 경우든 가로축의 해상도는 떨어져 보일 것이다.
따라서 가로축은 그대로이고 세로축만 1/4로 축소된, 1024x256 밉맵을 미리 만들어두는 생각을 해볼 수 있다. 이렇게 하면 세로축의
은 없으면서도 가로축의 해상도는 1024 그대로를 유지할 수 있다.
이렇게 1024x512, 1024x256, 1024x128, ... 식으로 세로축이 축소되는 밉맵과, 512x1024, 256x1024, 128x1024, ... 식으로 가로축이 축소되는 밉맵, 그리고 또 512x512, 512x256, 512x128, ... 처럼 가로축이 1/2인 경우, ... 등등을 모두 만들어 놓으면, 가로축과 세로축이 축소된 정도 각각에 따라 적절한 밉맵을 사용할 수 있다. 이것이 비등방성 필터링이다.
전체 비교
샘플러를 사용한다라는 것은
셰이더 스테이지에 세팅되어 있는 샘플러 스테이지를 경유해서 텍스처(셰이더 리소스 뷰)에 엑세스 함으로써
SamplerState pointSampler : register(s0); // point sampler SamplerState linearSampler : register(s1); // linear sampler SamplerState anisotropicSampler : register(s2); // anisotropic sampler SamplerState postProcessingSampler : register(s3); // postProcss sampler
C++
복사
필터링 처리나 샘플링 처리를 수행한 값을 얻을 수 있다.
아래는 샘플러스테이트를 생성하는 예시이다.
D3D11_SAMPLER_DESC samplerDesc = {}; samplerDesc.Filter = D3D11_FILTER::D3D11_FILTER_ANISOTROPIC; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_MODE::D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_MODE::D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_MODE::D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.ComparisonFunc = D3D11_COMPARISON_FUNC::D3D11_COMPARISON_NEVER; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; GetDevice()->CreateSamplerState(&samplerDesc, samplerStates[(UINT)eSamplerType::Anisotropic].GetAddressOf());
C++
복사
하나하나 옵션을 설명해보자면
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;
C++
복사
텍스처 어드레싱 모드
텍스처 좌표 값은 0.0 ~ 1.0이 표준 범위이다.
예를들어 2D텍스처의 경우 (0.0, 0.0) ~ (1.0, 1.0) 일 것이다.
그러나 0.0 이하 1.0이상이 안쓰리란 법은 없으며 오히려 이러한 값을 사용함으로 특수한 효과를 줄수도 있다.
텍스처 어드레싱 모드에는 총5개의 모드가 있다.
enum D3D11_TEXTURE_ADDRESS_MODE { D3D11_TEXTURE_ADDRESS_WRAP = 1,//텍스처 좌표를 반복한다. D3D11_TEXTURE_ADDRESS_MIRROR = 2,//인접한 이미지를 반복한다. D3D11_TEXTURE_ADDRESS_CLAMP = 3,// 텍스처 끝 부분의 픽셀이 늘어진다 D3D11_TEXTURE_ADDRESS_BORDER = 4,//경계색을 설정한다. D3D11_TEXTURE_ADDRESS_MIRROR_ONCE = 5//CLAMP + MIRROR 모드 } D3D11_TEXTURE_ADDRESS_MODE;
C++
복사
텍스처를 그냥 렌더링하면 텍스처 이미지가 확대되거나 축소될때의 원래 이미지처럼 깔끔하게 보이지 않는다. 이부분을 보간처리하여 보다 깔끔하게 보일수 있도록 하는것이 필터링 모드이다.
이방성 필터링을 사용하려면 이방성의 차수를 설정해야 한다.
이방성 차수를 1로 설정하면 이방성 필터링이 무효가 되며 1보다 큰값을 설정하면 이방성 필터링이 유효가 된다.
가장 깔끔하게 보이지만 성능은 가장 떨어진다.
또 텍셀의 값을 비교함수로 비교할수도 있다.
다양한 필터링이 존재하니 자세한건 아래 주소에서 확인해보자.
텍스처 샘플링
셰이더 함수내에서 샘플러를 사용하여 필터링 처리나 샘플링 처리를 수행하고 텍스처로 부터 값을 읽어들이려면
다음 함수를 사용한다.
<T>.Sample() 와 <T>.SampleCmp() 는 픽셀세이더에서만 사용할수 있으며 나머지 함수들은 모든 셰에더에서 사용 가능하다.
color = triangleTexture.Sample(g_sam_0, _in.vUV);
C++
복사