OpenGL早期深度测试不起作用

时间:2016-02-08 23:16:33

标签: opengl graphics glsl gpu opengl-4

这是我的片段着色器:

#version 420 core
#extension GL_ARB_explicit_uniform_location : enable
#extension GL_ARB_shader_storage_buffer_object : require
layout(early_fragment_tests) in;
layout(binding = 4, offset = 0) uniform atomic_uint num_fragments;
// ...
void main(void)
{
    atomicCounterIncrement(num_fragments);
    frag_color = vec4(1.0, 0.0, 0.0, 0.0);

    atomicAdd(...);
}

我的三角形完全覆盖了屏幕。 num_fragments的预期行为等于像素数(640 * 480 = 307200),它是单层三角形的。但是,当我在现有三角形后面添加一个三角形时,num_fragments会变为更高的值,就像正在为被遮挡的三角形执行片段着色器一样。

这是为什么?我虽然early_fragment_tests指令会阻止这种行为。这不仅仅是一种优化,因为着色器中有原子存储,只能为未遮挡的像素运行。

1 个答案:

答案 0 :(得分:4)

  

我的三角形完全覆盖了屏幕。 num_fragments的预期行为等于像素数(640 * 480 = 307200),它是单层三角形的。

不,这不是预期的行为。

早期深度测试不是 magic 。它们不以任何方式保证随机分类的三角形将没有过度绘制。它们只是在执行片段着色器之前强制执行片段测试。所有这一切都确保测试通过或失败。因此,片段着色器只会对已经过的片段执行。

透支与早期深度测试无关。 Overdraw是关于你正在渲染的三角形顺序。如果你渲染它们从前到后排序,那么你得到零透支。如果你渲染它们从前到后排序,那么你得到最大可能的透支。

无论片段着色器是否在片段着色器之前发生,都会发生这种情况。

  

这不仅仅是一种优化,因为着色器中的原子存储只能为未遮挡的像素运行。

这样做的唯一方法是进行仅限深度的预传。您必须将场景渲染到深度缓冲区(没有片段着色器)。然后,当您渲染真实场景时,通过深度测试的唯一片段将是可见的片段。