使用Opengl FBO时性能损失严重

Sca*_*urs 12 java opengl lwjgl

我已经使用lwjgl(opengl)成功实现了一个简单的2-d游戏,当对象越来越远离玩家时,对象逐渐消失.这种衰落最初是通过计算距离玩家的每个对象的原点的距离并使用它来缩放对象的alpha /不透明度来实现的.

但是,当使用较大的对象时,这种方法看起来有点过于粗糙.我的解决方案是为对象中的每个像素实现alpha/opacity缩放.这不仅看起来更好,而且还会将计算时间从CPU转移到GPU.

我想我可以使用FBO和临时纹理来实现它.
通过绘制到FBO并使用特殊混合模式用预先计算的距离图(纹理)对其进行遮罩,我打算实现这种效果.算法是这样的:

0)初始化opengl和设置FBO
1)将背景渲染到标准缓冲区
2)切换到自定义FBO并清除它
3)渲染对象(到FBO)
4)使用距离纹理掩码FBO
5)切换到标准缓冲区
6)渲染FBO临时纹理(到标准缓冲区)
7)渲染hud元素

一些额外的信息:

  • 临时纹理与窗口大小相同(因此标准缓冲区)
  • 步骤4使用特殊混合模式来实现所需效果:
    GL11.glBlendFunc(GL11.GL_ZERO,GL11.GL_SRC_ALPHA);
  • 我的临时纹理是使用min/mag过滤器创建的:GL11.GL_NEAREST
  • 数据使用:org.lwjgl.BufferUtils.createByteBuffer(4*width*height)分配;
  • 使用以下公式初始化纹理:GL11.glTexImage2D(GL11.GL_TEXTURE_2D,0,GL11.GL_RGBA,width,height,0,GL11.GL_RGBA,GL11.GL_UNSIGNED_BYTE,dataBuffer);
  • 我的代码中没有GL错误.

这确实达到了预期的效果.然而,当我进行一些性能测试时,我发现我的FBO方法削弱了性能.我通过请求1000次连续渲染并测量时间来测试.结果如下:

在512x512分辨率:

  • 正常:~1.7s
  • FBO:~2.5s
  • (FBO -step 6:~1.7s)
  • (FBO -step 4:~1.7s)

在1680x1050分辨率:

  • 正常:~1.7s
  • FBO:~7s
  • (FBO -step 6:~3.5s)
  • (FBO -step 4:~6.0s)

正如你所看到的,这非常严重.更糟糕的是,我打算做这种类型的第二次传球.我测试的机器应该是我的目标观众的高端,所以我可以期望人们使用这种方法远远低于60 fps,这对于这么简单的游戏来说是难以接受的.

我能做些什么来挽救我的表现?

Sca*_*urs 5

正如 Damon 和 sidewinderguy 所建议的,我使用片段着色器(和顶点着色器)成功地实现了一个类似的解决方案。我的性能比我最初的 cpu-run 基于对象的计算要好一点,这比我的 FBO 方法快得多。同时,它提供了更接近 FBO 方法的视觉效果(重叠对象的行为略有不同)。

对于任何感兴趣的人来说,片段着色器基本上都会转换 gl_FragCoord.xy 并进行纹理查找。我不确定这会提供最佳性能,但仅激活其他 1 个纹理,我不希望通过省略查找和直接计算纹理值来提高性能。此外,我现在不再有性能瓶颈,所以应该等到发现需要进一步优化。

另外,我非常感谢我收到的所有帮助、建议和评论:-)