为什么 GL 深度函数推荐使用 GL_LEQUAL(为什么它对我不起作用)?
在 GL wiki 上,他们建议使用 GL_LEQUAL 作为深度函数。另外,深度函数默认为 GL_LESS。当我使用这些函数中的任何一个时,我都会得到奇怪的结果。在这张图片中,红色方块应该在蓝色方块的前面(两个方块大小相同):
但是,如果我使用 glClearDepth(0.0)
然后使用 glDepthFunc(GL_GREATER )
,运行其他未更改的程序我得到:
再仔细考虑一下,GL_LESS 给出的结果是有道理的:如果传入的深度值小于存储的,则写入该片段。
如果我将相机定位在 (1, 0, 0)
并朝 (0, 0, 0)
方向看,我期望在 (0.5, 0, 0)
位于 (0, 0, 0)
处的对象前面。如果使用 GL_LESS,(0, 0, 0)
处的对象不就是其片段被写入的对象吗?
编辑: 尼科尔,感谢您提到投影矩阵。看来是设置错误了。我在 arcsynthesis.org 上学习了一段时间的教程,并将代码调整到我自己的项目中,但我偏离了你的投影矩阵,并使用 glFrustum 手册页上描述的数学来实现我自己的该函数版本,然后使用 NeHe 的 gluPerspective替换以替换 gluPerspective。我不知道为什么替换不起作用,因为我的矩阵数学是正确的(我已经针对各种在线计算器对其进行了检查)。使用你的矩阵我得到了 GL_LESS 的正确结果。
On the GL wiki they recommend using GL_LEQUAL for the depth function. Also, the depth function defaults to GL_LESS. When I use either of these functions, I get strange results. In this picture the red square should be in front of the blue one (both squares are the same size):
However, if I use glClearDepth(0.0)
and then glDepthFunc(GL_GREATER)
, running the otherwise unchanged program I get this:
Thinking about it a bit more, it makes sense that GL_LESS would give the results it does: if the incoming depth value is less than the stored one, the fragment is written.
If I positioned my camera at (1, 0, 0)
and looked towards (0, 0, 0)
I expect an object at (0.5, 0, 0)
to be in front of an object at (0, 0, 0)
. With GL_LESS wouldn't the object at (0, 0, 0)
be the one whose fragments are written?
EDIT:
Nicol, thanks for mentioning the projection matrix. It seems like it was set incorrectly. I was following your tutorial on arcsynthesis.org for awhile and adapting the code to my own project, but I deviated from your projection matrix and used math described on the glFrustum man page to implement my own version of that function, and then used NeHe's gluPerspective replacement to replace gluPerspective. I don't know why the replacements didn't work because my matrix math is correct (i have checked it against various online calculators). Using your matrix I get the correct result with GL_LESS.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Shaders推荐使用GL_LEQUAL。多通道阿尔法混合闪电(可能带有凹凸贴图)。为此,您必须在相同的位置/深度上多次绘制相同的对象,但使用不同的着色器/混合参数,并且应启用深度测试(可以在第一次过去后禁用深度写入)。 GL_LESS 将删除第二遍以及此后的每遍。 GL_LEQUAL 不会,并且照明将正常工作。
GL_LEQUAL 本身不会导致深度冲突,当两个几乎平行的多边形共享几乎相同位置时,就会发生深度冲突。可以通过增加深度缓冲区精度来减少影响。在过去,它也可以通过使用 w-buffer 来减少(至少在 DirectX 中),但据我所知这个功能不再流行了。
没有源代码就不可能正确回答。
Shaders. Multipass alphablended lightning (possibly with bumpmapping). To do that, you'll have to paint same object on same position/depth several time, but with different shader/blending parameters AND depth test should be enabled (depth writing can be disabled after 1st past). GL_LESS will cut out 2nd pass and every pass after that. GL_LEQUAL won't, and lighting will work properly.
GL_LEQUAL will not cause z-fighting by itself, z-fighting happens when you have two almost parallel polygons sharing almost identical location. Effect can be reduced by increasing depth buffer precision. In the past it could have been also reduced by using w-buffer (at least in DirectX), but AFAIK this feature isn't popular anymore.
Impossible to answer correctly without source code.
根据此链接: http://www-01.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.opengl/doc/openglrf/glDepthFunc.htm%23b5afa88027vbia,
这里:z 值是从相机到对象的距离。这会导致在屏幕上绘制更近的对象。这里也对此进行了解释:http://www.glprogramming.com/red/chapter10.html
我引用最后一个链接:
According to this link: http://www-01.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.opengl/doc/openglrf/glDepthFunc.htm%23b5afa88027vbia,
Here: the z value is distance from camera to the object. This results in the closer object to be drawn on the screen. This is also explained here: http://www.glprogramming.com/red/chapter10.html
I quote from the last link: