シェーダー LOD
Debugging DirectX 11/12 shaders with Visual Studio

テクスチャ配列

Unity は、通常の 2D テクスチャ (Texture2D クラス、シェーダーの sampler2D )、 キューブマップ (Cubemap クラス、シェーダーの samplerCUBE )、3D テクスチャ (Texture3D クラス、シェーダーの sampler3D ) 同様、2D テクスチャ配列もサポートします。

テクスチャ配列は、サイズ、形式、フラグが同じ2Dテクスチャの集まりで、GPUからは単体のオブジェクトのように見えるので、シェーダーからはテクスチャ要素でサンプリングすることができます。独自の環境レンダリングシステムを実装する場合や、その他の特殊な効果を使うために、たくさんのサイズと形式が同じテクスチャにアクセスする場合に便利です。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

他のプラットフォームはテクスチャ配列をサポートしません (OpenGL ES 2.0 or WebGL 1.0)。ランタイムにテクスチャ配列のサポートを定義するには、SystemInfo.supports2DArrayTextures を使用します。

テクスチャ配列の作成と操作

テクスチャ配列をインポートするパイプラインはないので、自前のスクリプトから生成しなくてはなりません。テクスチャ配列の作成と操作には、 Texture2DArray クラスを使います。テクスチャ配列はアセットとしてシリアライズが可能なので、エディタースクリプトから作成することも可能です。

通常、テクスチャ配列は完全に GPU メモリ内で使用されます。ただし、Graphics.CopyTexture, Texture2DArray.GetPixels, Texture2DArray.SetPixels はピクセルをシステムメモリに変換したり、その逆を行うのに使用できます。

レンダリングターゲットとしてのテクスチャ配列の使用

テクスチャ配列の要素はレンダリングターゲットとして使用されることもあります。レンダリングターゲットを 2D テクスチャ配列にするかどうかを事前に取得するには、RenderTexture.dimension を使用します。Graphics.SetRenderTargetdepthSlice 引数は、レンダリングするミップマップレベルやキューブマップ面を指定します。「レイヤーレンダリング」 (例えば、ジオメトリシェーダーなど) をサポートするプラットフォーム上で、depthSlice 引数を –1 にするとテクスチャ配列全体をレンダリングターゲットに設定することができます。また、ジオメトリシェーダーを使うと個々の要素にレンダリングすることができます。

シェーダーでのテクスチャ配列の使用

Since texture arrays do not work on all platforms, shaders need to use an appropriate compilation target or feature requirement to access them. The minimum shader model compilation target that supports texture arrays is 3.5, and the feature name is 2darray.

テクスチャ配列を宣言してサンプリングするには、以下の マクロ を使用します。

  • 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
            // texture arrays are not available everywhere,
            // only compile shader on platforms where they are
            #pragma require 2darray
            
            #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
        }
    }
}

関連項目


  • 2018–03–20 編集レビュー を行って修正されたページ
  • Shader #pragma directives added in Unity 2018.1
シェーダー LOD
Debugging DirectX 11/12 shaders with Visual Studio