I guess this is more a math question than it is an OpenGL one, but I digress. Anyways, if the whole purpose of the perspective divide is to get usable x and y coordinates, why bother dividing z by w? Also how do I get w in the first place?
我想这是一个数学问题,而不是OpenGL的问题,但我跑题了。不管怎样,如果透视的全部目的是为了得到可用的x和y坐标,为什么要把z除以w呢?我怎么得到w呢?
1 个解决方案
#1
12
Actually, the explanation has much more to do with the limitations of the depth buffer than it does math.
实际上,这个解释与深度缓冲的局限性有关,而不是数学。
At its simplest, "the depth buffer is a texture in which each on-screen pixel is assigned a grayscale value depending on its distance from the camera. This allows visual effects to easily alter with distance." Source
在最简单的情况下,“深度缓冲是一种纹理,每个屏幕上的像素根据其与摄像机的距离来分配灰度值。这使得视觉效果可以轻易地改变距离。源
More accurately, a depth buffer is a texture containing the value of z/w for each fragment, where:
更准确地说,深度缓冲是一个包含每个片段的z/w值的纹理,其中:
- Z is the distance from the near clipping plane to the fragment.
- Z是距离近剪切面到碎片的距离。
- W is the distance from the camera to the fragment.
- W是距离摄像机到碎片的距离。
In the following diagram illustrating the relationship between z, w, and z/w, n is equal to the zNear
parameter passed to gluPerspective
, or an equivalent function, and f is equal to the zFar
parameter passed to the same function.
下图说明了z、w和z/w之间的关系,n等于传递给gluPerspective的zNear参数,或等效函数,f等于传递给相同函数的zFar参数。
At a glance, this system look unintuitive. But as a result, z/w is always a floating-point value between 0 and 1 (0/n and f/f), and can therefore be represented as a single channel of a texture.
乍一看,这个系统看起来不太直观。但是,z/w始终是0到1 (0/n和f/f)之间的浮点值,因此可以表示为纹理的单个通道。
A second important note: the depth buffer is nonlinear, meaning an object exactly in between the near and far clipping planes is nowhere near a value of 0.5 in the depth buffer. As shown above, it would correlate to a value of 0.999 in the depth buffer. Depending on your view, this could be good or bad; you may want the depth buffer to be more detailed close-up (which it is), or offer even detail throughout (which it doesn't).
另一个重要的注意事项:深度缓冲是非线性的,这意味着在深度缓冲中,近距离和远剪切面之间的距离远小于0.5。如上所示,它与深度缓冲区中的0.999的值相关。根据你的观点,这可能是好是坏;您可能希望深度缓冲是更详细的特写(它是),或者提供更详细的(它没有)。
TL;DR:
TL;博士:
- You divide z by w so it is always in the range [0, 1].
- 你把z除以w,所以它总是在范围[0,1]。
- W is the distance from the camera to the fragment.
- W是距离摄像机到碎片的距离。
#1
12
Actually, the explanation has much more to do with the limitations of the depth buffer than it does math.
实际上,这个解释与深度缓冲的局限性有关,而不是数学。
At its simplest, "the depth buffer is a texture in which each on-screen pixel is assigned a grayscale value depending on its distance from the camera. This allows visual effects to easily alter with distance." Source
在最简单的情况下,“深度缓冲是一种纹理,每个屏幕上的像素根据其与摄像机的距离来分配灰度值。这使得视觉效果可以轻易地改变距离。源
More accurately, a depth buffer is a texture containing the value of z/w for each fragment, where:
更准确地说,深度缓冲是一个包含每个片段的z/w值的纹理,其中:
- Z is the distance from the near clipping plane to the fragment.
- Z是距离近剪切面到碎片的距离。
- W is the distance from the camera to the fragment.
- W是距离摄像机到碎片的距离。
In the following diagram illustrating the relationship between z, w, and z/w, n is equal to the zNear
parameter passed to gluPerspective
, or an equivalent function, and f is equal to the zFar
parameter passed to the same function.
下图说明了z、w和z/w之间的关系,n等于传递给gluPerspective的zNear参数,或等效函数,f等于传递给相同函数的zFar参数。
At a glance, this system look unintuitive. But as a result, z/w is always a floating-point value between 0 and 1 (0/n and f/f), and can therefore be represented as a single channel of a texture.
乍一看,这个系统看起来不太直观。但是,z/w始终是0到1 (0/n和f/f)之间的浮点值,因此可以表示为纹理的单个通道。
A second important note: the depth buffer is nonlinear, meaning an object exactly in between the near and far clipping planes is nowhere near a value of 0.5 in the depth buffer. As shown above, it would correlate to a value of 0.999 in the depth buffer. Depending on your view, this could be good or bad; you may want the depth buffer to be more detailed close-up (which it is), or offer even detail throughout (which it doesn't).
另一个重要的注意事项:深度缓冲是非线性的,这意味着在深度缓冲中,近距离和远剪切面之间的距离远小于0.5。如上所示,它与深度缓冲区中的0.999的值相关。根据你的观点,这可能是好是坏;您可能希望深度缓冲是更详细的特写(它是),或者提供更详细的(它没有)。
TL;DR:
TL;博士:
- You divide z by w so it is always in the range [0, 1].
- 你把z除以w,所以它总是在范围[0,1]。
- W is the distance from the camera to the fragment.
- W是距离摄像机到碎片的距离。