为什么 GL 深度函数推荐使用 GL_LEQUAL(为什么它对我不起作用)?

发布于 2024-12-31 21:25:18 字数 924 浏览 1 评论 0原文

GL wiki 上,他们建议使用 GL_LEQUAL 作为深度函数。另外,深度函数默认为 GL_LESS。当我使用这些函数中的任何一个时,我都会得到奇怪的结果。在这张图片中,红色方块应该在蓝色方块的前面(两个方块大小相同): with GL_LESS

但是,如果我使用 glClearDepth(0.0) 然后使用 glDepthFunc(GL_GREATER ),运行其他未更改的程序我得到: with 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):
with GL_LESS

However, if I use glClearDepth(0.0) and then glDepthFunc(GL_GREATER), running the otherwise unchanged program I get this:
with GL_GREATER

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

记忆里有你的影子 2025-01-07 21:25:18

为什么GL深度函数推荐使用GL_LEQUAL

Shaders推荐使用GL_LEQUAL。多通道阿尔法混合闪电(可能带有凹凸贴图)。为此,您必须在相同的位置/深度上多次绘制相同的对象,但使用不同的着色器/混合参数,并且应启用深度测试(可以在第一次过去后禁用深度写入)。 GL_LESS 将删除第二遍以及此后的每遍。 GL_LEQUAL 不会,并且照明将正常工作。

GL_LEQUAL 本身不会导致深度冲突,当两个几乎平行的多边形共享几乎相同位置时,就会发生深度冲突。可以通过增加深度缓冲区精度来减少影响。在过去,它也可以通过使用 w-buffer 来减少(至少在 DirectX 中),但据我所知这个功能不再流行了。

在这张图片中,红色方块应该位于蓝色方块的前面(两个方块大小相同):

没有源代码就不可能正确回答。

Why is GL_LEQUAL recommended for the GL depth function

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.

In this picture the red square should be in front of the blue one (both squares are the same size):

Impossible to answer correctly without source code.

森末i 2025-01-07 21:25:18

如果我将相机定位在 (1, 0, 0) 并朝 (0, 0, 0) 方向看,我预计 (0.5, 0, 0) 处的物体位于 (0, 0) 处物体的前面, 0).使用 GL_LESS 时,位于 (0, 0, 0) 的对象不就是其片段被写入的对象吗?

根据此链接: http://www-01.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.opengl/doc/openglrf/glDepthFunc.htm%23b5afa88027vbia

glDepthFunc 子例程指定用于比较每个的函数
传入像素 z 值与深度缓冲区中存在的 z 值。”
它还指出:“如果传入的 z 值是,则 GL_LESS 通过
小于存储的 z 值。

这里:z 值是从相机到对象的距离。这会导致在屏幕上绘制更近的对象。这里也对此进行了解释:http://www.glprogramming.com/red/chapter10.html

我引用最后一个链接:

深度缓冲区

深度缓冲区存储每个像素的深度值。如中所述
第 5 章中的“隐藏表面去除生存套件”,深度通常为
根据到眼睛的距离来测量,因此具有较大像素
深度缓冲区值会被具有较小值的像素覆盖。
然而,这只是一个有用的约定,深度缓冲区的
可以按照“深度测试”中的描述修改行为。深度
缓冲区有时称为 z 缓冲区(z 来自以下事实
x 和 y 值测量水平和垂直位移
屏幕,z 值测量垂直于屏幕的距离
屏幕)。

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?

According to this link: http://www-01.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.opengl/doc/openglrf/glDepthFunc.htm%23b5afa88027vbia,

The glDepthFunc subroutine specifies the function used to compare each
incoming pixel z value with the z value present in the depth buffer."
It is also stated that: "GL_LESS Passes if the incoming z value is
less than the stored z value.

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:

Depth Buffer

The depth buffer stores a depth value for each pixel. As described in
"A Hidden-Surface Removal Survival Kit" in Chapter 5, depth is usually
measured in terms of distance to the eye, so pixels with larger
depth-buffer values are overwritten by pixels with smaller values.
This is just a useful convention, however, and the depth buffer's
behavior can be modified as described in "Depth Test." The depth
buffer is sometimes called the z buffer (the z comes from the fact
that x and y values measure horizontal and vertical displacement on
the screen, and the z value measures distance perpendicular to the
screen).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文