대부분의 경우 텍스처를 셰이더에서 샘플링할 때 텍스처 샘플링 상태는 텍스처 설정에서 비롯되며, 기본적으로 텍스처와 샘플러는 함께 결합되어 있습니다. 다음은 DX9 스타일 셰이더 구문을 사용할 때의 기본 동작입니다.
sampler2D _MainTex;
// ...
half4 color = tex2D(_MainTex, uv);
sampler2D, sampler3D, samplerCUBE HLSL 키워드를 사용하여 텍스처와 샘플러를 선언합니다.
대부분의 경우는 이 옵션이 적합하며, 구형 그래픽스 API(예: OpenGL ES)는 이 옵션만 지원합니다.
많은 그래픽스 API와 GPU에서는 텍스처보다 적은 샘플러를 사용할 수 있으며, 연결된 텍스처+샘플러 구문으로 인해 더 복잡한 셰이더를 작성하지 못할 수도 있습니다. 예를 들어, Direct3D 11은 한 셰이더에 최대 128개의 텍스처와 16개의 샘플러를 지원합니다.
Unity는 DX11 스타일 HLSL 구문으로 텍스처와 샘플러를 선언할 수 있으며, 특수한 명명 규칙으로 일치시킵니다. “sampler”+TextureName 형식의 이름을 가진 샘플러는 샘플링 상태를 해당 텍스처에서 가져옵니다.
위 섹션의 셰이더 스니핏은 DX11 스타일 HLSL 구문으로 재작성해도 같은 동작을 합니다.
Texture2D _MainTex;
SamplerState sampler_MainTex; // "sampler" + “_MainTex”
// ...
half4 color = _MainTex.Sample(sampler_MainTex, uv);
하지만 이렇게 하면 다른 텍스처의 샘플러를 ‘재사용’하는 동시에 둘 이상의 텍스처를 샘플링하는 셰이더를 작성할 수 있습니다. 아래 예시에서는 세 가지 텍스처가 샘플링되지만 하나의 샘플러만 샘플링에 사용됩니다.
Texture2D _MainTex;
Texture2D _SecondTex;
Texture2D _ThirdTex;
SamplerState sampler_MainTex; // "sampler" + “_MainTex”
// ...
half4 color = _MainTex.Sample(sampler_MainTex, uv);
color += _SecondTex.Sample(sampler_MainTex, uv);
color += _ThirdTex.Sample(sampler_MainTex, uv);
Unity는 이 ‘분리된 샘플러’ 방식을 사용한 선언과 텍스처 샘플링에 도움이 될 만한 여러 셰이더 매크로를 제공하고 있습니다. 빌트인 매크로를 참조하십시오. 위 예시는 해당 매크로를 사용하여 다음과 같이 다시 작성할 수 있습니다.
UNITY_DECLARE_TEX2D(_MainTex);
UNITY_DECLARE_TEX2D_NOSAMPLER(_SecondTex);
UNITY_DECLARE_TEX2D_NOSAMPLER(_ThirdTex);
// ...
half4 color = UNITY_SAMPLE_TEX2D(_MainTex, uv);
color += UNITY_SAMPLE_TEX2D_SAMPLER(_SecondTex, _MainTex, uv);
color += UNITY_SAMPLE_TEX2D_SAMPLER(_ThirdTex, _MainTex, uv);
위는 Unity가 지원하는 모든 플랫폼에서 컴파일할 수 있지만 DX9 같은 구형 플랫폼에서는 3개의 샘플러를 사용하도록 폴백합니다.
“sampler”+TextureName이라는 HLSL SamplerState 오브젝트를 인식하는 것 외에도 Unity는 샘플러 이름에서 몇 가지 다른 패턴을 인식합니다. 이는 셰이더에서 직접 단순한 하드코딩 샘플링 상태를 선언할 때 유용합니다. 예제:
Texture2D _MainTex;
SamplerState my_point_clamp_sampler;
// ...
half4 color = _MainTex.Sample(my_point_clamp_sampler, uv);
“my_point_clamp_sampler” 이름은 포인트(가장 가까운) 텍스처 필터링과 클램프 텍스처 랩 모드를 사용하는 샘플러로 인식됩니다.
샘플러 이름은 “inline” 샘플러 상태로 인식됩니다(대소문자 구분).
“Point”, “Linear” 또는 “Trilinear”(필수)는 텍스처 필터링 모드를 설정합니다.
“Clamp”, “Repeat”, “Mirror” 또는 “MirrorOnce”(필수)는 텍스처 랩 모드를 설정합니다.
“Compare”(선택 사항)는 뎁스 비교용 샘플러를 설정합니다. HLSL SamplerComparisonState 유형과 SampleCmp/SampleCmpLevelZero 함수를 사용합니다.
“AnisoX”(X는 2, 4, 8 또는 16일 수 있음. 예: Aniso8)를 추가하여 이방성 필터링을 요청할 수 있습니다.
다음은 각각 sampler_linear_repeat 및 sampler_point_repeat SamplerState 샘플링 텍스처의 예시로, 이름이 필터링 모드를 조절하는 방식을 나타냅니다.
다음은 각각 SmpClampPoint, SmpRepeatPoint, SmpMirrorPoint, SmpMirrorOncePoint, Smp_ClampU_RepeatV_Point SamplerState가 있는 예시로, 이름이 래핑 모드를 제어하는 방식을 나타냅니다. 마지막 예시에서는 가로(U) 및 세로(V) 축에 서로 다른 랩 모드를 설정했습니다. 모든 경우 텍스처 좌표는 –2.0에서 +2.0으로 바뀝니다.
분리된 텍스처+샘플러 구문과 마찬가지로 인라인 샘플러 상태가 모든 플랫폼에서 지원되지는 않습니다. 현재 Direct3D 11/12 및 Metal에서 구현됩니다.
참고로 “MirrorOnce” 텍스처 랩 모드는 대부분의 모바일 GPU/API에서 지원되지 않고, 이런 경우 Mirror 모드로 폴백합니다.
플랫폼 기능과 선택한 API에 따라 “AnisoX” 필터링 모드가 가장 적합합니다. 실제 값은 지원되는 최대 이방성 레벨에 따라 고정됩니다(이방성 필터링이 지원되지 않는 경우 비활성화 포함).
| 매크로: | 용도: |
|---|---|
UNITY_DECLARE_TEX2D(name) |
텍스처 및 샘플러 페어를 선언합니다. |
UNITY_DECLARE_TEX2D_NOSAMPLER(name) |
샘플러 없이 텍스처를 선언합니다. |
UNITY_DECLARE_TEX2DARRAY(name) |
텍스처 배열 샘플러 변수를 선언합니다. |
UNITY_SAMPLE_TEX2D(name,uv) |
주어진 텍스처 좌표를 사용하여 텍스처와 샘플러 페어에서 얻은 샘플입니다. |
UNITY_SAMPLE_TEX2D_SAMPLER( name,samplername,uv) |
다른 텍스처의 샘플러(samplername)를 사용해 텍스처에서 얻은 샘플(name)입니다. |
UNITY_SAMPLE_TEX2DARRAY(name,uv) |
float3 UV가 있는 텍스처 배열에서 얻은 샘플입니다. 좌표의 Z 컴포넌트는 배열 요소 인덱스입니다. |
UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod) |
명시적인 밉맵 레벨이 있는 텍스처 배열에서 얻은 샘플입니다. |