前几天尝试写一个传送门的shader,发现自己对坐标之间的变换掌握的不够熟练,趁着这阵子想整理shader相关的知识点,先把各种空间及之间转换整理一下。
1 模型空间-世界空间-观察空间-裁剪空间
建模时在模型空间进行,模型自带的坐标均为模型空间下的表示。
当模型被放到世界坐标系中时,表达某个模型的位置使用的是世界空间下的坐标,所以模型上对应的某一个点,必须相应的转化为世界空间下的坐标。
从模型空间到世界空间的变换 叫做 模型变换。
Unity的Shader中,模型空间的坐标由Renderer直接提供,作为顶点着色器的输入,语义为POSITION。如:
struct appdata
{
float4 vertex : POSITION;
}
由于我们能看到的渲染图像均是通过摄像机得到的,为了方便后续裁剪、投影等操作,所以在将模型从模型空间变换到世界空间之后,还需要将其转换到观察空间。所谓的观察空间,就是以摄像机位置为原点,摄像机局部坐标轴为坐标轴的坐标系。
从世界空间到观察空间的变换叫做观察变换(视图变换)。
坐标转换到观察空间后,由于直接使用摄像机的平截头体进行裁剪比较复杂(平截头体的边界方程求交困难),所以需要将其转化到裁剪空间。裁剪空间变换的思路是,对平截头体进行缩放,使近裁剪面和远裁剪面变成正方形,使坐标的w分量表示裁剪范围,此时,只需要简单的比较x,y,z和w分量的大小即可。
从观察空间到裁剪空间的变换叫做投影变换。
注意,虽然叫做投影变换,但是投影变换并没有进行真正的投影。
在顶点着色器中,模型、观察、裁剪空间的相关变换矩阵一般为以下几个:
别名 | 定义 | 含义 |
---|---|---|
UNITY_MATRIX_M | unity_ObjectToWorld | 模型变换矩阵 |
UNITY_MATRIX_V | unity_MatrixV | 视图变换矩阵 |
UNITY_MATRIX_P | glstate_matrix_projection | 投影变换矩阵 |
UNITY_MATRIX_VP | unity_MatrixVP | 视图投影变换矩阵 |
UNITY_MATRIX_MV | mul(unity_MatrixV, unity_Obj |