Unity は、通常の 2D テクスチャ (Texture2D クラス、シェーダーの sampler2D )、 キューブマップ (Cubemap クラス、シェーダーの samplerCUBE )、3D テクスチャ (Texture3D クラス、シェーダーの sampler3D ) 同様、2D テクスチャ配列もサポートします。
テクスチャ配列は、サイズ、形式、フラグが同じ2Dテクスチャの集まりで、GPUからは単体のオブジェクトのように見えるので、シェーダーからはテクスチャエレメントのインデックスでサンプリングすることができます。独自の環境レンダリングシステムを実装する場合や、その他の特殊な効果のために、サイズと形式が同じたくさんのテクスチャにアクセスする場合に便利です。2Dテクスチャ配列のエレメントは、スライスやレイヤーとしても知られています。
テクスチャ配列には基礎となるグラフィックス API と GPUによるサポートが必要です。以下のプラットフォームで可能です。
他のプラットフォームはテクスチャ配列をサポートしません (Direct3D 9, OpenGL ES 2.0 or WebGL 1.0)。ランタイムにテククチャ配列のサポートを判断するには SystemInfo.supports2DArrayTextures を使用します。
テクスチャ配列をインポートするパイプラインはないので、自前のスクリプトから生成しなくてはなりません。テクスチャ配列の生成と操作には、 Texture2DArray クラスを使います。テクスチャ配列はアセットとしてシリアライズが可能なので、エディタースクリプトから生成してデータで満たすことも可能です。
通常、テクスチャ配列は完全に GPU メモリ内で使用されます。ただし、Graphics.CopyTexture, Texture2DArray.GetPixels, Texture2DArray.SetPixels はピクセルをシステムメモリに変換したり、その逆を行うのに使用できます。
テクスチャ配列の要素はレンダリングターゲットとして使用されることもあります。レンダリングターゲットを 2D テクスチャ配列するかどうかを事前に特定するには、RenderTexture.dimension を使用します。Graphics.SetRenderTarget の depthSlice 引数は、レンダリングするミップマップレベルやキューブマップ面を特定します。「レイヤーレンダリング」 (例えば、ジオメトリシェーダーなど) をサポートするプラットフォーム上で、depthSlice 引数を –1 にするとテクスチャ配列全体をレンダリングターゲットに設定することができます。また、ジオメトリシェーダーを使うと個々の要素にレンダリングすることができます。
テクスチャ配列はすべてのプラットフォームで使用できるわけではないので、シェーダーはそれらにアクセスするために、適切な コンパイルターゲット を使用する必要があります。テクスチャ配列をサポートするため最低限のシェーダーモデルのコンパイルターゲットは3.5 です。
テクスチャ配列を宣言してサンプリングするには、以下の マクロ を使用します。
以下のシェーダーの例は、オブジェクトの空間の頂点位置を使用してテクスチャ配列をサンプリングしています。
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
// テクスチャ配列を使うには、DX10/OpenGLES3、つまり、
// シェーダーモデル 3.5 以上をターゲットにする必要があります。
#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
}
}
}