数学基础
参考games101和unity shader 入门精要
一些重点的推导
透视变换矩阵
-
将锥体压缩成长方体
-
将长方体压缩成中心移到原点
-
将长方体压缩成\([-2 , 2]^3\)的正方体 , [-1 , 1]也行
先将这个锥体压缩成和Znear(近平面)同宽同高的长方体 ,远平面Zfar
方法:假设一个4x4的仿射变换矩阵,找一些特殊的点
比如:近平面的点\(\left(\begin{matrix} x \\ y \\ Znear \\ 1\end{matrix}\right)\tag{2}\) 经过变换之后还是\(\left(\begin{matrix} x \\ y \\ Znear \\ 1\end{matrix}\right)\tag{2}\),也可以写成\(\left(\begin{matrix} x*Znear \\ y * Znear \\ Znear*Znear \\ Znear\end{matrix}\right)\tag{2}\)
再找一个远平面Zfar最中心的点\(\left(\begin{matrix} 0 \\ 0 \\ Zfar \\ 1\end{matrix}\right)\tag{2}\), 经过变换之后依旧是\(\left(\begin{matrix} 0 \\ 0 \\ Zfear \\ 1\end{matrix}\right)\tag{2}\) , 也可以写成\(\left(\begin{matrix} 0 \\ 0 \\ Zfar * Zfar\\ Zfar\end{matrix}\right)\tag{2}\)
将长方体压缩成中心移到原点
此时定义一个摄像头的视角fov , 还有一个宽高比 那么长方体上下左右坐标分别为
eye_fov = eye_fov * 0.5 * MY_PI / 180.0;
float top = tan(eye_fov) * zNear, bottom = -top;
float right = top * aspect_ratio, left = -right;
那么移动到原点的仿射变换方程为
将长方体压缩成\([-2 , 2]^3\)的正方体 , [-1 , 1]也行
最后 \(projection = orth * orth\_to\_orgin * perspective\_orth;\)
空间变换
上面的透视变换矩阵只是一种,还有一种高级用法:法线变换
法线变换:由法线空间变换到观察空间内
-
首先看空间变换是怎么回事,是怎么变的
父空间P以及子空间C , 一般有两种需求,1,从子空间变换到父空间;2,从父空间变换到子空间,只要把这个矩阵表示为正交矩阵,两者求一个就行,另一个转置即可
我们求从子空间变换到父空间
子坐标表示下的矢量或者坐标\(A_C\) 转换到父坐标空间\(A_p\)
\(A_p = M_{c->p} * A_c \\ M_{c->p}即为子空间变换到父空间的变换坐标\)
那么怎么求?
使用一个很简单的例子:
子空间的坐标轴在父空间的表示为\(X_C ,Y_C , Z_C , 以及O_C\)
还有一点子坐标空间内的\(A_C = (a , b , c)\)
那么从坐标原点\(O_c\) 走到\(A_c\) 即为 \(O_c + a * X_c + b * Y_c + c * Z_c\)
在父空间下面同样的步骤也会走到\(A_c\) , 但是此时此刻实在父空间下,也可以写成\(A_p = O_c + a * X_c + b * Y_c + c * Z_c\)
写成矩阵即为
\[A_p = \left(\begin{matrix}| & | & | & x_{O_c} \\X_c &Y_c&Z_c&Y_{O_c}\\|&|&|&Z_{O_c}\\0&0&0&1\end{matrix}\right) *\left(\begin{matrix}a\\b\\c\\1\end{matrix}\right)\\ M_{c->p} = {\left(\begin{matrix}| & | & | & x_{O_c} \\X_c &Y_c&Z_c&Y_{O_c}\\|&|&|&Z_{O_c}\\0&0&0&1\end{matrix}\right) } \]-
那么一个矢量从子空间变换到父空间的矩阵
因为上面是点,需要位移,这个是矢量,不需要位移把最后一行,最后一列去掉
\[M_{c->p} = {\left(\begin{matrix}| & | & | \\X_c &Y_c&Z_c\\|&|&|\end{matrix}\right) } \] -
那么从父空间到子空间的矩阵为
-
前提,这个矩阵必须正交,三个向量相互垂直(三个坐标轴肯定垂直) , 然后将三个向量单位化,ok
法线变换
在法线进行非同一伸缩变换的时候,不能够直接使用上述公式
法线不能,但是切线可以。
假设如同上面,切线为\(父空间下 T_p , 子空间下T_c\)
法线为\(父空间下 N_P, 子空间下N_c\)
切线变换公式
无论在父空间还是子空间下面法线始终和切线垂直
这个G为从子空间将法线变换到父空间的正交矩阵
上式等于
那么在unity中法线最后从子空间C变换到P空间是什么呢。
如有错误,敬请指正