個人認為,紋理陣列是一個非常有用的圖形特性。紋理本質上是一個二維的圖形資料;通過紋理陣列,給圖形資料再加上了一個維度。這無疑會帶來一個巨大的效能提升:一次性傳輸大量的資料總是比分批次傳輸資料要快。
建立一個GameObject物件,並且加入Mesh Filter元件和Mesh Renderer元件。Mesh Filter我們可以設定Mesh為Quad,同時在Mesh Filter上掛一個我們新建的材質:
在這個GameObject物件上掛接一個我們建立的C#指令碼:
using Unity.Collections;
using UnityEngine;
[ExecuteInEditMode]
public class Note10Main : MonoBehaviour
{
public Texture2D texture1;
public Texture2D texture2;
[Range(0.0f, 1.0f)]
public float weight;
Material material;
// Start is called before the first frame update
void Start()
{
MeshRenderer mr = GetComponent<MeshRenderer>();
material = mr.sharedMaterial;
Texture2DArray texture2DArray = CreateTexture2DArray();
material.mainTexture = texture2DArray;
material.SetFloat("_Weight", weight);
}
Texture2DArray CreateTexture2DArray()
{
Texture2DArray texture2DArray = new Texture2DArray(texture1.width, texture1.height, 2,
texture1.format, false);
NativeArray<byte> pixelData1 = texture1.GetPixelData<byte>(0);
NativeArray<byte> pixelData2 = texture2.GetPixelData<byte>(0);
texture2DArray.SetPixelData(pixelData1, 0, 0, 0);
texture2DArray.SetPixelData(pixelData2, 0, 1, 0);
texture2DArray.Apply(false, false);
return texture2DArray;
}
// Update is called once per frame
void Update()
{
material.SetFloat("_Weight", weight);
}
}
這段C#指令碼的意思是,通過傳入兩個Texture2d,生成一個texture2DArray;並且,將這個texture2DArray傳入到材質中。需要注意的是紋理陣列中的每個紋理的引數如寬、高等引數都需要一致,否則不能組成紋理陣列。
材質使用我們自定義的Shader:
Shader "Custom/TextureArrayShader"
{
Properties
{
_MainTex ("Texture", 2DArray) = "" {}
_Weight ("Weight", float) = 0.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
UNITY_DECLARE_TEX2DARRAY(_MainTex);
float _Weight;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col0 = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(i.uv, 0));
fixed4 col1 = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(i.uv, 1));
return lerp(col0, col1, _Weight);
}
ENDCG
}
}
}
這裡實現的效果是,將紋理陣列中的兩個紋理根據權重進行混合。權重值也是在C#指令碼中傳入到Shader中的。在編輯器中將權重調整到中間一點的位置(例如0.5):
Shader程式碼也很好理解,關鍵在於紋理陣列相關的宏,其實是對hlsl或者glsl的封裝:
#define UNITY_DECLARE_TEX2DARRAY(tex) Texture2DArray tex; SamplerState sampler##tex
#define UNITY_SAMPLE_TEX2DARRAY(tex,coord) tex.Sample (sampler##tex,coord)
#define UNITY_DECLARE_TEX2DARRAY(tex) sampler2DArray tex
#define UNITY_SAMPLE_TEX2DARRAY(tex,coord) tex2DArray (tex,coord)