目录
一、纹理数组
2D纹理数组的元素也称为切片或图层,它们可以用于实现自定义地形渲染系统或其他特殊效果。并不是所有平台都支持2D纹理数组,因为纹理数组需要受到底层图形 API 和 GPU 的支持。
纹理数组的导入
1、将源纹理导入unity ,在项目视图选择生成的纹理资源。unity在Inspector中显示纹理导入设置。
2、在 Inspector 中,将 Texture Shape 设置为 2D Array。Unity 显示 Columns 和 Rows 属性。
3、把 Columns 和 Rows 设置为适用于翻页纹理的值。
4、单击 Apply确认。
(有关更多信息,请参阅纹理导入设置)
平台支持
支持的平台:
1、Direct3D 11/12 (Windows)
2、OpenGL Core(Mac OS X、Linux)
3、Metal(iOS、Mac OS X)
4、OpenGL ES 3.0(Android、WebGL 2.0)
不支持的平台:
1、OpenGL ES 2.0
2、WebGL 1.0
(可使用 SystemInfo.supports2DArrayTextures 在运行时确定纹理数组支持情况)
在着色器中使用纹理数组
使用以下宏可声明和采样纹理数组:
UNITY_DECLARE_TEX2DARRAY(name) 在 HLSL 代码中声明纹理数组采样器变量。
UNITY_SAMPLE_TEX2DARRAY(name,uv) 使用 float3 UV 采样纹理数组;坐标的 z 分量是数组元素索引。
UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod) 使用显式 Mipmap 级别采样纹理数组。
由于纹理数组并非适用于所有平台,因此着色器需要使用适当的编译目标或功能要求来访问纹理数组。支持纹理数组的最低着色器模型编译目标为 3.5,功能名称为 2darray。
二、在脚本中创建二维纹理数组
在unity中的创建步骤
把脚本放到unity中,在顶部菜单栏中会显示Examples菜单栏,点击创建2DTextureArray,它会默认存储到你的工程中。 (这张图可以使用在shader中)
代码展示
using System.Collections;
using UnityEditor;
using UnityEngine;
public class Create2DTexArray : MonoBehaviour
{
[MenuItem("Examples/Create2DTextureArray")]
static void Create2DTextureArray()
{
// 设置纹理参数
int width = 32;
int height = 32;
int slices = 3;
TextureFormat format = TextureFormat.RGBA32;
bool mipChain = false;
// 创建纹理数组并应用参数
Texture2DArray textureArray = new Texture2DArray(width, height, slices, format, mipChain);
// 创建一个2D颜色数组,用于存储切片中每个像素的颜色数据
Color[] colors = new Color[width * height];
// 遍历每个切片
for (int slice = 0; slice < slices; slice++)
{
// 生成一个随机颜色
Color randomColor = new Color(Random.value, Random.value, Random.value, 1f);
// 将颜色数组中的所有像素设置为随机颜色
for (int color = 0; color < colors.Length; color++)
{
colors[color] = randomColor;
}
// 将切片的像素设置为颜色数组
textureArray.SetPixels(colors, slice);
}
// 通过将更新的像素上传到GPU,将更改应用于纹理数组
textureArray.Apply();
// 保存纹理数组到你的Unity项目中
AssetDatabase.CreateAsset(textureArray, "Assets/Example2DTextureArray.asset");
}
}
三、采样2D纹理数组贴图
代码展示
Shader "Example/Sample2DArrayTexture"
{
Properties
{
// 声明2D纹理数组
_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;
UNITY_DECLARE_TEX2DARRAY(_MyArr);
v2f vert (float4 vertex : POSITION)
{
v2f o;
o.vertex = UnityObjectToClipPos(vertex);
// 2D纹理数组uv是一个三维向量
o.uv.xy = (vertex.xy + 0.5) * _UVScale;
o.uv.z = (vertex.z + 0.5) * _SliceRange;
return o;
}
half4 frag (v2f i) : SV_Target
{
// 采样2D纹理数组贴图
float4 myArr = UNITY_SAMPLE_TEX2DARRAY(_MyArr, i.uv);
return myArr;
}
ENDCG
}
}
}
文献
- 纹理数组 - Unity 手册
- Direct3D 文档中的纹理简介 (Introduction To Textures)。
- OpenGL Wiki 中的数组纹理 (Array Textures)。