Answers:
“记忆”和“效率”通常是误用的术语,因此,我将为您解答可能影响游戏性能的四个不同要素。
为了简化和简洁起见,我将简化太多的事情,但是下面的文本中有很多错误之处,因此请捏一些盐。但是,主要概念应该是可以理解的。
存储
这是图像在软件发行版中消耗的大小。资源消耗的空间越多,下载(例如从您的网站下载)的时间就越长。如果要分发CD或DVD等物理介质,则可能必须在这方面进行一些认真的优化。
通常,JPEG对没有锐利边框的照片和图像进行最佳压缩。但是,由于JPEG使用有损压缩,因此图像的质量会下降(在将图像导出为JPEG时可以微调压缩级别/降级。有关更多信息,请参阅成像软件的文档)。
但是,虽然可能与JPEG一样好,但它不支持透明度。如果您要使图像可以通过其他人显示,或者想要具有不规则形状的图像,这就至关重要。GIF是一个不错的选择,但是它已被PNG所取代(GIF支持的几件事PNG不支持,但它们在游戏编程中基本上无关紧要)。
PNG支持透明性(和半透明性),在不降低质量的情况下压缩数据(即,使用无损压缩),并且压缩效果相当好,但不及JPG。
当您需要良好的压缩以及透明度时,就会出现问题。如果您不介意图像质量稍有下降,可以使用PNG量化程序(如pngquant),您可以在TinyPNG上在线对其进行测试。请记住,量化本身导致的图像质量下降与JPEG(包括量化以及其他主动技术)所造成的图像质量下降有所不同,因此请务必在多种设置下尝试两者。
如果您想最大程度地减小分发大小,则可以手动处理每个图像,如下所示:
if the image has transparency then
try pngquant on the image
if the results are not satisfactory then
revert to the non-quantized image
end
store as PNG
else
try storing it as JPG with different quality settings
if no single setting yields an image of an acceptable quality then
try pngquant on the image
if the results are not satisfactory then
revert to the non-quantized image
end
store as PNG
else
store as JPG
end
end
提示:可以以一种格式存储一些图像,而以另一种格式存储其他图像。
还有其他专用格式,例如DXT,ETC和PVRTC。它们支持压缩,也可以压缩后加载到内存中,但是它们仅受特定的GPU支持,并且这些GPU中的大多数仅支持其中一个,因此除非您知道目标硬件的确切硬件规格(值得注意的情况是(支持PVRTC纹理的iPhone / iPad),则应避免使用这些格式。
程序记忆
我将其包含在此处,因为这就是“内存”的通常名称。但是,如果您的游戏使用图形加速(并且很可能是在1998年以后制作游戏),那么唯一会消耗内存的是纹理描述符(每个图像只有几个字节),这仅取决于图像的数量,而不是图像的大小或格式(这有一些警告,但大多数是无关紧要的)。
如果您的平台没有专用视频内存,没有硬件加速或其他不常见的情况,则有关VRAM的下一部分将完全或部分在RAM中发生,但主要原理相同。
显存
程序运行后,将在此处存储图像。通常,这里存储它们的格式没有什么区别,因为所有图像在加载到视频存储器之前都已解压缩。
现在,映像消耗的VRAM大致是width * height * bitdepth
针对 VRAM中加载的每个映像。这里有几件事要注意:
在VRAM中存储图像的宽度和高度不一定与原始图像的宽度和高度匹配。某些GPU只能处理大小为2的幂的纹理,因此您的320x240图像实际上可能存储在VRAM的512x256空间中,有效地浪费了未使用的内存。有时甚至不允许加载大小不是2的幂的纹理(例如在GLES 1.1中)。
因此,如果要最大程度地减少VRAM的使用,则可能需要考虑对图像进行地图集处理,并以2的幂进行调整大小,这还具有在渲染时减少渲染状态更改的优点。稍后再详细介绍。
位深度非常重要。通常,纹理以32位ARGB或32位XRGB的形式加载到VRAM中,但是如果您的硬件可以支持16位深度,并且您不介意位深度较低,则可以将每个图像消耗的VRAM数量减少一半,这可能是一件有趣的事情。
但是无论您做什么,考虑游戏使用的VRAM数量时,最重要的因素是给定时间VRAM中的图像数量。如果您想要一款性能出色的游戏,那么您最有可能希望将其保持在最低水平。将纹理加载和卸载到VRAM中非常昂贵,因此,在使用每一个图像时都不能仅仅加载它。您必须在预加载您最有可能使用的图像与确定您不再要使用它们的图像之间卸载之间找到平衡。做到这一点并非易事,您必须考虑自己针对特定游戏的策略。
执行速度
即使不是“内存”,它也与游戏性能密切相关。绘制图像非常昂贵,并且您要确保渲染运行尽可能快。当然,在这里,格式无关紧要,但是其他事情却可以:
图像尺寸(实际上是“采样尺寸”):要绘制的图像区域越大,则绘制图像所花费的时间就越多。在屏幕的一小部分中渲染大图像效果不是很好,因此存在一种称为mipmapping的技术,该技术包括通过交易VRAM来提高渲染速度,方法是将图像以多种分辨率存储几次,并使用最小的分辨率在任何给定时间为您提供所需的质量。可以在加载映像时执行Mipmapping,这会影响加载速度和VRAM的使用,或者在预处理时(通过手动存储同一映像的不同版本,或使用本机支持mipmapping的格式(例如DDS))会影响存储。和VRAM的使用,但对加载速度几乎没有影响。
渲染状态更改。您很可能希望同时在屏幕上绘制几个不同的图像。但是,GPU在任何给定时间只能使用一个源图像(这是不正确的,但请在这里与我联系)。当前用于渲染的图像是许多渲染状态之一,并且价格昂贵。因此,如果您打算多次使用同一张图片(还记得我提到的纹理地图集吗?),如果您在更改渲染状态并开始使用a之前尽可能多地重复使用图片,则会发现性能获得了巨大的提升。不同的图像(除此之外还有其他渲染状态,在增强游戏性能时,微调绘制对象的顺序以最小化渲染状态变化是很常见的活动)
但是,图像使用优化是一个非常复杂的主题,我在这里写的内容是对编写游戏时必须考虑的一些因素的广泛而过分简化的概述,因此,我认为最好保持简洁是最好的选择,并且仅在真正需要的时候进行优化。在大多数情况下,过早的优化是不必要的(有时甚至是有害的),因此请放轻松。
setEnforcePotImages
,它禁用了OpenGLES 1.0的2种大小纹理的增强功能。这不是一个好主意,因为并非所有硬件都支持非2幂幂纹理。OpenGLES 2.0需要支持非2次幂纹理,因此,如果您的目标是2.0,则可以使用任何大小的纹理。有关更多信息,请参考libgdx文档。
一旦将图像从磁盘上加载并格式化以进行渲染,它将使用相同数量的内存,而不管该图像是使用PNG,JPEG还是GIF保存到磁盘的。
一般经验法则:JPEG是一种有损格式,会降低图像质量,从而使磁盘上的图像变小。另一方面,PNG是无损图像格式,因此通常会导致磁盘上的文件更大。从技术上讲,GIF也是一种无损格式,但是每个图像最多支持256种颜色,因此如果将彩色图像另存为GIF,则通常会导致质量下降。
但是,这仅用于磁盘上的表示。在内存中,无论您将它们以PNG,JPEG还是GIF格式保存到磁盘上,它们都将使用相同的内存量扩展为相同的纹理格式。
我对libgdx不太了解,但是对图像格式和图形了解不多:
JPEG在真实照片中非常好。它们是有损的,但是除非您用清晰的彩色空间(如书面文字或漫画)拍摄锐利边缘的照片,否则您不会在照片上看到人工痕迹。将它们用于大型背景图形。
GIF已过时,它只能存储具有一种专用颜色的调色板颜色(每个像素最多8位),以实现完全透明。它允许基于帧的小动画。曾经有一种关于其打包算法的专利,因此不能合法地在任何地方使用它。由于该专利,开发了PNG。
PNG或多或少是可以存储RGB + alpha(最大32bit)和其他像素格式的压缩位图。它专门用于快速解压缩图片的一小部分,这对于非常小的和慢速的设备(例如10岁的手机)来说很方便,但是今天的库在加载时只是将它们解压缩为位图。
PNG在大小,速度和功能方面比GIF更好,但是,如果您想有效地存储位图,我建议:.PNM.BZ2([由于不同的打包方法,.PNM.BZ2并不总是效率更高比.PNG。[/ edit])
PNM / PBM / PGM / PAM是具有纯文本KISS标题的纯位图格式。在这些文件上使用gzip将导致文件大小类似于PNG,因此bzip2是更好的解决方案。如果要在程序内部使用位图,则可能要在.tar或.zip容器中使用bzip2压缩的位图。如果没有bzip2,则在zip容器(压缩程度最高的zip)中使用PNM可能与使用PNG相似。–因此,将PNG存储在ZIP文件中可能只会带来很小的好处,或者没有任何好处–很可能只会增加加载图像的时间。
除此之外,将多个小图片/图片存储在一个位图中是一个不错的选择,尤其是当您在相同的情况下都需要它们时。
作为存储格式,JPEG可能是草木或墙壁等某些纹理的最佳选择,在这些纹理中信息丢失可能是无法检测到的。当您需要透明性或无法在信息丢失的情况下付款(例如2D游戏中的精灵(玩家,敌人,宝库))时,紧随其后的是PNG,您可能希望对图像使用PNG。
在谈到内存成本时,用于在文件系统中存储游戏图形的格式根本不相关。如果将像素缓冲区存储在VRAM或RAM(软件渲染器)中,则可能会将它们存储为未压缩状态,因为游戏倾向于快速读取像素而不是每个像素缓冲区所使用的内存。
将压缩数据存储在内存中没有任何意义,除非您维护某种缓存以保存磁盘读取,但是对于游戏中给定时间使用的图像,您可能必须从该缓存读取到未压缩状态。
如果可以进行快速的硬件解码,则压缩后的图像数据更具意义。至少对于法线贴图,我记得这个http://en.wikipedia.org/wiki/3Dc。这样,您可以保存一些VRAM。我还不知道其他硬件解码示例。
在简历中:无论您的游戏将图形存储在永久性存储中的格式是什么,您都必须对其进行解码并在动态内存,视频内存或两者中保持未压缩的版本,以便能够在需要时快速渲染它们。
最后:我是桌面专家。当我说“内存”时,我总是指动态内存。当我说“磁盘”,“文件系统”或“永久性存储”时,我总是指您的设备用作永久性存储的任何东西,通常我认为是在硬盘中。当您说“内存效率”时,我将其用于“动态内存”而不是“持久存储”。最近,我看到很多人使用“内存”一词来指代“永久存储”(也许是移动设备的术语?)。