셰이더 디테일 수준(LOD)
Visual Studio로 DirectX 11 셰이더 디버깅

텍스처 배열(Texture arrays)

일반 2D 텍스처(셰이더의 Texture2D 클래스, sampler2D), 큐브 맵(셰이더의 Cubemap 클래스, samplerCUBE), 3D 텍스처(셰이더의 Texture3D 클래스, sampler3D)와 유사하게 Unity는 2D 텍스처 배열도 지원합니다.

텍스처 배열은 GPU에 단일 오브젝트처럼 보이는 같은 크기/형식/플래그 2D 텍스처의 컬렉션이며 텍스처 요소 인덱스를 사용하여 셰이더에서 샘플링할 수 있습니다. 텍스처 배열은 커스텀 터레인 렌더링 시스템 또는 기타 크기와 형식이 같은 많은 텍스트처에 효율적으로 액세스하는 방법이 필요한 특수 이펙트를 구현하는 데 유용합니다. 2D 텍스처 배열의 요소는 슬라이스 또는 레이어라고도 합니다.

플랫폼 지원

텍스처 배열은 기본 그래픽스 API 및 GPU의 지원을 받아야 하며, 다음에서 사용할 수 있습니다.

  • Direct3D 11/12(Windows, Xbox One)
  • OpenGL Core(Mac OS X, Linux)
  • Metal(iOS, Mac OS X)
  • OpenGL ES 3.0(Android, iOS, WebGL 2.0)
  • PlayStation 4

다른 플랫폼(Direct3D 9, OpenGL ES 2.0, WebGL 1.0)은 텍스처 배열을 지원하지 않습니다. 런타임 시점에 텍스처 배열 지원 여부를 확인하려면 SystemInfo.supports2DArrayTextures를 사용해야 합니다.

텍스처 배열 생성 및 조작

텍스처 배열을 위한 텍스처 임포트 파이프라인이 없으므로 스크립트상 만들어야 합니다. 텍스처 배열을 만들고 조작하려면 Texture2DArray 클래스를 사용해야 합니다. 텍스처 배열은 에셋으로 직렬화할 수 있으므로 에디터 스크립트에서 만들고 데이터를 채울 수 있습니다.

일반적으로 텍스처 배열은 GPU 메모리 내에서만 사용되지만 Graphics.CopyTexture, Texture2DArray.GetPixelsTexture2DArray.SetPixels를 사용하여 시스템 메모리와의 사이에 픽셀을 이동할 수 있습니다.

텍스처 배열을 렌터 타겟으로 사용

텍스처 배열 요소는 렌더 타겟으로 사용할 수도 있습니다. 렌더 타겟이 2D 텍스처 배열이 될지 여부를 미리 지정하려면 RenderTexture.dimension을 사용해야 합니다. Graphics.SetRenderTargetdepthSlice 인수는 렌더링할 밉맵 레벨 또는 큐브 맵 면을 지정합니다. “레이어드 렌더링”(즉 지오메트리 셰이더)을 지원하는 플랫폼에서 depthSlice 인수를 –1로 설정하여 전체 텍스처 배열을 렌더 타겟으로 설정할 수 있습니다. 지오메트리 셰이더를 사용하여 개별 요소로 렌더링할 수도 있습니다.

셰이더에서 텍스처 배열 사용

텍스처 배열은 모든 플랫폼에서 작동하지는 않으므로 셰이더에서 텍스처 배열에 액세스하려면 적절한 컴파일 타겟을 사용해야 합니다. 텍스처 배열을 지원하는 최소 셰이더 모델 컴파일 타겟은 3.5입니다.

텍스처 배열을 선언하고 샘플링하려면 다음 매크로를 사용해야 합니다.

  • UNITY_DECLARE_TEX2DARRAY(name)는 HLSL 코드 내에 텍스처 배열 샘플러 변수를 선언합니다.
  • UNITY_SAMPLE_TEX2DARRAY(name,uv)는 float3 UV가 있는 텍스처 배열을 샘플링합니다. 좌표의 z 컴포넌트는 배열 요소 인덱스입니다.
  • UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod)는 명시적 밉맵 레벨이 있는 텍스처 배열을 샘플링합니다.

예제

다음 셰이더 예제에서는 오브젝트 공간 버텍스 포지션을 좌표로 사용하여 텍스처 배열을 샘플링합니다.

Shader "Example/Sample2DArrayTexture"
{
    Properties
    {
        _MyArr ("Tex", 2DArray) = "" {}
        _SliceRange ("Slices", Range(0,16)) = 6
        _UVScale ("UVScale", Float) = 1.0
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // to use texture arrays we need to target DX10/OpenGLES3 which
            // is shader model 3.5 minimum
            #pragma target 3.5
            
            #include "UnityCG.cginc"

            struct v2f
            {
                float3 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            float _SliceRange;
            float _UVScale;

            v2f vert (float4 vertex : POSITION)
            {
                v2f o;
                o.vertex = mul(UNITY_MATRIX_MVP, vertex);
                o.uv.xy = (vertex.xy + 0.5) * _UVScale;
                o.uv.z = (vertex.z + 0.5) * _SliceRange;
                return o;
            }
            
            UNITY_DECLARE_TEX2DARRAY(_MyArr);

            half4 frag (v2f i) : SV_Target
            {
                return UNITY_SAMPLE_TEX2DARRAY(_MyArr, i.uv);
            }
            ENDCG
        }
    }
}

참고 항목

셰이더 디테일 수준(LOD)
Visual Studio로 DirectX 11 셰이더 디버깅