为什么我们需要第四个坐标除以z?

我在这里阅读回复:

显卡与vector的第四个元素作为最终位置是做什么的?

“第四部分是跟踪透视投影的一个技巧,当你做一个透视投影时,你想除以z:x'= x / z,y'= y / z,但这不​​是一个操作可以通过在x,y,z向量上运行的3×3matrix来实现,已经成为标准的技巧是追加第四个坐标w,并声明x,y,z将总是被w毕竟转换应用之后,光栅化之前“。

但我不明白为什么我们不能用z分割使用3x3matrix?

我们不能只乘以

1/z 0 0 0 1/z 0 0 0 1/z 

得到[x/zy/z 1]

因为如果你只用z[x, y, z] ,你会得到[x/z, y/z, 1]并且你失去了z的实际值,如果你想做near / far plane clipping或者填充一个Z缓冲区。

因此,至less在GPU上保留关于z一些信息的最好方法是使用4个分量而不是3个。实际上,在透视分割之前,最后两个向量分量实际上取决于什么样的投影和效果你要。

例如,在透视投影的情况下,这是得到的四分量vector:

 | a 0 0 0 | | x | | ax | | 0 b 0 0 | | y | | by | | 0 0 cd | × | z | = | cz + d | | 0 0 1 0 | | 1 | | z | 

透视分割vector变成:

 | ax/z | | by/z | | c + d/z | | 1 | 

c + d/z部分给我们留下足够的信息来填充Z缓冲区。

从技术上讲,你可以做到这一点。 但为什么要麻烦? 当你有最后的z ,你可以:

  • 如上所述构造一个3x3matrix,浪费9 * sizeof(float)字节的空间,花费周期来计算1/z (一个分割),然后做九个乘法和六个加法来获得最终的顶点, 或者
  • 你可以像现代管道那样做三个部门

其中一个对我来说似乎更加优化,而且不是第一个。 即使matrix乘法存在最优化的硬件,就像它确实那样,它在概念上仍然比简单的划分更复杂。

另外,一个3×3的matrix不能对一个平移进行编码,所以在stream水线的早期使用一个4x4matrix(以及第四个w坐标)。 这意味着你已经拥有了第四个组件,所以你可以使用它来传递有用的价值,并与之分工。