手游资源优化--美术你怎么看
--引言
作者简介:高级3D动画特效,目前在项目组内主要负责游戏内的战斗表现、动画特效制作和一些与开发策划的协作工作。
资源优化这种高大尚的东西,大部分美术都是知其然而不知其所以然,面对开发哥的发难很难扳回一成。这篇文章将从美术的角度出来带你去了解手游资源优化的来龙去脉,从制作的初期就很好的去规划资源避免后期大规模的资源重制和浪费。
--满满的干货
手游资源优化总的来说需要做到以下几点:
1、尽可能的缩小和合并纹理贴图。
2、尽可能的降低并合并DrallCall。
3、最简化Shader。
4、减少大面积的半透明计算。
--手机图像处理基础知识
为了支撑上面的结论,我们先来看看智能手机处理图像的一些理论知识:
A、大部分职能手机的核心高速显存是1M,且未来的一两年内情况不会得到太大改观。主流手机的运行内存为1G-2G,但是为了适配低端机,一般一款应用的占用内存需要控制在200M以内(之前项目的数据)。主流手机的GPU核心频率在600Mhz左右。高通的技术专家建议手机游戏的最大分辨率保持在720P,保持游戏的流畅度和降低耗电量。
B、因为显存和运行内存小,所以智能手机上的图像处理会划分为数个小格子,分开进行图像计算处理。下面是一个球体进入画面所会产生的计算步骤,假设背景是不动的,那么红色的格子代表产生计算量的部分。
C、下面我们再来简单看下手机各模块和它的作用。简单来说,手机发热和耗电大部分时间是因为处理器的计算和内存的反复读写造成的。
所以尽可能的缩小纹理和避免大面积的半透计算能够很大程度上缓解显存和内存的压力。
--什么是Drawcall
简单来说Drawcall是当前时间帧下,请求绘制模型顶点和图像的需求,由于手机的计算处理能力有限,所以Drawcall对手机来说是一个非常重要的优化点。下图中红色框体的部分就代表了这一帧下产生了4个Drawcall,绘制时会按照上面的分块理论进行处理(还有很多背景的部分为了演示方便没有框进来)
如上图假设当前画面中所的纹理使用了两张合并的纹理贴图,且前后层的属性(Shader、各种参数等)是一致的,那么可以通过调整Dracall的次序,让同属性同纹理的Drawcall合并,从6个变成2个,大大提高图像运算速度。
--Shader简述
Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)
以指定的方式和输入的贴图或者颜色等组 合作用,然后输出。包含以下三个部分:
1、States(状态值):如材质颜色(Material Color)、材质的贴图(Material Texture)、混色方式(blending option)等等。
2、顶点着色器指令:定义如何运算、操作每一个已经着色完成的面所包含的顶点数据,在运算、操作过程中,GPU将只使用 State所定义的顶点属性(如顶点颜色、顶点法向量或是贴图轴坐标…等)做计算。
3、像素着色器指令:定义如何运算、操作每一个已经着色完成的面所包含的像素数据,在运算、操作过程中,GPU将只使用「着色状态值」(Render State)所定义的像素属性(如像素颜色、像素混色或是Z值…等)做计算。
混色计算公式:
可以看到,Shader包含着大量的数学计算,效果的层次越多,计算量就越大。手游应该尽可能的减少效果的层次,并最简化Shader的逻辑(引擎自带的默认Shader会把多个功能合并在一个Shader里,手游应该尽量去提炼出我们需要的部分做最简化处理,而不要直接使用默认的Shader)。
--美术你怎么看
资源优化与美术效果总是鱼和熊掌不可兼得,但通过这篇文章,希望美术同僚能够从自己的出发点上提前做足准备,以免后期资源优化的过程中让美术效果大打折扣甚至导致项目延后和时间上的浪费。
最后结合实例回顾下重点:
A减少大面积的半透明计算、最简化Shader。
由于手机显示模式的特点,大面积的半透明动画就意味着高速显存的满负荷运转,特别是纹理比较大和层次比较多的时候,特效部分还会涉及到Shader的数学计算部分。大部分的游戏卡顿和FPS下降都是因为这个原因造成的。且所有带有alpha通道的纹理,都会被判定为半透明。
这个技能,由于大面积的半透明和叠加计算,导致运行时FPS从25掉到了13。
而降大面积的半透明去掉以后,运行时的FPS提升回了23。
为了保证游戏内的效果和流畅度,在制作时建议分级制作效果,根据手机的性能调用不同的分级效果。而shader涉及到数学计算的部分,需要尽量的精简计算的步骤,减少一些不需要的计算,降低CPU的压力。
B尽可能的缩小和合并纹理贴图、尽可能的降低并合并DrallCall。
缩小纹理的部分之前在KM上有一篇分享:
结论是:在Iphone4屏幕大小的面积上,电脑上960*640像素静止的图片50%的压缩比在手机上大部分人(除开专业的美术)看不出区别,25%压缩比只有较小的区别。而动画特效大部分是连续的动效。压缩可以分为几个部分进行压缩:主体造型和需要清晰边缘的部分50%-60%压缩比;存在时间短但面积大的部分30%-40%压缩比;很小很模糊的部分10%-30%压缩比。
合并纹理的好处,通过下面一组图进行说明:
这是一个角色的3个技能所需要的序列图素,最终切碎压缩后大小为512*512像素,如果不切碎仅使用TexturePacker拼接得到的图像大小为512*1024,如果不使用TexturePacker想使用这套序列贴图总图素大小会在2048*2048以上。TexturePacker可以很好的压缩序列图的尺寸,减少图片的容量大小,缓解内存上的压力。
降低并合并DrallCall实例1(2D引擎):
使用图素来源于同一张贴图且属性一致都为高亮时,Drawcall为1
使用图素来源于同一张贴图且第二层A_02属性去掉高亮时,Drawcall为3
使用图素来源于同一张贴图且第三层A_03属性去掉高亮、A_01和A_02属性一致时,Drawcall为2
使用A高亮B没有高亮,如图交叉混合时Drawcall为6
使用A高亮B没有高亮,如图同属性归类排列时Drawcall为2
降低并合并DrallCall实例2(U3D引擎):
U3D是一款3D引擎,所以降低Drallcall要分为粒子渲染和模型渲染两块。
U3D的粒子系统里,渲染属性下有个设置可以调整渲染的先后顺序,我们通过改变这个数字来调整渲染顺序。
使用图素来源于同一张贴图且A为Blend、B为高亮,AB交叉排列时,Drawcall为6
使用图素来源于同一张贴图且A为Blend、B为高亮,AB分类排列时Drallcall为2。
一般模型的渲染先后顺序取决于它到摄像机的距离,而特效模型的调用可以通过粒子发射模型的方式来设置它的渲染先后顺序,但是由于模型无法合并渲染,所以每个单个的模型都会产生一个Drallcall,目前还不知道有能够合并渲染粒子调用模型的方法。3D模型上产生的Drallcall可以通过合并模型贴图和减少同一时间内出现的Mesh数量来控制。
所以,实际操作时,保证同已帧下各图层的图素和属性是一致的并且按属性类别组合排列图层顺序就可以合并和降低Drawcall。
--总结
手游的开发跟以往端游和页游的开发有很多相同之处同时也存在很大的差别,每个游戏平台都拥有自己的特点。这篇文章是我从事手游开发所累积的一些经验,希望各位美术同学都能够刨根问底的去看待资源优化问题,从根源上理解手游资源优化的目的和途径。其实美术可以做到的更多,换个角度去看去理解也许一些问题就会豁然开朗。
现在手游开发节奏越来越快,资源优化如果能在制作的前期就制定好相应的规范,想必能在开发末的冲刺期省下不少的时间和精力。希望大家能通过这篇文章都有所斩获,如果有什么问题也欢迎与我一起探讨。