是否可以通过模版测试找出有多少碎片?


11

我有一个OpenGL应用程序,该应用程序广泛使用模板测试来渲染不规则形状(有点像简单的2-D CSG)。如果我能找到通过模板测试并实际渲染的片段数量,这将有助于简化某些计算。具体来说,它可以让我免费确定渲染形状的面积,而不必稍后使用蒙特卡洛模拟对其进行近似。

我知道从几何着色器发出的图元也有类似的概念,称为变换反馈。我想知道片段和模板测试是否存在类似的概念。


粗略的解决方案是仅通过模板将一种对比色涂在另一种上,保存该缓冲区,并计算被更改的像素数。
TheBuzzSaw

嗯,规范说咬合查询会计算通过深度测试的碎片数量,但是我不知道现在该如何与模板测试相互作用。
克里斯说,请

@ChristianRau似乎只有通过深度测试的片段才会被计数,但模板,丢弃和alpha测试将被忽略。
莫里斯·拉沃

2
@ChristianRau和Maurice,原始的ARB_occlusion_query规范明确表示,它对通过深度模版测试的样本进行计数。另请参阅此StackOverflow问题
内森·里德

@NathanReed听起来您将要写一个答案。
克里斯说,请在2015年

Answers:


10

一种可能的方法是使用硬件遮挡查询。

您可以使用以下事实:根据规范,模板测试在深度测试之前执行,并且遮挡查询仅统计通过深度测试的片段。

一个简单的示例(未经测试)如下所示:

    GLuint samples_query = 0;
    GLuint samples_passed = 0;
    glGenQueries(1, &samples_query);
    // Initialize your buffers and textures ...
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Set up the values on the stencil buffer ...

    // Now we count the fragments that pass the stencil test
    glDepthFunc(GL_ALWAYS); // Set up the depth test to always pass
    glBeginQuery(GL_SAMPLES_PASSED, samples_query);
    // Render your meshes here
    glEndQuery(GL_SAMPLES_PASSED);
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT, &samples_passed);
    // samples_passed holds the number of fragments that passed the stencil test (if any)

    // Release your resources ...
    glDeleteQueries(1, &samples_query);

请注意,获取样本数的调用将强制调用管道刷新,并等待查询完成。如果您需要更异步的方法,可以使用以下方法查询是否进行了遮挡查询:

    GLuint query_done = 0;
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT_AVAILABLE, &query_done);
    if (query_done != 0)
        // Your query result is ready
    else
        // Maybe check the next frame?

2

如果您感兴趣的是该区域,则可以缩小模板缓冲区的大小,直到达到一个像素并从其颜色推断出该区域。

步骤将是:

  • 使用足够精确的格式将模板复制到纹理。
  • 加载一个着色器,该着色器输出与给定颜色的纹理像素数量成比例的颜色。
  • 在帧缓冲区之间进行乒乓操作,以将大小减小一半,直到达到一个像素为止。
  • 像素的颜色是该区域所覆盖的视口的百分比:只需将其乘以视口的面积即可。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.