一、需要提前了解的
无论是用哪种图形接口,又或是游戏引擎,入门的数学公式和逻辑就是那一套:
- 基础线代公式汇总:https://blog.csdn.net/Jaihk662/article/details/103811465
- 欧拉角:https://blog.csdn.net/Jaihk662/article/details/106519595
- 基本空间:https://blog.csdn.net/Jaihk662/article/details/106237306
- 法向量/切线空间:https://blog.csdn.net/Jaihk662/article/details/106640285 & https://blog.csdn.net/Jaihk662/article/details/107917594
顺序有关,①③是必须掌握的,没有办法
想要深入了解的话线性代数的话推荐3B1B的视频,讲的非常好:https://www.bilibili.com/video/BV1ys411472E
二、Unity内置变换矩阵
- UNITY_MATRIX_MVP:模型 x 观察 x 投影矩阵,将目标由模型空间变换到裁剪空间
- UNITY_MATRIX_MV:模型 x 观察矩阵,将目标由模型空间变换到观察空间
- UNlTY_MATRIX_VP:观察 x 投影矩阵,将目标由世界空间变换到裁剪空间
- UNlTY_MATRIX_V:观察矩阵
- UNITY_MATRIX_P:投影矩阵
- unity_ObjectToWorld:模型矩阵
- unity_WorldToObject:模型矩阵的逆矩阵
- UNlTY_MATRIX_T_MV:UNITY_MATRIX_MV 的转置矩阵,只要没有平移变换,那么这个矩阵就可以当作逆矩阵来参与计算。注意缩放的话要除以缩放倍数,因为此时 UNITY_MATRIX_MV 不是标准的正交矩阵
- UNlTY_MATRIX_IT_MV:UNITY_MATRIX_MV 的逆转置矩阵,用于将法线从模型空间变换到观察空间,再次转置就直接是 UNITY_MATRIX_MV 的逆矩阵了
三、Unity内置的摄像机屏幕参数
- _WorldSpaceCameraPos(float3):摄像机在世界空间的位置
- _ProjectionParams(float4):摄像机投影矩阵参数,x为1或-1(投影矩阵是否翻转),y为近平面到摄像机的距离,z为远平面到摄像机的距离,w = 1 + 1/z
- _ScreenParams(float4):x = width, y = height, z = 1 + 1/width, w = 1 + 1/height,其中 width 和 height 分别是该摄像机渲染目标(render target)的像素宽高
- _ZBufferParams(float4):x = 1 - Far/Near, y = Far/Near, z = x/Far, w = y/Far,用于线性化 Z 缓存中的深度值,方便计算
- unity_OrthoParams(float4):x 和 y 是正交投影的宽和高,w表示当前是否是正交摄像机(1or0),z无用
- unity_CameraProjection(float4x4):摄像机投影矩阵
- unity_CameralnvProjection(float4x4):摄像机投影矩阵的逆矩阵
- unity_CameraWorldClipPlanes[6]:相机6个裁剪平面的世界空间方程(ax+by+cz+d),按顺序为:左、右、底部、顶部、近、远
屏幕坐标的获取:
一种是在片元着色器的输入中声明 VPOS(HLSL) 或 WPOS(CG) 语义,一个参考如下:
fixed4 frag(float4 sp: VPOS): SV_Target
{
return fixed4(sp.xy/_ScreenParams.xy, 0.0, 1, 0);
}
VPOS/WPOS 语义定义的输入是一个 float4 类型的变量,其值和 GLSL 内建变量 gl_FragCoord 的值相似,其中小数部分恒为(0.5, 0.5),整数部分就是数第几个像素点了,若屏幕分辨率为 2560 x 1440,x, y 的取值范围就为(0.5, 0.5, 2560.5, 1440.5);z坐标为当前片元的深度信息,远裁剪平面处 z 为 1,近平面处 z 为 0;w 分量范围为 ,Near 和 Far 对应了在 Camera 组件中远近平面到摄像机的距离;如果使用的是正交投影,那么 w 分量的值恒为 1
还有一种方法是通过 Unity 提供的 ComputeScreenPos 函数,这个函数在 UnityCG.cginc 中被定义,不过这种方法获得的 xy 值需要手动进行齐次除法(除以 )的操作,z值的范围是[-Near, Far],w值的范围是[Near, Far],正好是裁剪空间中的 zw 值,这样如果使用的是正交投影,那么 z 值范围就是 [-1, 1],w 值恒为 1