Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Opengl FBO时会造成可怕的性能损失_Java_Opengl_Lwjgl - Fatal编程技术网

Java 使用Opengl FBO时会造成可怕的性能损失

Java 使用Opengl FBO时会造成可怕的性能损失,java,opengl,lwjgl,Java,Opengl,Lwjgl,我已经成功地使用lwjgl(opengl)实现了一个简单的二维游戏,当对象离玩家越来越远时,它们会逐渐消失。这种褪色最初是通过计算从播放器到每个对象原点的距离来实现的,并使用该距离来缩放对象的alpha/不透明度 然而,当使用较大的对象时,这种方法显得有点过于粗糙。我的解决方案是为对象中的每个像素实现alpha/不透明度缩放。这不仅看起来更好,而且还可以将计算时间从CPU转移到GPU 我想我可以使用FBO和临时纹理来实现它。 通过绘制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)
  • 我的临时纹理是使用最小/最大过滤器创建的:GL11.GL\u
  • 数据分配使用:org.lwjgl.BufferUtils.createByteBuffer(4*宽*高)
  • 使用以下命令初始化纹理: GL11.glTexImage2D(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,这对于这么简单的游戏来说是很难接受的


我能做些什么来挽救我的性能?

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

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


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

效果到底应该如何?在边界或类似位置淡出?距离图目前使用
double dist=Math.hypop(nRadius-i,nRadius-j)实现;双a=数学最大值(0,1-距离/nRadius)。其中a*a用作alpha。其中i,j迭代对象中的所有像素?我无法回答为什么FBO操作很慢,但我会使用多重纹理实现它,将距离贴图作为第二个纹理,如果达到某个距离,可能还会额外缩放alpha。这是一个碎片着色器上下跳跃的示例,它会大叫“请,请,请,使用Meeeee!”-虽然这是你必须思考和计划的一个严重改变,但是你应该考虑它。从某个点到gl_Fragcoord.xy的平方距离(以均匀方式传递)归结为一个向量减法和一个点积。如果你想要线性衰减,这是另一个recp和乘法,但它仍然是尽可能容易,将是超高速(大约十几个周期,没有额外的纹理,没有额外的混合,没有模糊的混合模式)。我同意达蒙。您的FBO解决方案很聪明,但最终与基于着色器的方法相比,它的速度总是很慢。最好只使用FBO渲染纹理,而不必更改每一帧。感谢您不断更新我们!我只使用过可编程管道,有趣的是,除了更灵活之外,它还可以比固定功能快很多。