使用图像API渲染到纹理(无Framebuffer)

时间:2013-03-27 20:16:02

标签: opengl glsl opengl-4

作为一项实验,我决定尝试使用图像API专门渲染纹理。起初,结果显然是错误的,因为纹理写入发生在深度测试之前。所以我启用了early_fragment_tests,我虽然已经介绍了这种类型的用例,但是现在我得到了一种奇怪的闪烁,这似乎是Z-fighting,这看起来很奇怪,因为它应该执行相同的深度测试,适用于常规渲染。

无论如何,我已经包含了一个问题的图像,我很好奇是否有人解释正在发生的事情,以及为什么这不起作用。能使它起作用吗?

Flickering Dwarf

这是一个最小的复制者

    #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);
    }

1 个答案:

答案 0 :(得分:0)

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

  1. 当您前往显示此图片时(无论是实际屏幕还是glReadPixels / glGetTexImage操作),您使用了proper memory coherence operations
  2. 您使用常规渲染命令渲染此场景,没有特殊排序的三角形或任何东西。您没有使用单独的渲染命令渲染每个三角形,每个三角形之间都有内存一致性操作。
  3. 简而言之,我将假设您的问题实际上是由于您的着色器。这可能是由于许多其他事情。但是,既然你没有显示你的其余代码,我无法分辨。因此,这个答案实际上可能无法解决您的问题。但垃圾进去,垃圾出来。

    我可以从着色器和上述假设中看到的问题非常简单:incoherent memory accesses (like image load/store) 完全无序。您执行了图像写入操作。因此,除非您采取措施进行这些保证,否则您无法保证此写操作。

    是的,您使用过早期的片段测试。但这并不意味着片段着色器的非相干内存访问顺序将以任何特定顺序排列。

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

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

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