有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在使用Opengl FBO时会出现可怕的性能损失

我已经成功地使用lwjgl(opengl)实现了一个简单的二维游戏,当对象离玩家越来越远时,它们会逐渐消失。这种褪色最初是通过计算从播放器到每个对象原点的距离来实现的,并使用该距离来缩放对象的alpha/不透明度

然而,当使用较大的对象时,这种方法显得有点过于粗糙。我的解决方案是为对象中的每个像素实现alpha/不透明度缩放。这不仅看起来更好,而且还可以将计算时间从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。最近的
  • 使用:org分配数据。lwjgl。BufferUtils。createByteBuffer(4*宽*高)
  • 使用以下命令初始化纹理: GL11。GLTEXAGE2D(GL11.GL_纹理_2D,0,GL11.GL_RGBA,宽度,高度,0,GL11.GL_RGBA,GL11.GL_无符号_字节,数据缓冲)
  • 我的代码中没有总账错误

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

在512x512分辨率中:

  • 正常值:~1.7秒
  • 固定基地运营商:~2.5秒
  • (固定基地运营商-第6步:~1.7s)
  • (FBO-第4步:~1.7s)

在1680x1050分辨率中:

  • 正常值:~1.7秒
  • FBO:~7秒
  • (固定基地运营商-第6步:~3.5s)
  • (FBO-第4步:~6.0s)

正如你所看到的,这个比例非常糟糕。更糟糕的是,我打算再做一次这种类型的测试。就我的目标受众而言,我测试的机器应该是高端的,所以我可以预期人们使用这种方法的速度远低于60 fps,这对于这么简单的游戏来说是很难接受的

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


共 (1) 个答案

  1. # 1 楼答案

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

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

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