Unity中的法线变换

Unity中的法线变换

  • 前言
  • 一、特殊的法线变换


前言

最近,在学习UnityCG.cgjnc源码时,发现在非统一变换下,矩阵变换变成了左乘,顿时充满了疑惑,故此文章推导官方为啥这么写。
Unity中的法线变换_第1张图片


符号 含义
T o T_o To 模型空间下顶点的切线向量
T w T_w Tw 世界空间下顶点的切线向量
N o , N w N_o,N_w NoNw 同上,N表示法线向量
M o w M_{ow} Mow 模型空间到世界空间的变换矩阵
M w o M_{wo} Mwo 世界空间到模型空间的变换矩阵
G G G 法线向量从模型空间到世界空间的变换矩阵

一、特殊的法线变换

在计算光照的时候,我们常常会用到世界空间坐标下的法线。对于顶点的切线向量 T w T_w Tw ,可由下列公式得到:
T w = M o w ⋅ T o T_w = M_{ow} \cdot T_o Tw=MowTo
单独来说,顶点的法线向量,也可通过上式变换。但是,变换后的法线向量却不一定与变换后的切线向量垂直了。具体可看乐乐女神的图解,
Unity中的法线变换_第2张图片
所以,为了求得 N w N_w Nw,我们得利用切线与法线垂直的关系。即:
T w ⋅ N w = 0 T_w \cdot N_w = 0 TwNw=0
因此,我们可以进行如下公式推导:
T w ⋅ N w = 0 ( M o w ⋅ T o ) ⋅ ( G ⋅ N o ) = 0 T o T ⋅ ( M o w T ⋅ G ) ⋅ N o = 0 T_w \cdot N_w = 0 \\ (M_{ow} \cdot T_o) \cdot (G \cdot N_o) = 0 \\ T_o^T \cdot (M_{ow}^T \cdot G) \cdot N_o = 0 \\ TwNw=0(MowTo)(GNo)=0ToT(MowTG)No=0
因为 T o T ⋅ N o = 0 T_o^T \cdot N_o =0 ToTNo=0, 所以只要 M o w T ⋅ G = I M_{ow}^T \cdot G = I MowTG=I,上式即可成立。
故,
G = ( M o w T ) − 1 G = ( M o w − 1 ) T G = (M_{ow}^T)^{-1} \\ G = (M_{ow}^{-1})^T \\ G=(MowT)1G=(Mow1)T
因此, N w = ( M o w − 1 ) T ⋅ N o N_w = (M_{ow}^{-1})^T \cdot N_o Nw=(Mow1)TNo,再来个双重转置可得, N w = N o T ⋅ M o w − 1 N_w = N_o^T \cdot M_{ow}^{-1} Nw=NoTMow1,又因为 M o w − 1 = M w o M_{ow}^{-1} = M_{wo} Mow1=Mwo,所以最终得到:
N w = N o ⋅ M w o N_w = N_o \cdot M_{wo} Nw=NoMwo
这个公式,就是源码中的实现方式。

你可能感兴趣的:(Unity,Shader,Unity学习笔记,unity,着色器,技术美术)