Cg 程式設計/Unity/置換貼圖
外觀

本教程介紹了置換貼圖,作為頂點著色器中紋理查詢應用的示例。
本教程需要一些關於紋理對映的知識,如“紋理球體”部分中所述。
本華夏公益教科書中的大多數教程僅在片段著色器中使用紋理查詢,因為頂點著色器中的紋理查詢是 Shader Model 3.0 特性,即,並非所有 GPU 都支援它(參見Unity 對平臺特定渲染差異的描述)。
然而,置換對映需要對每個頂點進行紋理值的查詢,該值用於位移,即移動每個頂點到新的位置。出於技術原因,我們不能使用標準的tex2d命令。相反,我們必須使用命令tex2dlod,使用一個四維向量來指定紋理座標,其中第四個分量為 0。(這確保我們始終從最精細的mipmap級別讀取值,並且我們不會請求 mipmap 級別自動計算,這在頂點著色器中是不可能的。)該命令可能如下所示
float4 dispTexColor = tex2Dlod(_DisplacementTex, float4(i.texcoord.xy, 0.0, 0.0));
其中i.texcoord.xy是兩個紋理座標。
下面的示例將得到的顏色dispTexColor轉換為灰度值,並將其縮放為使用者指定的統一_MaxDisplacement
float displacement = dot(float3(0.21, 0.72, 0.07), dispTexColor.rgb) * _MaxDisplacement;
然後,此位移值用於沿其表面法線向量移動每個頂點,即,我們將物件座標中的頂點位置(示例中的i.vertex)新增到與位移值相乘的表面法線向量(i.normal)。
float4 newVertexPos = i.vertex + float4(i.normal * displacement, 0.0);
請注意,i.normal是一個三維向量;因此,我們必須附加一個 0.0 座標以形成一個四維向量,然後才能將其新增到頂點位置。
其餘程式碼應用標準頂點變換,並使用無光照紋理貼圖對錶面進行著色。請確保將其用於具有相對較多頂點的網格上 - 否則位移表面將顯得相當“塊狀”。
Shader "Vertex Displacement" {
Properties {
_MainTex ("Main Texture", 2D) = "white" {}
_DisplacementTex ("Displacement Texture", 2D) = "white" {}
_MaxDisplacement ("Max Displacement", Float) = 1.0
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _MainTex;
uniform sampler2D _DisplacementTex;
uniform float _MaxDisplacement;
struct vertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 position : SV_POSITION;
float4 texcoord : TEXCOORD0;
};
vertexOutput vert(vertexInput i) {
vertexOutput o;
// get color from displacement map, and convert to float from 0 to _MaxDisplacement
float4 dispTexColor = tex2Dlod(_DisplacementTex, float4(i.texcoord.xy, 0.0, 0.0));
float displacement = dot(float3(0.21, 0.72, 0.07), dispTexColor.rgb) * _MaxDisplacement;
// displace vertices along surface normal vector
float4 newVertexPos = i.vertex + float4(i.normal * displacement, 0.0);
// output data
o.position = UnityObjectToClipPos(newVertexPos);
o.texcoord = i.texcoord;
return o;
}
float4 frag(vertexOutput i) : COLOR
{
return tex2D(_MainTex, i.texcoord.xy);
}
ENDCG
}
}
}
請注意,如果紋理影像邊緣的顏色不匹配,或者對應頂點的表面法線向量不匹配,則表面網格的邊緣可能無法對齊。
恭喜你,你已經完成了本教程。你看到了
- 如何在頂點著色器中使用紋理對映。
- 如何沿表面法線向量移動頂點位置。
如果你還想了解更多
- 關於紋理對映,你應該閱讀“紋理球體”部分中的描述。
- 關於
tex2dlod,你可以閱讀Unity 對平臺特定渲染差異的描述和Microsoft 對 tex2dlod 的描述。
除非另有說明,否則本頁上的所有示例原始碼均授予公有領域。