法线在世界空间 视角空间的转化

在进行一些光照计算时经常需要将法线和顶点坐标,光照转到同一个坐标系下

在游戏中发法线经常存储在切线线空间,当然也可以根据需要存储在是世界空间和模型空间等。

1.法线由切线空间转到世界空间
关键是求出切线空间到世界空间的变换矩阵,在顶点着色其中算出该矩阵,然后传递给片元着色器,(法线向量的的变化矩阵只需要3X3的矩阵即可,但是为了充分利用插值寄存器的存储空间,把世界空间的顶点位置存储在W分量中)得到一个3X4的矩阵。切线空间到世界空间的变换矩阵等于把世界空间的切线X轴,副法线y轴,法线Z轴的顺序按列排列。最后在片元着色其中把采样得到的法线乘以该矩阵,转化到世界空间下。由于在片元着色其中计算,所以计算量比较大。

顶点着色器代码
o.tTow1 = float4(WTangent.x,WBinormal.x,WNormal.x,worldPos.x);
o.tTow2 = float4(WTangent.y,WBinormal.y,WNormal.x,worldPos.y);
o.tTow3 = float4(WTangent.z,WBinormal.z,WNormal.x,worldPos.z);

片元着色器

float3 bump = UnpackNormal(tex2D(_bump,i,xy));
//切线空间到世界空间
float3 bumpW = normalize(half3(dot(o.tTow1.xyz,bump),half3(dot(o.tTow2.xyz,bump),half3(dot(o.tTow3.xyz,bump)));

如果一个变换仅存在平移和旋转,这个变换的逆矩阵就等于它的转置矩阵

2.光照和视角方向等从模型空间到切线空间
从模型空间到切线空间的变换矩阵,把切线X轴,副法线y轴,法线Z轴的顺序按行排列即可得到

//v.tangent.w和叉积结果进行相乘,W用来决定副切线的最终方向,因为垂直的方向跟左右手有关系
float3 binormal = cross(normalize(v,normal),normalize(v.tangent.xyz))*v.tangent.w;
float3X3 rotation = float3X3(tangent.xyz,binormal ,normal);//变换矩阵
lightDir = mul(rotation,lightDir).xyz;
ViewDir = mul(rotation,ViewDir).xyz;

你可能感兴趣的:(笔记,unity)