在上一篇专栏中涉及了不少Unity中坐标空间变换的内容,因为数学不好,所以特地撰写一篇文章补一下,从头推导Unity Shader中那些常用的矩阵。
线性变换
3D CG中常用的四维向量通常由一个三维的向量
形如
缩放
对于三维空间的一个点
绕坐标轴的旋转
Unity使用的是左手坐标系,因此也以左手坐标系进行推导。判断是左手坐标系还是右手坐标系的方法很简单,我们都假设
左手坐标系的旋转方向如左手所示,拇指指向绕轴的正向,四指自然弯曲,即旋转的正方向。
先从2D坐标系看,如下图所示,
因此有:
将其展开:
带入
如果写成矩阵形式就是:
这里推出的2D情形,显然可以被视为是绕
其他绕坐标轴的矩阵也可推知:
我们知道矩阵运算不满足乘法交换律,因此有必要明确旋转的顺序。在Unity的Transform.Rotate文档中指明:
Applies a rotation of eulerAngles.z degrees around the z axis, eulerAngles.x degrees around the x axis, and eulerAngles.y degrees around the y axis (in that order).
即先绕
绕任意轴的旋转
这里不考虑平移,假定所绕轴过原点,且单位向量为
![v2-eb0ca59088a3d5d6f4e07b603564f519_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=9278bc58-8c2e-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-eb0ca59088a3d5d6f4e07b603564f519_b.jpg)
可见,
而
目前仅仅得出一个式子,而没有矩阵
众所周知,向量也可以写成列矩阵的形式,将三个基向量旋转之后的列矩阵合并,即可得
仿射变换
平移并不是线性变换,因为
平移
上述给出的缩放和旋转矩阵,只是3x3的部分。平移矩阵的将使用到矩阵的第四列:
模型空间转世界空间
从模型空间转换到世界空间需要考虑Transform的父子关系问题。先不考虑父子关系,则依循先缩放、在旋转、最后平移的原则,模型空间的某点应当以如下方式换算:
如果Transform仍有父亲,则继续按照如上原则计算,直至抵达世界空间。
世界空间转视口空间
我习惯称呼为视口空间,实际上也可以叫观察空间(view space)或者摄像机空间(camera space),指的是相机进行观察的特殊模型空间。Unity的相机空间是右手坐标系。
这一块的计算与模型空间转世界空间恰好相反,要将摄像机作为世界的原点,操作顺序反转的同时,旋转顺序也变成了
视口空间转裁剪空间
众所周知,Camera有正交和透视两种模式,这两种模式最大的区别就在于视锥体的不同,一个是长方体,一个是平头四棱锥。裁剪空间是左手坐标系,这个矩阵可以通过Camera.projectionMatrix拿到。
视锥体可以用六个参数表示,分别是视锥体的六个面,简写成:
![v2-0527f5dbbacbe60f5d72b43631e2a0b6_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=9278bc58-8c2e-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-0527f5dbbacbe60f5d72b43631e2a0b6_b.jpg)
透视投影矩阵
既然是投影,那么必然存在着降维:令视口空间内存在某点
注意此处仍是视口空间,右手坐标系,故
同理:
带入根据相似三角形计算的值:
同理:
这里的
有必要明确一下,
在上述矩阵中,
得到了一个方程之后,我们取两个边界解
最后,透视投影矩阵
考虑到视口空间中的视锥体都是关于
实际上我们对Camera的控制并没有到直接设置六个面的程度,那样既不方便,也不够直观,相反我们使用以下3个参数Viewport Rect、FOV、Clipping Plane,Viewport Rect的W和H共同决定了aspect,
宽度就更简单了:
于是,矩阵可做如下表达:
正交投影矩阵
对于正交投影而言,就更简单,直接做线性映射就行,以
其他分量如法炮制成:
可以看到,相对于透视投影矩阵而言,正交投影矩阵进行了整体的缩放和平移;而透视投影矩阵在各分量上缩放程度不同,还将
裁剪
这时GPU就可以根据矩阵运算后的结果来决定一个片元是否应该被裁剪了,如果一个顶点在视锥体内,则变换后的坐标必须满足:
这是显而易见的,因为无论是透视投影还是正交投影我们推导的时候就要求映射到
裁剪空间投影到屏幕空间
裁剪之后,将三维坐标映射到二维空间中,进行真正的投影。首先做齐次除法,拿到归一化的设备坐标。进行完这一步后,无论是透视投影还是正交投影,裁剪空间都被变换成了一个三个轴向上范围都是
其次将设备参数考虑进去,把
参考文献
【1】计算机图形学之四维齐次坐标 - J1ac - 博客园
【2】软渲染器Soft Renderer:3D数学篇
【3】《Unity Shader入门精要》