这是我的片段着色器:
#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指令会阻止这种行为。这不仅仅是一种优化,因为着色器中有原子存储,只能为未遮挡的像素运行。
答案 0 :(得分:4)
我的三角形完全覆盖了屏幕。 num_fragments的预期行为等于像素数(640 * 480 = 307200),它是单层三角形的。
不,这不是预期的行为。
早期深度测试不是 magic 。它们不以任何方式保证随机分类的三角形将没有过度绘制。它们只是在执行片段着色器之前强制执行片段测试。所有这一切都确保测试通过或失败。因此,片段着色器只会对已经过的片段执行。
透支与早期深度测试无关。 Overdraw是关于你正在渲染的三角形的顺序。如果你渲染它们从前到后排序,那么你得到零透支。如果你渲染它们从前到后排序,那么你得到最大可能的透支。
无论片段着色器是否在片段着色器之前发生,都会发生这种情况。
这不仅仅是一种优化,因为着色器中的原子存储只能为未遮挡的像素运行。
这样做的唯一方法是进行仅限深度的预传。您必须将场景渲染到深度缓冲区(没有片段着色器)。然后,当您渲染真实场景时,通过深度测试的唯一片段将是可见的片段。