所以我知道使用spritesheet比加载奇异图像要好得多,但spriteesheet的最佳实现是什么?
使用许多spritesheets(例如在游戏中,每个角色一个等),或将所有图像放入一个MEGA spritesheet,可以说10,000 x 10,000大小。
两者中的哪一个会带来更好的表现?
答案 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元素分层 - 取决于它们的重叠方式:
前两个非常明显 - 后者可能不是。
如上所述:游戏引擎以背景开始,向前工作。它首先在一批中绘制您的背景。细
然后它涉及角色,敌人,子弹,游戏对象等等。 全部在一张纸上:没问题。多张纸:可能必须切换纹理 - 强制额外的绘制调用:游戏中重叠的精灵(背景到前景):
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 - 它会照顾你的床单包装,去除额外的透明度以及你需要的一切。