简体   繁体   English

如果我使用 early_fragment_tests 丢弃着色器中的片段,深度缓冲区会发生什么?

[英]What happens to the depth buffer if I discard a fragment in a shader using early_fragment_tests?

I'm using a fragment shader which discards some fragments using the discard keyword.我正在使用一个片段着色器,它使用丢弃关键字丢弃一些片段。 My shader also uses the early_fragment_tests ( image store load obliges ).我的着色器还使用了early_fragment_tests (图像存储加载义务)。

EDIT : I do not write the gl_FragDepth , I let the standard OpenGL handle the depth value.编辑:我不写gl_FragDepth ,我让标准 OpenGL 处理深度值。

Will my depth buffer be updated with the fragment's depth before the discard keyword is executed?在执行 discard 关键字之前,我的深度缓冲区是否会使用片段的深度进行更新?

EDIT : It does not seems like it on my NVidia Quadro 600 and K5000.编辑:在我的 NVidia Quadro 600 和 K5000 上似乎不是这样。

Any clue where I could find that information?我在哪里可以找到这些信息的任何线索? FYI, I searched http://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt .仅供参考,我搜索了http://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt I found close enough topics but not that particular one.我找到了足够接近的主题,但不是那个特定的主题。

Will my depth buffer be updated with the fragment's depth before the discard keyword is executed?在执行 discard 关键字之前,我的深度缓冲区是否会使用片段的深度进行更新?

No, this sort of behavior is explicitly forbidden in a shader that contains discard or that writes an arbitrary value to gl_FragDepth .不,这种行为在包含discard或将任意值写入gl_FragDepth的着色器中是明确禁止的。 This is because in such a shader, the depth of your fragment after it is shaded may be unrelated the position generated during initial rasterization (pre-shading).这是因为在这样的着色器中,着色后片段的深度可能与初始光栅化(预着色)期间生成的位置无关。

Without writing to gl_FragDepth or discarding, the depth of a fragment is actually known long before the actual fragment shader executes and this forms the foundation for early depth tests.在不写入gl_FragDepth或丢弃的情况下,片段的深度实际上在实际片段着色器执行之前很久就已经知道了,这构成了早期深度测试的基础。 Rasterization/shading can be skipped for some (individual tiled regions) or all of a primitive if it can be determined that it would have failed a depth test before the fragment shader is evaluated, but if the fragment shader itself is what determines a fragment's depth, then all bets are off.如果可以在评估片段着色器之前确定它在深度测试中失败,则可以跳过某些(单个平铺区域)或所有图元的光栅化/着色,但如果片段着色器本身决定了片段的深度,那么所有赌注都将关闭。

There is an exception to this rule in DX11 / OpenGL 4.x.在 DX11/OpenGL 4.x 中,此规则有一个例外。 If you write your shaders in such a way that you can guarantee the output depth will always preserve the result of a depth test (same result as the depth generated during rasterization), early fragment tests can be enabled in a shader that uses discard or writes to gl_FragDepth .如果您编写着色器的方式可以保证输出深度始终保留深度测试的结果(与光栅化期间生成的深度相同),则可以在使用discard或写入的着色器中启用早期片段测试到gl_FragDepth This feature is known as conservative depth , and unless you use this it is generally understood that discard is going to break early depth optimizations across the board.这个特性被称为保守深度,除非你使用它,否则通常会理解discard会全面破坏早期的深度优化。

Now, since you should never write to the depth buffer before you know whether the value you are writing passes or fails a depth test ( gl_FragDepth may be different) or if the fragment even survives ( discard may be used), you can see why a primitive shaded by a fragment shader that contains discard cannot write to the depth buffer before the shader is evaluated.现在,由于在知道要写入的值是否通过或未通过深度测试( gl_FragDepth可能不同)或者片段是否仍然存在(可以使用discard )之前,您永远不应该写入深度缓冲区,您可以理解为什么由包含discard的片段着色器着色的图元无法在评估着色器之前写入深度缓冲区。

I think the information you are looking for is on that page:我认为您要查找的信息在该页面上:

If early fragment tests are enabled, any depth value computed by the fragment shader has no effect.如果启用了早期片段测试,则片段着色器计算的任何深度值都无效。 Additionally, the depth buffer, stencil buffer, and occlusion query sample counts may be updated even for fragments or samples that would be discarded after fragment shader execution due to per-fragment operations such as alpha-to-coverage or alpha tests.此外,深度缓冲区、模板缓冲区和遮挡查询样本计数可能会更新,即使对于片段着色器执行后由于每个片段操作(例如 alpha 到覆盖或 alpha 测试)而将被丢弃的片段或样本。

The word "may" in "the depth buffer, [etc.] may be updated", implies it is implementation dependent (or completely random). “深度缓冲区,[等] 可能会更新”中的“可能”一词意味着它是依赖于实现的(或完全随机的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM