我正在渲染每片草(每个对象)有8个顶点的草。这使我的游戏从50+ FPS下降到31FPS。
试图找到解决方案,我偶然发现a Mipmapping tutorial,这是一种使纹理不那么详细的方法。 "伟大",我想!由于草只是两个带有纹理的平面,看起来它可以解决问题!
草模型看起来像这样(显然我只是对它应用纹理并使用着色器使某些部分透明):
然而,当我启用mipmapping时,我获得了32 FPS - 仅比没有mipmapping的FPS多1个! 我还在草地上得到某种蓝色调?
没有mipmapping,草看起来像这样:
为什么我的Mipmapping没有给我任何性能提升?考虑到我的草几乎只是纹理,那么为什么降低纹理不会提高性能?
而且,为什么草地上会出现蓝色调?是否与mipmapping如何降低纹理分辨率有关?
我目前使用此代码生成:
texture = TextureLoader.getTexture("PNG",
new FileInputStream("res/" + fileName + ".png"));
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, 0);
我使用此代码实际渲染草:
public void render(){
Main.TerrainDemo.shader.start();
glPushMatrix();
glTranslatef(location.x, location.y, location.z);
TexturedModel texturedModel = TerrainDemo.texModel;
RawModel model = texturedModel.getRawModel();
GL30.glBindVertexArray(model.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texturedModel.getTexture().getID());
glScalef(10f, 10f, 10f);
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL30.glBindVertexArray(0);
glPopMatrix();
Main.TerrainDemo.shader.stop();
}
答案 0 :(得分:4)
mip-mapping修改了纹理,但是草在纹理中并没有做太多工作,因为它是一个小物体。
渲染草的大部分工作都是处理所有顶点,尤其是当草是很多小物时,然后处理这些物体。
你应该将草一起组合成一个网格,然后让它被渲染。图形卡非常适合处理具有大量顶点的对象,而对于大量对象则不是很好。
如果您使用的是jMonkeyEngine,我可以推荐一些为您提供批处理的类(最明显的是BatchNode,尽管还有一些其他选项)。可能仍然值得一看jMonkeyEngine是如何为创意做的。
答案 1 :(得分:2)
@TimB已经涵盖了你的瓶颈在渲染管道中的其他地方的可能性,例如:在顶点处理或绘制调用开销。这很有可能。有一种粗略但非常有用的方法可以缩小瓶颈的范围。您可以使窗口更小/更大,并查看是否进行帧数增加/减少。
您还可以查看CPU使用情况。如果CPU的挂机率接近100%,那么您可能不会受GPU限制,并且需要降低CPU开销。许多平台/供应商都提供CPU和GPU性能分析工具,可以为您提供更具决定性的数据。
让我们假设你实际上受到纹理采样的限制。 Mipmapping并非自动获胜。您处理的碎片数量取决于您绘制的三角形的数量和大小以及窗口大小。因此,通过mipmapping,您仍然可以在片段着色器中处理相同数量的片段,并调用相同数量的纹理采样操作。
当你使用mipmapping时,会发生一些事情:
LINEAR_MIPMAP_LINEAR
模式的8个纹素,而非mipmap情况下的LINEAR
需要4个。您定位的效果增益来自此列表中的第3项。缓存命中率很重要。但是如果你已经在没有mipmapping的情况下获得了很高的缓存命中率(例如,如果你的纹理很小,并且访问模式有利),那么你可能实际上并没有获得太大的收益。
其他两项可能会抵消这些收益。 GPU可以在双线性插值的同时进行三线性插值,因此这可能不是问题。第1项可能会受到伤害由于texel访问更加本地化,您将有望获得整体收益。但这并不能保证。