【问题标题】:Rendering to a texture using the image API (no Framebuffer)使用图像 API 渲染到纹理(无帧缓冲区)
【发布时间】:2013-03-27 20:16:01
【问题描述】:

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

无论如何,我已经包含了问题的图像,我很好奇是否有人解释发生了什么,以及为什么这不起作用。可以让它工作吗?

这是一个最小的复制器

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

【问题讨论】:

  • 你在说什么“图像 API”?此外,添加一些代码会有所帮助。
  • ARB_shader_image_load_store
  • 那么...您的代码是什么样的?错误使用 Image Load/Store 操作的方法有很多,不看代码就无法知道你做了哪些。
  • 基本上我会在哪里写出片段颜色,我只是使用imageStore(outputTex, ivec2(gl_FragCoord.xy), fragColor); 来写入纹理。唯一的其他变化是文件顶部的layout(early_fragment_tests) in;
  • “你的代码是什么样的”,我的意思是“发布你的代码”。不是您的代码片段。将您的代码放在人们可以看到的问题中。

标签: opengl glsl opengl-4


【解决方案1】:

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

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

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

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

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

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

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

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

【讨论】:

  • 就像我说的,这是一个实验。我了解到除了执行正确渲染所需的早期片段测试之外,还需要额外的逻辑。该功能是否可以用原子再现或我尚未发现的东西。目前我没有时间进行更多实验。但是,是的,当我不进行实验时,我使用的是帧缓冲区和片段输出。
猜你喜欢
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多