【问题标题】:Why do I divide Z by W in a perspective projection in OpenGL?为什么在 OpenGL 的透视投影中将 Z 除以 W?
【发布时间】:2014-10-24 10:23:30
【问题描述】:

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

【问题讨论】:

  • 这与齐次坐标有关。他们映射 R^3 -> R^4 显然不是一对一的。 w 因子可以“规范化”为 1。但是应用 4x4 矩阵运算符时,结果“w”可能会改变。如果我没记错的话,齐次坐标的一个优点是将平移作为线性算子。

标签: c++ opengl math matrix


【解决方案1】:

实际上,这个解释更多地与深度缓冲区的限制有关,而不是数学。

最简单的说法是,“深度缓冲区是一种纹理,其中每个屏幕像素都根据其与相机的距离分配一个灰度值。这使得视觉效果可以轻松地随着距离而改变。” Source

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

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

在下图中说明zwz/w之间的关系>n 等于传递给gluPerspectivezNear 参数或等效函数,f 等于传递给同一函数的zFar 参数。 p>

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

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

TL;DR:

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

【讨论】:

  • 我真的不太同意这个答案,这个问题属于纯数学问题,这里解释的是opengl和z-buffer算法实现细节(深度缓冲区)。跨度>
  • NDC 中的 z 在 [-1, 1] 范围内,而不是 DirectX 约定的 [0, 1]。
  • 为什么在最远的片段,w 和 z 都是 f? w 和 z 起点之间有“n”个距离。谢谢。
  • Z is the distance from the near clipping plane to the fragment. W is the distance from the camera to the fragment. 我想我可以有把握地假设这些句子也适用于 DirectX。
猜你喜欢
  • 2012-05-15
  • 2013-04-17
  • 2013-11-26
  • 2016-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多