Hi, guys
I want to convert normals (sampled from a bump map) from tangent space to world space. I found that the built-in shaders such as “Bumped Diffuse” use a matrix from tangent space to world space (Tangent2World) to transform the normal, like this:
v2f vert(a2v v) {
float3 worldPos = mul(_Object2World, v.vertex).xyz;
fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;
o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
}
fixed4 frag(v2f i) : SV_Target {
fixed3 bump = UnpackNormal(tex2D(_BumpMap, i.uv));
bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)));
}
However, I’ve learned that a normal vector is correctly transformed using the inverse transpose of the matrix used to transform points, in this case, the transpose of the World2Tangent matrix.
So, why unity uses the Tangent2World directly to transform the normals? Will non-uniform scale
cause wrong results?