opengl 着色器存储缓冲区对象是在着色器循环之间具有持久内存的合适工具吗?

mwyxok5s  于 2023-02-08  发布在  其他
关注(0)|答案(1)|浏览(135)

背景

我有一个处理2D图像的片段着色器。有时一个像素可能在几帧内被认为是"无效的"(RGB值0/0/0),而在其余帧内是有效的。这会导致这些像素 Flink 时产生时间噪声。
我想实现一种时间滤波器,在每个渲染循环中,每个像素都"显示"(RGB值不是0/0/0)当且仅当该像素在最后X个循环中"有效",其中X可能是5、10等。我想如果我可以有一个与图像大小相同的数组,当一个像素无效时,我可以将该像素对应的元素设置为0,否则将其递增,如果该值〉= X,则可以显示该像素。
时间滤波器引起的图像延迟不是问题,但我希望最小化性能成本。

这个问题

这就是背景。我正在寻找一种机制,允许我在同一个片段着色器的不同渲染循环之间读写(因此统一)。从我的OpenGL应用程序读回数据是一个优点,但不是必要的。
我遇到了Shader Storage Buffer Object,它是否适合我的需要?
是否还有其他我应该注意的问题?性能?一致性/内存障碍?

gab6jxml

gab6jxml1#

是的,SSBO是在着色器循环之间具有持久内存的合适工具。

由于我找不到它不工作的原因,我实现了它,并且我确实能够将SSBO作为一个数组,每个元素Map到一个像素,以便对每个像素进行时间滤波。
我不得不做一些事情来消除图像中的伪影:

  • 将数据与glBufferData绑定时使用GL_DYNAMIC_COPY
  • 在着色器中将SSBO设置为volatile
  • 在我的着色器中使用一个屏障(memoryBarrierBuffer();)来分隔SSBO的写入和阅读。

正如@user253751在评论中提到的,我必须将纹理坐标转换为索引数组。
我检查了使用SSBO的性能成本,在我的案例中可以忽略不计:对于848 x480帧〈0.1毫秒。

相关问题