齐次坐标
非常神奇的做法, 把仿射变换和透视投影操作统一成了矩阵乘法操作. (虽然之前好像在 Games101 的笔记中简单稍微写了一点, 不过这次具体的再说说)
仿射变换
对于一个三维坐标, 它的缩放 / 旋转 都可以使用一个矩阵乘法表示 ——
这样虽然没有问题, 我们先写出一次变换的通用形式 ——
那么对于组合变换来说, 就是一堆类似的操作嵌套. 假设我们在当前的框架下按照操作顺序楞算, 绝对是没有问题的, 但是如果拓展到空间中的所有点呢? 如果我们有大量的点都需要做同样的变换, 那么按照一个一个嵌套的来算, 我们没有任何一个中间结果可以拿去复用. 于是这条计算管线就会非常贵. 那么假设我们可以先把这个嵌套操作给展开, 之后它依旧是一个
此处的拦路虎是平移, 如果平移也可以使用矩阵乘法来实现的话, 我们就可以非常方便的左乘过去, 让最后的形式非常方便的写成
于是对于每一个点, 我们将其拓展到四维的齐次坐标系下 ——
此时, 平移就可以写作 ——
不赖.
那么对于一个方向向量来说, 我们会把它表示成
所以加入的
不过值得注意的, 对于
透视投影
透视有一个非常核心的现象 —— 「近大远小」, 也就是在视觉上, 越远的东西看起来越小. 比如在一个简化的针孔摄像机的模型中(焦距
假设在 View 的空间中存在两个三维点
假设
我们当然无法消去除法这个操作, 因为实际上矩阵乘法能做的仅是线性变换罢, 不过我们可以把“除法信息”压入一个矩阵, 也就是 Projection 矩阵来进行实现, 这样在最后仅需要做除
还是先说上述的最简单的情况,
然后由于是二维平面, 所以舍去最后的 -1 即得到我们投影在投影面上的结果了.所以如果我们可以构造一个矩阵, 使得
让这个点就表示我们透影之后的点不就好了? —— 因为上文说过, 我们在真的使用一个点的时候会执行一次除
可以快速的得到, 此处构造出来的 Projection 为
也就是我们借助了一个 P 矩阵实现了把透视除法信息压入, 不赖. 不过实际上要复杂许多, 要考虑整个视锥体, 略复杂一些, 后面在计算机图形学中具体推导如何推导出那个情况下的 P 吧.
而且实际上情况下, 我们不会简单的让所有经过 P 的矩阵的 z 都为 -1, 这样会丢失掉深度信息, 导致之后深度测试/ early-z 之类的算法难于运作. 所以会构造一些更好的 P (实际上就是让乘法之后的