纹理数组是具有相同大小/格式/标记的 2D 纹理的集合,这些纹理对于 GPU 而言像是单个对象,并可在着色器中使用纹理元素索引进行采样。它们可以用于实现自定义地形渲染系统或其他特殊效果,让您高效访问大量相同大小和格式的纹理。2D 纹理数组的元素也称为切片或图层。
纹理数组需要受到底层图形 API 和 GPU 的支持。纹理数组在以下平台上可用:
Some platforms don’t support texture arrays. Use SystemInfo.supports2DArrayTextures to determine texture array support at runtime.
可以从划分成单元格的源纹理文件导入纹理数组。这些被称为翻页纹理。为此需要执行以下操作:
有关更多信息,请参阅纹理导入设置。
从 C# 脚本创建纹理数组,使用 Texture2DArray 类来初始化纹理和设置像素数据,并使用 AssetDatabase.CreateAsset 将对象保存为资源文件。
通常,纹理数组完全是在 GPU 内存中使用,但您可以使用 Graphics.CopyTexture、Texture2DArray.GetPixels 和 Texture2DArray.SetPixels 与系统内存之间双向传输像素。
纹理数组元素也可用作渲染目标。使用 RenderTexture.dimension 提前指定渲染目标是否是 2D 纹理数组。Graphics.SetRenderTarget 的 depthSlice 参数可指定要渲染到的 Mipmap 级别或立方体贴图面。在支持“分层渲染”(例如,几何着色器)的平台上,可将 depthSlice 参数设置为 –1 以便将整个纹理数组设置为渲染目标。此外还可使用几何着色器来渲染到个别元素中。
由于纹理数组并非适用于所有平台,因此着色器需要使用适当的编译目标或功能要求来访问纹理数组。支持纹理数组的最低着色器模型编译目标为 3.5
,功能名称为 2darray
。
使用以下宏可声明和采样纹理数组:
以下着色器示例通过使用对象空间顶点位置作为坐标来采样纹理数组:
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
}
}
}
Texture2DArray