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

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

评论

粗略的解决方案是只通过模板将一种对比色涂到另一种上,保存该缓冲区,并计算已更改的像素数。
嗯,规范说咬合查询会计算通过深度测试的碎片数量,但是我不知道现在该如何与模板测试相互作用。
@ChristianRau似乎只对通过深度测试的片段进行计数,而忽略模板,丢弃和alpha测试。

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

@NathanReed听起来您将要写一个答案。

#1 楼

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

您可以使用以下事实:根据规范,在深度测试之前执行模板测试,只有通过深度测试的片段才被使用。

一个简单的示例(未经测试)将是:

的样本将强制调用管道的刷新,并等待查询完成。 >
    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);


#2 楼

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

步骤将是:


使用足够精确的格式将模板复制到纹理。
加载着色器,该着色器输出与给定颜色的纹理像素数量成正比的颜色。
在帧缓冲器之间进行乒乓将尺寸减小一半,直到达到一个像素。
颜色是视口被该区域覆盖的百分比:将其乘以视口的面积即可。