Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在OpenGL的透视投影中,为什么要将Z除以W?_C++_Opengl_Math_Matrix - Fatal编程技术网

C++ 在OpenGL的透视投影中,为什么要将Z除以W?

C++ 在OpenGL的透视投影中,为什么要将Z除以W?,c++,opengl,math,matrix,C++,Opengl,Math,Matrix,我想这更像是一个数学问题,而不是OpenGL问题,但我离题了。无论如何,如果透视图分割的全部目的是获得可用的x和y坐标,那么为什么还要麻烦将z除以w呢?还有,首先我该如何得到w呢?事实上,这个解释更多地与深度缓冲区的限制有关,而不是与数学有关 最简单的说,“深度缓冲区是一种纹理,其中每个屏幕上的像素根据其与相机的距离分配一个灰度值。这使得视觉效果可以很容易地随距离而改变。” 更准确地说,深度缓冲区是一种纹理,每个纹理包含z/w值,其中: Z是从近剪裁平面到碎片的距离 W是从摄影机到碎片的距离

我想这更像是一个数学问题,而不是OpenGL问题,但我离题了。无论如何,如果透视图分割的全部目的是获得可用的x和y坐标,那么为什么还要麻烦将z除以w呢?还有,首先我该如何得到w呢?

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

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

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

  • Z是从近剪裁平面到碎片的距离
  • W是从摄影机到碎片的距离
在下图中,说明了z、w和z/w之间的关系,n等于传递给的
zNear
参数或等效函数,f等于传递给相同函数的
zFar
参数

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

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

TL;博士:

  • 将z除以w,使其始终在[0,1]范围内
  • W是从摄影机到碎片的距离

这与同质坐标有关。它们映射R^3->R^4显然不是一对一的。w系数可以“cannonized”为1。但如果使用4x4矩阵运算符,则结果“w”可能会发生变化。如果我没记错的话,齐次坐标的一个优点是将平移作为线性运算符。我真的不太同意这个答案,这个问题属于纯数学问题,这里解释的是opengl和z-buffer算法的实现细节(深度缓冲)。NDC中的z在范围[-1,1]内,而不是[0,1]这是DirectX约定。为什么在最远的片段,w和z都是f?有“n”w和z起点之间的距离。谢谢。
z是从近剪裁平面到片段的距离。w是从相机到片段的距离。
我想我可以放心地假设这些句子也适用于DirectX。