Version: 2018.3
シェーダー LOD
Visual Studio を使った DirectX 11/12 シェーダーのデバッグ

テクスチャ配列

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

テクスチャ配列は、サイズ、形式、フラグが同じ 2D テクスチャの集まりで、GPU からは単体のオブジェクトのように見えます。さらに、シェーダーからはテクスチャ要素インデックスでサンプリングすることができます。それらは、独自の環境 (terrain) レンダリングシステムを実装する場合や、サイズと形式が同じ多数のテクスチャにアクセスする必要がある特殊な効果を使う場合に有用です。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 にするとテクスチャ配列全体をレンダリングターゲットに設定することができます。また、ジオメトリシェーダーを使うと個々の要素にレンダリングすることができます。

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

テクスチャ配列はすべてのプラットフォームで動作するわけではないので、テクスチャ配列にアクセスするために、シェーダーは適切な コンパイルターゲット や機能要件を必要とします。テクスチャ配列をサポートする最小のシェーダーモデルのコンパイルターゲットは 3.5 で、機能名は 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
            // テクスチャ配列はどこででも使用可能なわけではありません
            // テクスチャ配列の位置するプラットフォームのコンパイルシェーダーのみです
            #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 編集レビュー を行って修正されたページ
  • シェーダー #pragma ディレクティブは Unity 2018.1 で追加
シェーダー LOD
Visual Studio を使った DirectX 11/12 シェーダーのデバッグ