为什么我在OpenGL的透视投影中将Z除以W?

时间:2014-08-30 16:44:10

标签: c++ opengl math matrix

我想这是一个数学问题而不是OpenGL问题,但我离题了。无论如何,如果透视划分的整个目的是获得可用的x和y坐标,为什么还要将z除以w呢?另外我如何才能获得w?

1 个答案:

答案 0 :(得分:14)

实际上,解释与深度缓冲区的限制有很大关系,而不是数学。

最简单的是,"深度缓冲区是一种纹理,其中每个屏幕上的像素根据其与相机的距离分配灰度值。这使得视觉效果很容易随距离而变化。" Source

更准确地说,深度缓冲区是一个纹理,其中包含每个fragment z / w 的值,其中:

  • Z 是从近剪裁平面到片段的距离。
  • W 是从相机到片段的距离。

在下图中说明 z w z / w 之间的关系, n 等于传递给gluPerspectivezNear参数或等效函数, f 等于传递给zFar的{​​{1}}参数相同的功能。

Diagram illustrating the relationship between *z*, *w*, and *z*/*w*

乍一看,这个系统看起来不直观。但结果是, z / w 始终是介于0和1之间的浮点值(0 / n f < / em> / f ),因此可以表示为纹理的单个通道。

第二个重要注意事项:深度缓冲区是非线性的,这意味着在深度缓冲区中,精确位于近剪裁平面和远剪裁平面之间的对象远未接近0.5的值。如上所示,它将与深度缓冲区中的值0.999相关联。根据您的观点,这可能是好的也可能是坏的;你可能希望深度缓冲区更加详细(特写),或者提供整个细节(它没有)(

)。

TL; DR:

  • 您将 z 除以 w ,因此它始终在[0,1]范围内。
  • W 是从相机到片段的距离。