【问题标题】:OpenGL - Occlusion query depth buffer?OpenGL - 遮挡查询深度缓冲区?
【发布时间】:2014-12-09 17:41:46
【问题描述】:

我刚刚开始研究 OpenGL 中的遮挡查询这一主题,但我对它们的实际工作方式有点困惑。

在我发现的大多数示例中,深度和颜色蒙版在使用遮挡查询进行绘制之前被停用(因为我们实际上不需要“绘制”任何东西),本质上有点像这样:

glDepthMask(GL_FALSE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

glBeginQuery(GL_ANY_SAMPLES_PASSED,query1);
    // Draw Object 1
glEndQuery(GL_ANY_SAMPLES_PASSED);

glBeginQuery(GL_ANY_SAMPLES_PASSED,query2);
    // Draw Object 2
glEndQuery(GL_ANY_SAMPLES_PASSED);
// etc

glDepthMask(GL_TRUE);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

(假设对象是从前到后绘制的,所以对象1在对象2的前面。上面的代码只是为了这个问题的伪代码。查询的结果将在以后检索.)

现在,要知道对象 2 是否实际上被对象 1 遮挡,它需要以某种方式保留来自查询 1 的片段信息(我假设在某种深度缓冲区中)。但是我们禁用了对深度和颜色缓冲区的绘制,这意味着什么都没有绘制,这意味着它不应该在任何地方存储任何东西?

是否有特殊的“查询”缓冲区?如果是这样,有没有办法访问它?它是否以任何方式连接到当前绑定的纹理或帧缓冲区?我需要清除它吗?我是否误解了遮挡查询的实际工作原理?

【问题讨论】:

  • 这通常是在一切都已经渲染之后的另一个渲染过程。
  • 对,这是有道理的。不过,信息实际存储在哪里,是否可以访问它? (主要用于调试目的)
  • 在 GPU/驱动程序上,您可以使用 glGetQueryObject 获得结果
  • 所以这个问题的答案是你在开始遮挡查询之前没有清除深度缓冲区,对吗?换句话说,您针对上一帧的最终深度缓冲区测试您的查询?

标签: c++ opengl depth-buffer occlusion occlusion-culling


【解决方案1】:

现在,要知道对象 2 是否真的被对象 1 遮挡,它需要以某种方式保留来自查询 1 的片段信息

为什么会这样?遮挡查询存储通过深度测试的样本数的计数器,它是一个整数。

由于您已禁用对颜色和深度缓冲区的写入,因此绘制对象唯一要做的就是增加遮挡查询计数器*。对象 2 不可能遮挡对象 1,因为绘制对象 1 不会更改深度缓冲区。

*除非您有模板缓冲区或正在执行诸如在着色器中加载/存储图像之类的操作

【讨论】:

  • 我不会真正将遮挡查询描述为布尔值。他们实际上计算了通过深度测试的样本数量。 GL_ANY_SAMPLES_PASSED 只是对此的一种简化,如果通过的样本数 > 0,则返回 true。实际上,它不必在单个样本通过后继续计数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-11
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多