Unity模型、场景整合--美工制作优化事项 - 纳金网
联系我们

给我们留言

联系我们

地址:福建省晋江市青阳街道洪山路国际工业设计园纳金网

邮箱:info@narkii.com

电话:0595-82682267

(周一到周五, 周六周日休息)

当前位置:主页 > 3D教程 > 图文教程

Unity模型、场景整合--美工制作优化事项

来源: csdn | 责任编辑:六月芳菲 | 发布时间: 2018-08-10 09:51 | 浏览量:
1.Draw Call Batching优化
首先我们要先理解为何2个没有使用相同材质的物体即使使用批处理,也无法实现Draw Call数量的下降和性能上的提升。
因为被“批处理”的2个物体的网格模型需要使用相同材质的目的,在于其纹理是相同的,这样才可以实现同时渲染的目的。因而保证材质相同,是为了保证被渲染的纹理相同。
因此,为了将2个纹理不同的材质合二为一,我们就需要进行上面列出的第二步,将纹理打包成图集。具体到合二为一这种情况,就是将2个纹理合成一个纹理。这样我们就可以只用一个材质来代替之前的2个材质了。
而Draw Call Batching本身,也还会细分为2种。
Static Batching 静态批处理
看名字,猜使用的情景。
静态?那就是不动的咯。还有呢?额,听上去状态也不会改变,没有“生命”,比如山山石石,楼房校舍啥的。那和什么比较类似呢?嗯,聪明的各位一定觉得和场景的属性很像吧!所以我们的场景似乎就可以采用这种方式来减少draw call了。
那么写个定义:只要这些物体不移动,并且拥有相同的材质,静态批处理就允许引擎对任意大小的几何物体进行批处理操作来降低描绘调用。
那要如何使用静态批来减少Draw Call呢?你只需要明确指出哪些物体是静止的,并且在游戏中永远不会移动、旋转和缩放。想完成这一步,你只需要在检测器(Inspector)中将Static复选框打勾即可,如下图所示:
2.减少绘制的数目
那么第一个方面的优化也就是减少顶点数量,简化复杂度,具体的举措就总结如下了:
·保持材质的数目尽可能少。这使得Unity更容易进行批处理。
·使用纹理图集(一张大贴图里包含了很多子贴图)来代替一系列单独的小贴图。它们可以更快地被加载,具有很少的状态转换,而且批处理更友好。
·如果使用了纹理图集和共享材质,使用Renderer.sharedMaterial 来代替Renderer.material 。
·使用光照纹理(lightmap)而非实时灯光。
·使用LOD,好处就是对那些离得远,看不清的物体的细节可以忽略。
·遮挡剔除(Occlusion culling)
·使用mobile版的shader。因为简单。
3.优化建议二:
a.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与CPU。
b.如果你用U3D自带的SHADER,在表现不差的情况下选择Mobile或Unlit目录下的。它们更高效。
c.尽可能共用材质。
d.将不需要移动的物体设为Static,让引擎可以进行其批处理。
e.尽可能不用灯光。
f.动态灯光更加不要了。
g.尝试用压缩贴图格式,或用16位代替32位。
h.如果不需要别用雾效(fog)
i.尝试用OcclusionCulling,在房间过道多遮挡物体多的场景非常有用。若不当反而会增加负担。
j.用天空盒去“褪去”远处的物体。
k.shader中用贴图混合的方式去代替多重通道计算。
l.shader中注意float/half/fixed的使用。
m.shader中不要用复杂的计算pow,sin,cos,tan,log等。
n.shader中越少Fragment越好。
o.注意是否有多余的动画脚本,模型自动导入到U3D会有动画脚本,大量的话会严重影响消耗CPU计算。
p.注意碰撞体的碰撞层,不必要的碰撞检测请舍去。
4.假设你有一个上千三角面的模型却用上千个三角型模型来代替,在GPU上花费是差不多的,但是在CPU上则是极其不一样,消耗会大很多很多。为了让CPU更少的工作,需要减少可见物的数目,可以采取以下措施:
a.合并相近的模型,手动在模型编辑器中合并或者使用UNITY的Draw call批处理达到相同效果(Draw call batching)。具体方法和注意事项查看以下链接:Draw call batching : http://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html
b.在项目中使用更少的材质(material),将几个分开的贴图合成一个较大的图集等方式处理。(有一个合并模型材质不错的插件叫Mesh Baker,大家可以考虑试下。)
6.关于光照
若不用光肯定是最快的。移动端优化可以采用用光照贴图(Lightmapping)去烘培一个静态的贴图,以代替每次的光照计算,在U3D中只需要非常短的时间则能生成。这个方法能大大提高效率,而且有着更好的表现效果(平滑过渡处理,还有附加阴影等)。
在移动设备上和低端电脑上尽量不要在场景中用真光,用光照贴图。这个方法大大节省了CPU和GPU的计算,CPU得到了更少的DRAWCALL,GPU则需要更少顶点处理和像素栅格化。
Lightmapping : http://docs.unity3d.com/Documentation/Manual/Lightmapping.html
7.对GPU的优化——图片压缩和多重纹理格式
Compressed Textures(图片压缩):
http://docs.unity3d.com/Documentation/Components/class-Texture2D.html
图片压缩将降低你的图片大小(更快地加载更小的内存跨度(footprint)),而且大大提高渲染表现。压缩贴图比起未压缩的32位RGBA贴图占用内存带宽少得多。
之前U3D会议还听说过一个优化,贴图尽量都用一个大小的格式(512 * 512 , 1024 * 1024),这样在内存之中能得到更好的排序,而不会有内存之间空隙。这个是否真假没得到过测试。
MIPMAps(多重纹理格式):
http://docs.unity3d.com/Documentation/Components/class-Texture2D.html
跟网页上的略缩图原理一样,在3D游戏中我们为游戏的贴图生成多重纹理贴图,远处显示较小的物体用小的贴图,显示比较大的物体用精细的贴图。这样能更加有效的减少传输给GPU中的数据。
8.LOD 、 Per-Layer Cull Distances 、 Occlusion Culling
LOD (Level Of Detail) 是很常用的3D游戏技术了,其功能理解起来则是相当于多重纹理贴图。在以在屏幕中显示模型大小的比例来判断使用高或低层次的模型来减少对GPU的传输数据,和减少GPU所需要的顶点计算。
摄像机分层距离剔除(Per-Layer Cull Distances):为小物体标识层次,然后根据其距离主摄像机的距离判断是否需要显示。
遮挡剔除(Occlusion Culling)其实就是当某个物体在摄像机前被另外一个物体完全挡住的情况,挡住就不发送给GPU渲染,从而直接降低DRAW CALL。不过有些时候在CPU中计算其是否被挡住则会很耗计算,反而得不偿失。
以下是这几个优化技术的相关使用和介绍:
Level Of Detail :
http://docs.unity3d.com/Documentation/Manual/LevelOfDetail.html
Per-Layer Cull Distances :
http://docs.unity3d.com/Documentation/ScriptReference/Camera-layerCullDistances.html
Occlusion Culling :
http://docs.unity3d.com/Documentation/Manual/OcclusionCulling.html
9.优化: 
① 更新不透明贴图的压缩格式为ETC 4bit,因为android市场的手机中的GPU有多种,
每家的GPU支持不同的压缩格式,但他们都兼容ETC格式,
②对于透明贴图,我们只能选择RGBA 16bit 或者RGBA 32bit。
10.地形
·地形的分辨率大小
长宽均尽量小于257。这是因为地形太大,会造成大量顶点数据,给你的内存带宽造成一定的影响,在目前的ios设备中,内存带宽是非常有限的,需要尽量节省。同时,如果用Unity自带的地形,一定也要使用Occlusion Culling,因为Unity的刷地形工具虽然方便,但却是framekiller,刷过之后,你会发现drawcall增加的非常多。
·混合纹理数量
不要超过4。地形的混合操作是很耗时的,应该尽量避免。能合并的纹理尽量合并。
11.纹理
·纹理格式
建议png或tga。不用转成ios硬件支持的PVRTC格式,因为Unity在发布时会帮你自动转的。
·纹理尺寸
长宽小于1024。同时应该尽可能地小,够用就好,以保证纹理对内存带宽的影响达到最小。
·支持Mipmap
建议生成Mipmap。虽然这种做法会增加一些应用程序的大小,但在游戏运行时,系统会根据需求应用Mipmap来渲染,从而减少内存带宽。
·检查Alpha值
如果纹理的alpha通道均为1,则用RGB的24位纹理来代替RGBA的32位纹理。(据说Unity内部会进行自动检测)
12.光源
·光源“Important”个数
建议1个,一般为方向光。“Important”个数应该越小越少。个数越多,drawcall越多。
·Pixel Light数目
1-2个。
13.粒子特效
·屏幕上的最大粒子数
建议小于200个粒子。
·每个粒子发射器发射的最大粒子数
建议不超过50个。
·粒子大小
如果可以的话,粒子的size应该尽可能地小。因为Unity的粒子系统的shader无论是alpha test还是alpha blending都是一笔不小的开销。同时,对于非常小的粒子,建议粒子纹理去掉alpha通道。
·尽量不要开启粒子的碰撞功能。
非常耗时。
14.音频
·游戏中播放时间较长的音乐(如背景音乐)
使用.ogg或.mp3的压缩格式。
·较短音乐(如枪声)
使用.wav和.aif的未压缩音频格式。
15.相机
·裁剪平面
将远平面设置成合适的距离。远平面过大会将一些不必要的物体加入渲染,降低效率。
·根据不同的物体设置不同的远裁剪平面
Unity提供了可以根据不同的layer来设置不同的view distance,所以我们可以实现将物体进行分层,大物体层设置的可视距离大些,而小物体层可以设置地小些,另外,一些开销比较大的实体(如粒子系统)可以设置得更小些等等。
16.碰撞
·尽量不用MeshCollider
如果可以的话,尽量不用MeshCollider,以节省不必要的开销。如果不能避免的话,尽量用减少Mesh的面片数,或用较少面片的代理体来代替。
17.其他
·Drawcall
尽可能地减少Drawcall的数量。IOS设备上建议不超过100。减少的方法主要有如下几种:Frustum Culling,Occlusion Culling,Texture Packing。Frustum Culling是Unity内建的,我们需要做的就是寻求一个合适的远裁剪平面;Occlusion Culling,遮挡剔除,Unity内嵌了Umbra,一个非常好OC库。但Occlusion Culling也并不是放之四海而皆准的,有时候进行OC反而比不进行还要慢,建议在OC之前先确定自己的场景是否适合利用OC来优化;Texture Packing,或者叫Texture Atlasing,是将同种shader的纹理进行拼合,根据Unity的static batching的特性来减少draw call。建议使用,但也有弊端,那就是一定要将场景中距离相近的实体纹理进行拼合,否则,拼合后很可能会增加每帧渲染所需的纹理大小,加大内存带宽的负担。这也就是为什么会出现“DrawCall降了,渲染速度也变慢了”的原因。
·非运动物体尽量打上Static标签
Unity在运行时会对static物体进行自动优化处理,所以应该尽可能将非运行实体勾上static标签。
·场景中尽可能地使用prefab
尽可能地使用prefab的实例化物体,以降低内存带宽的负担。检查实体的PrefabType,尽量将其变成PrefabInstance,而不是ModelPrefabInstance。
·尽量减少alphaTest和alphaBlend材质的使用。在手机上,这是很杀效率的。
·网格:如果可能的话,把相邻的物体(网格)合并为一个只有一个材质的物体(网格)。比如,你的游戏中包含一个桌子,上面有一堆东西,你完全可以在3D程序中将它们合并在一起(这可能也需要你将这些物体的纹理合并为一个大的纹理集)。减少需要渲染的物体的数量可以极大地提高游戏性能。
·性能占用顺序:聚光灯>点光源>平行光。
一个好的点亮场景的方法就是先得到你想要的效果,然后看看哪些光更重要;
在保持光效的前提下看看哪些光可以去掉。
点光源和聚光灯只影响它们范围内的网格。
如果一个网格处于点光源或者聚光灯的照射范围之外,并且光源的attenuate开关是打开的,那么这个网格将不会被光源所影响,这样就可以节省性能开销。
这样做理论上来讲可以使用很多小的点光源而且依然能有一个好的性能,因为这些光源只影响一小部分物体。
一个网格在有8个以上光源影响的时候,只响应前8个最亮的光源。
18.模型方面优化三
    ·合并使用同贴图的材质球,合并使用相同材质球的Mesh;
  ·角色的贴图和材质球只要一个,若必须多个则将模型离分离为多个部分;
  ·骨骼系统不要使用太多;
  ·当使用多角色时,将动画单独分离出来;
  ·使用层距离来控制模型的显示距离;
  ·阴影其实包含两方面阴暗和影子,建议使用实时影子时把阴暗效果烘焙出来,不要使用灯光来调节光线阴暗。
  ·少用像素灯和使用像素灯的Shader;
    ·如果硬阴影可以解决问题就不要用软阴影,并且使用不影响效果的低分辨率阴影;
  ·实时阴影很耗性能,尽量减小产生阴影的距离;
  ·允许的话在大场景中使用线性雾,这样可以使远距离对象或阴影不易察觉,因此可以通过减小相机和阴影距离来提高性能;
  ·使用圆滑组来尽量减少模型的面数;
  ·项目中如果没有灯光或对象在移动那么就不要使用实时灯光;
  ·水面、镜子等实时反射/折射的效果单独放在Water图层中,并且根据其实时反射/折射的范围来调整;
  ·碰撞对效率的影响很小,但碰撞还是建议使用Box、Sphere碰撞体;
  ·建材质球时尽量考虑使用Substance;
  ·尽量将所有的实时反射/折射(如水面、镜子、地板等等)都集合成一个面;
  ·假反射/折射没有必要使用过大分辨率,一般64*64就可以,不建议超过256*256;
  ·需要更改的材质球,建议实例化一个,而不是使用公共的材质球;
  ·将不须射线或碰撞事件的对象置于IgnoreRaycast图层;
  ·将水面或类似效果置于Water图层
  将透明通道的对象置于TransparentFX图层;
  ·养成良好的标签(Tags)、层次(Hieratchy)和图层(Layer)的条理化习惯,将不同的对象置于不同的标签或图层,三者有效的结合将很方便的按名称、类别和属性来查找;
    ·通过Stats和Profile查看对效率影响最大的方面或对象,或者使用禁用部分模型的方式查看问题到底在哪儿;
  ·使用遮挡剔除(Occlusion Culling)处理大场景,一种较原生的类LOD技术,并且能够“分割”作为整体的一个模型。

相关文章
网友评论

您需要登录后才可以发帖 登录 | 立即注册

关闭

全部评论:0条

推荐
热门