【问题标题】:OpenGl read and write to the same textureOpenGL读取和写入相同的纹理
【发布时间】:2017-04-23 04:32:43
【问题描述】:

我有一个 RGBA16F 纹理,上面有深度、normal.x、normal.y。我想在纹理上读取 r、g、b 并写入 a。我将准确地击中每个像素一次。

如果我在这种情况下读写同一个纹理,会不会出现性能问题?

【问题讨论】:

  • 听起来你在做延迟渲染。为什么要将深度存储在纹理中(尤其是在 16F 纹理中)而不是仅使用深度缓冲区?

标签: c++ opengl


【解决方案1】:

不会有性能问题。会有一个功能问题。就像这样,它不会工作。

您无法从您正在通过 FBO 写入的图像中读取并期望获得合理的结果。这会产生未定义的行为。

如果您使用 shader_image_load_store 进行读/写,您也许可以侥幸逃脱。但即便如此,它也是一个读/修改/写操作;您必须写回您阅读的 alpha。

话虽如此,如果您确定您将“准确地 打中每个像素一次”(强调补充),那么您确实有追索权。即NV_texture_barrier。不要让这个扩展上的“NV”欺骗你;它也广泛应用于 AMD 硬件(所有 HD 系列卡)。这个扩展允许你使用一个“屏障”函数(实际上是一个告诉 GPU 清除帧缓冲区和纹理缓存的函数),在调用之后,它将允许你准确地完成 一个 次读取/在片段着色器中修改/写入。在第一次通过之后,您需要在第二次通过之间设置另一个障碍。

【讨论】:

  • 分层(数组/3D)纹理的情况如何,您知道您正在从未附加到 FBO 的层中读取。从 OpenGL 的角度来看,它仍然是 RMW。有什么特别需要的吗?
  • 从硬件的角度来看,如果我们知道一个线程读写相同的纹素,为什么我们不能读/写相同的纹理?还有上面那个悬而未决的问题,我也想知道@Nicol Bolas
【解决方案2】:

如果我在这种情况下读写同一个纹理,会不会出现性能问题?

纹理可以是数据源或目标,互斥。您不能同时为两者使用纹理。

此外,纹理写入(嗯,图像写入)仅在 OpenGL-4.2 中引入,它们的性能不是很好,因为 GPU 针对聚集读取进行了优化,而不是分散写入。

【讨论】:

    【解决方案3】:

    您不能同时从单个纹理读取和写入。为了解决这个问题,您通常会创建另一个纹理,以便从一个纹理读取并写入另一个纹理。然后可以在着色器中一起或单独读取这两个纹理。

    【讨论】:

      【解决方案4】:

      如果您可以先编写然后将结果复制到纹理,则可以做到这一点。在这种情况下,您首先使用着色器进行渲染,然后在渲染完所有内容后,您将使用

      将结果复制到纹理中
      glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, windowWidth, windowHeight, 0,GL_RGB, GL_UNSIGNED_BYTE, 0);
      

      并且还使用此纹理作为着色器的输入。

      【讨论】:

        猜你喜欢
        • 2019-08-12
        • 2020-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-17
        • 2019-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多