UnityTips:法线的空间变化

法线空间转换

通常法线空间转换,使用下面两种方法

1使用内置函数

1
2
o.normalWS = unity_ObjectToWorldNormal(v.normalOS);
o.tangentWS = UnityObjectToWorldDir(v.tangentOS);

2使用矩阵乘法

1
2
o.normalWS = mul(float4(v.normalOS, 0.0), unity_WorldToObject).xyz;
o.tangentWS = mul(unity_ObjectToWorld, float4(v.tangentOS.xyz, 0.0)).xyz;

D:\Unity\2022.3.62f3c1\Editor\Data\CGIncludes\UnityCG.cginc。在源文件中Unity的转换方法是这样的。

关于法线的矩阵乘法顺序

对于法线和切线转换,调用顺序是不一样的,这是为什么呢

1
2
o.normalWS = mul(float4(v.normalOS, 0.0), unity_WorldToObject).xyz;
o.tangentWS = mul(unity_ObjectToWorld, float4(v.tangentOS.xyz, 0.0)).xyz;

通常来说,以切线为准,切线直接使用unity_ObjectToWorld转换就可以了

1
o.tangentWS = mul(unity_ObjectToWorld, float4(v.tangentOS, 0.0));

法线转换是不能直接这样做的,因为在非均匀缩放的时候法线会跟着变。这里需要推一下

副切线(副法线)

1
2
o.binormalWS = normalize(cross(o.normalWS, o.tangentWS)) * v.tangent.w;
//* v.tangent.w是为了处理不同平台副法线翻转问题



    Enjoy Reading This Article?

    Here are some more articles you might like to read next:

  • URP - RendererFeature :ScreenSpaceOutline
  • 平滑法线处理 - 八面体映射
  • Lv.3 Unity主线:一个简单的PBRShader
  • 理论支线:直接光漫反射与GGX高光的混合问题
  • 理论支线:PBR - 基于图像的照明( image based lighting-IBL)
  • # #