1

As an experiment I decided to try rendering to a texture using the image API exclusively. At first the results were obviously wrong as the texture write occurred before the depth test. So I enabled the early_fragment_tests, which I though was introduced for pretty much this type of use case, but now I get a weird sort of flickering which seems like Z-fighting, which seems strange since it should be performing the same depth test that works for regular rendering.

Anyway, I've included an image of the problem, and I'm curious if anyone has an explanation as what is going on, and why this doesn't work. Can it be made to work?

Flickering Dwarf

Here's a minimal reproducer

    #version 420
    in vec3 normal;
    layout(binding = 0) writeonly uniform image2D outputTex;
    void main()
    {
        vec4 fragColor = vec4(normal, 1);
        imageStore(outputTex, ivec2(gl_FragCoord.xy), fragColor);
    }
4

1 回答 1

0

我将对您未显示的代码做出一些假设。因为你没有表现出来。我将假设:

  1. 当您显示此图像时(无论是在实际屏幕上还是在/操作中) ,您使用了适当的内存一致性操作。glReadPixelsglGetTexImage
  2. 您使用常规渲染命令渲染了这个场景,没有对三角形或任何东西进行特殊排序。您没有使用单独的渲染命令渲染每个三角形,每个三角形之间都有内存一致性操作。

简而言之,我将假设您的问题实际上是由于您的着色器造成的。这很可能是由于许多其他事情。但是由于您不打算显示其余代码,因此我无法确定。因此,这个答案实际上可能无法回答您的问题。但是垃圾进,垃圾出。

我可以从您的着色器和上述假设中看到的问题非常简单:不连贯的内存访问(如图像加载/存储)完全无序的。您执行了图像写入操作。因此,除非您采取措施做出这些保证,否则您无法保证此写入操作。

是的,您使用了早期的片段测试。但这并不意味着来自片段着色器的不连贯内存访问的顺序将是任何特定的顺序。

考虑一下如果渲染一个三角形会发生什么,然后在它前面渲染一个完全覆盖它的三角形。早期的片段测试不会改变任何东西,因为顶部片段发生在底部片段之后。并且图像加载/存储不保证写入同一像素的顺序。因此,很有可能在写入顶部三角形后完成对底部三角形的写入。

据我所知,像这样从不同的片段着色器对同一像素进行排序是不可能的。即使您memoryBarrier在写入后发出了 a,我对规范的阅读也并不表明这将保证此处的写入顺序。

正确的答案是根本不这样做。写入片段着色器输出;这就是他们的目的。

于 2013-03-29T05:09:20.620 回答