多个小型spritesheets或一个巨型spritesheet性能? ---(java游戏开发)

时间:2016-03-11 00:31:43

标签: java performance sprite-sheet

所以我知道使用spritesheet比加载奇异图像要好得多,但spriteesheet的最佳实现是什么?

使用许多spritesheets(例如在游戏中,每个角色一个等),或将所有图像放入一个MEGA spritesheet,可以说10,000 x 10,000大小。

两者中的哪一个会带来更好的表现?

2 个答案:

答案 0 :(得分:1)

将spritesheets用于任何可能出现在游戏的同一部分/级别的动画和静态精灵通常是最好的方法。拥有一个巨大的spritesheet 可能会产生稍微好一点的性能,但是你会很快达到收益递减规律,并且可能会使内存更加密集。

Spritesheets倾向于通过以下几种方式提高效率:

  • 它们减少了从磁盘读取图像数据(或通过网络请求)的巨大开销。

    在游戏开始之前几乎总是加载Sprite,因为试图获取所有数据苍蝇会非常糟糕。因此,拥有精灵表可能会减少你的加载时间并且有一个巨大的spritesheet可能会加快这一速度,但也意味着你必须加载游戏中的每个精灵 - 即使你只使用一些精灵。这将有更大的内存占用,但它可能不足以产生很大的不同。

  • 它们通过允许简单翻译已经在内存中的图像来加速绘画/动画,而不是复制一堆数据。

    这可能是由于提供的更重要的性能优势spritesheets。通常,这些类型的转换是硬件加速的(虽然这实际上取决于系统架构),但它比复制图像数据的性能要高得多,即使没有硬件加速也是如此。在这里,一个巨大的spritesheet可能不会产生太大的收益,因为你只需要动画中存在的帧在sprite中。

由于只有一个巨大的spritesheet而不是一些组织良好的spritesheet只有很小的性能增益的潜力,我建议最简单的实现。如果一个巨大的spritesheet很难在你的系统中使用,你可能最终会在代码中做一些笨拙的事情来管理它,这最终会很快地破坏任何性能提升。但是如果你有一个能很好地处理它的系统,并且这是一个翻转某些配置的问题,那么它可能是值得的。

答案 1 :(得分:1)

您的目标平台是什么?

大多数游戏开发框架都使用OpenGL进行渲染(例如libgdx,andengine,......) - 这会提高性能但会受到限制:不要为移动设备创建大于2048x2048的精灵表。对于所有设备,我建议保持低于4096x4096。桌面可以处理更大的纹理,但是你可能会遇到着色器精度问题。

<强>性能

更改OpenGL的纹理和设置参数需要花费时间。

使用单个精灵看起来像这样(伪代码)

foreach(sprite in sprites)
{
    opengl.setTexture(sprite.texture)
    opengl.setTextureCoordinates(sprite.sourceRect)
    opengl.setTargetCoordinates(sprite.screenPosition)
    opengl.draw()
}

所以你的每个精灵都有4次调用。 100个精灵=&gt; 400个OpenGL调用。 这很糟糕!

draw()之后可能需要等到可以设置下一个纹理。

为了优化绘制调用的数量,您的游戏引擎会对精灵的绘制进行批处理。

游戏引擎可以通过3个绘制调用绘制一张精灵表上的所有精灵:

foreach(sprite in sprites)
{
    textureCoordinates.append(sprite.sourceRect)
    screenPositions.append(sprite.screenPosition)
}

opengl.setTexture(sheet.texture)
opengl.setTextureCoordinates(textureCoordinates)
opengl.setTargetCoordinates(screenPositions)
opengl.draw()

1个Sprite表,4个OpenGL调用。 这很好!

这太理论了?这是关于optimizing game performance的有趣视频。

您会看到:使用精灵表很重要。

绘画从背景中的对象开始,向前景工作。这是确保为重叠对象正确处理透明度所必需的。

只要您可以将所有精灵放在一张纸上,这就完美无缺。 如果您有许多动画,移动设备的限制(如上所述)可能不允许您将所有内容放在一张纸上。

因此,将精灵分布在多个精灵表中需要更多思考:

将精灵,对象和ui元素分层 - 取决于它们的重叠方式:

  • 明显落后于其他精灵的所有内容放在一张纸上。例如。背景图形。
  • 之前的所有内容放在之前的其他精灵中。例如。 UI元素,HUD,得分
  • 将可能出现在之前或之后的所有内容放在一张表中。

前两个非常明显 - 后者可能不是。

如上所述:游戏引擎以背景开始,向前工作。它首先在一批中绘制您的背景。细

然后它涉及角色,敌人,子弹,游戏对象等等。 全部在一张纸上:没问题。多张纸:可能必须切换纹理 - 强制额外的绘制调用:游戏中重叠的精灵(背景到前景):

Sheet A: Sprites: a1,a2
Sheet B: Sprites b1

a1,a2,b1 => 2 batches: A,B 
a1,b1,a2 => 3 batches: A,B,A

所以:如果你不能适应所有游戏对象,1张中的敌人和角色确保为他们定义一个明确的z顺序:

  • 背景中的敌人
  • 中间人物
  • 前面的子弹
  • 前面的游戏对象

尽可能在一张纸上分组 - 但不要在不同的纸张上分发一套。确保您的游戏也符合订单。

包装精灵

透明度在精灵上似乎没有任何意义。它只是透明的,对吧?不!

透明度很高。它浪费了记忆。它还需要性能 - 因为必须读取所有透明像素。由OpenGL处理​​。

使用从精灵表中获取最大值的软件。游戏引擎支持修剪的精灵,即:没有额外透明度的精灵 - 同时保持动画稳定且无抖动。

看一下这个sprite sheet maker - 它会照顾你的床单包装,去除额外的透明度以及你需要的一切。