【发布时间】:2014-05-20 12:22:36
【问题描述】:
我正在使用 libGDX,并创建了我自己的 Sprite 类和渲染器(它在后台使用了 libGDX 的 SpriteBatch)。渲染器非常“智能”,它按图层/着色器/纹理/混合对精灵进行排序,并且精灵可以包含子对象。
现在我正在尝试添加对 FrameBuffers 的支持,但遇到了一个小问题。
我正在尝试通过着色器向我的游戏中的“根”精灵添加多个后处理效果。
- 将根 Sprite 渲染为 FBO,(背景和所有实体)
- 为同一个 FBO 渲染“漩涡”效果
- 为同一个 FBO 渲染绽放效果
- 为同一个 FBO 渲染水平模糊
- 为同一个 FBO 渲染垂直模糊
- 通过 Sprite 将 FBO 的最终结果渲染到屏幕中
这一切都非常简单地实现,每个效果都有自己的 Sprite 对象。它们通过 setLayer(int) 分层,纹理/FBO/着色器通过 setTexture(Texture) / setTarget(Texture) / setShader(Shader) 设置。
我尝试并希望使用相同的纹理作为结果和目标。 例如:
Texture fbo = Video.newTarget();
...
bloom.setTexture(fbo);
bloom.setTarget(fbo);
blurH.setTexture(fbo);
blurH.setTarget(fbo);
....
如果我以这种方式使用相同的 FBO,我会在最终图像中看到一些难以描述的奇怪伪影。我要么在纹理的某处得到一些奇怪的线条,要么只是一些奇怪的扭曲。
如果我为每个效果创建一个单独的 FBO,一切都会正常工作。
例如:
Texture fbo1, fbo2, fbo3, fbo4;
...
bloom.setTexture(fbo1);
bloom.setTarget(fbo2);
blurH.setTexture(fbo2);
blurH.setTarget(fbo3);
...
如果可能的话,我真的很想避免这种情况,因为它会导致代码混乱,并损害性能。
我真的不太精通 OpenGL/GLSL(我什至不太了解渲染管道... :),但是,根据我的解释,有没有人知道可能导致这些伪影的原因?
我也想过有两个 FBO 和它们之间的“乒乓球”,但由于某种原因,我看到的都是黑色的.. 现在.. :) 我将不得不对此进行更多试验。
【问题讨论】:
-
更重要的是,它会导致未定义的行为。 GL 为这种情况起了一个名字,它是“反馈循环”。在较新的 NV 硬件上,您可以使用纹理屏障和几何着色器来明智地读取和写入相同的缓冲区,或者在 GL4+ 中使用图像加载/存储和内存屏障。但除此之外,这是未定义的,您描述的那些工件是最终结果。