在使用顶点着色器进行纹理坐标的光照计算过程中(也就是说在切线空间下计算)
在顶点着色器的函数体中
有
v2f vert(a2v v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
o.uv.zw = v.texcoord.zw * _BumpMap_ST.xy + _BumpMap_ST.zw;
float3 binormal = cross(normalize(v.normal),normalize(v.tangent.xyz))*v.tangent.w;
float3x3 rotation = float3x3(v.tangent.xyz,binormal,v.normal);
o.lightDir = mul(rotation,ObjSpaceLightDir(v.vertex));
o.viewDir = mul(rotation,ObjSpaceViewDir(v.vertex));
return o;
}
书中的0.uv.zw使用的v.texcoord.xy
当时我的想法是纹理和法线纹理两套纹理,而且在顶点着色器的输入结构体中
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord : TEXCOORD0;
};
纹理使用的是float4类型,就让我以为顶点上绑定的两套纹理,事实上并不是,顶点上只绑定了一套纹理但是有两张纹理图可以通过sampler2D采样器使用顶点上绑定的唯一一套纹理采样出两个结果(纹理结果和法线结果),所以这个地方并能使用.zw坐标,事实上这个地方并没有必要使用float4类型的声明。
需要注意的是a2v结构体中声明的纹理都是模型中的顶点绑定的纹理,顶点绑定的纹理坐标通过a2v传递进顶点着色器。
顶点着色器输出的仅仅是两套纹理坐标罢了(加上偏移和缩放,之所以用两套是为了两个纹理有不同的缩放和偏移),然后在片段着色器中进行对两张纹理的采样运算,达到分别控制的目的。