Java 使用Opengl FBO时会造成可怕的性能损失
我已经成功地使用lwjgl(opengl)实现了一个简单的二维游戏,当对象离玩家越来越远时,它们会逐渐消失。这种褪色最初是通过计算从播放器到每个对象原点的距离来实现的,并使用该距离来缩放对象的alpha/不透明度 然而,当使用较大的对象时,这种方法显得有点过于粗糙。我的解决方案是为对象中的每个像素实现alpha/不透明度缩放。这不仅看起来更好,而且还可以将计算时间从CPU转移到GPU 我想我可以使用FBO和临时纹理来实现它。Java 使用Opengl FBO时会造成可怕的性能损失,java,opengl,lwjgl,Java,Opengl,Lwjgl,我已经成功地使用lwjgl(opengl)实现了一个简单的二维游戏,当对象离玩家越来越远时,它们会逐渐消失。这种褪色最初是通过计算从播放器到每个对象原点的距离来实现的,并使用该距离来缩放对象的alpha/不透明度 然而,当使用较大的对象时,这种方法显得有点过于粗糙。我的解决方案是为对象中的每个像素实现alpha/不透明度缩放。这不仅看起来更好,而且还可以将计算时间从CPU转移到GPU 我想我可以使用FBO和临时纹理来实现它。 通过绘制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_无符号_字节,数据缓冲)李>
- 我的代码中没有总账错误
- 正常值:~1.7秒
- 固定基地运营商:~2.5秒
- (固定基地运营商-第6步:~1.7s)
- (FBO-第4步:~1.7s)
- 正常值:~1.7秒
- FBO:~7秒
- (固定基地运营商-第6步:~3.5s)
- (FBO-第4步:~6.0s)
我能做些什么来挽救我的性能?正如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渲染纹理,而不必更改每一帧。感谢您不断更新我们!我只使用过可编程管道,有趣的是,除了更灵活之外,它还可以比固定功能快很多。