unity几种优化建议
最简单的优化建议: 1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与CPU。 1.为什么需要针对CPU(中央处理器)与GPU(图形处理器)优化? CPU和GPU都有各自的计算和传输瓶颈,不同的CPU或GPU他们的性能都不一样,所以你的游戏需要为你目标用户的CPU与GPU能力进行针对开发。 2.CPU与GPU的限制 GPU一般具有填充率(Fillrate)和内存带宽(Memory Bandwidth)的限制,如果你的游戏在低质量表现的情况下会快很多,那么,你很可能需要限制你在GPU的填充率。 CPU一般被所需要渲染物体的个数限制,CPU给GPU发送渲染物体命令叫做DrawCalls。一般来说DrawCalls数量是需要控制的,在能表现效果的前提下越少越好。通常来说,电脑平台上DrawCalls几千个之内,移动平台上DrawCalls几百个之内。这样就差不多了。当然以上并不是绝对的,仅作一个参考。 往往渲染(Rendering)并不是一个问题,无论是在GPU和CPU上。很可能是你的脚本代码效率的问题,用Profiler查看下。 关于Profiler介绍:http://docs.unity3d.com/Documentation/Manual/Profiler.html 需要注意的是: 3.关于顶点数量和顶点计算 CPU和GPU对顶点的计算处理都很多。GPU中渲染的顶点数取决于GPU性能和SHADER的复杂程度,一般来说,每帧之内,在PC上几百万顶点内,在移动平台上不超过10万顶点。 CPU中的计算主要是在蒙皮骨骼计算,布料模拟,顶点动画,粒子模拟等。GPU则在各种顶点变换、光照、贴图混合等。 【个人认为,具体还是看各位的项目需求,假设你项目的是3d游戏。你游戏需要兼容低配置的硬件、流畅运行、控制硬件发热的话,还要达到一定效果(LIGHTMAP+雾效),那么顶点数必定不能高。此时同屏2W顶点我认为是个比较合适的数目,DRAWCALL最好低于70。另,控制发热请控制最高上限的帧率,流畅的话,帧率其实不需要太高的。】 4.针对CPU的优化——减少DRAW CALL 的数量 为了渲染物体到显示器上,CPU需要做一些工作,如区分哪个东西需要渲染、区分开物体是否受光照影响、使用哪个SHADER并且为SHADER传参、发送绘图命令告诉显示驱动,然后发送命令告诉显卡删除等这些。 假设你有一个上千三角面的模型却用上千个三角型模型来代替,在GPU上花费是差不多的,但是在CPU上则是极其不一样,消耗会大很多很多。为了让CPU更少的工作,需要减少可见物的数目: a.合并相近的模型,手动在模型编辑器中合并或者使用UNITY的Draw call批处理达到相同效果(Draw call batching)。具体方法和注意事项查看以下链接: Draw call batching : http://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html b.在项目中使用更少的材质(material),将几个分开的贴图合成一个较大的图集等方式处理。 如果你需要通过脚本来控制单个材质属性,需要注意改变Renderer.material将会造成一份材质的拷贝。因此,你应该使用Renderer.sharedMaterial来保证材质的共享状态。 有一个合并模型材质不错的插件叫Mesh Baker,大家可以考虑试下。 c.尽量少用一些渲染步骤,例如reflections,shadows,per-pixel light 等。 d.Draw call batching的合并物体,会使每个物体(合并后的物体)至少有几百个三角面。 假设合并的两个物体(手动合并)但不共享材质,不会有性能表现上的提升。多材质的物体相当于两个物体不用一个贴图。所以,为了提升CPU的性能,你应该确保这些物体使用同样的贴图。 另外,用灯光将会取消(break)引擎的DRAW CALL BATCH,至于为什么,查看以下: Forward Rendering Path Details: e.使用相关剔除数量直接减少Draw Call数量,下文有相关提及。 5.优化几何模型 最基本的两个优化准则: 需要注意的是,图形硬件需要处理顶点数并跟硬件报告说的并不一样。不是硬件说能渲染几个点就是几个点。模型处理应用通展示的是几何顶点数量。例如,一个由一些不同顶点构成的模型。在显卡中,一些集合顶点将会被分离(split)成两个或者更多逻辑顶点用作渲染。如果有法线、UV坐标、顶点色的话,这个顶点必须会被分离。所以在游戏中处理的实际数量显然要多很多。 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 : Per-Layer Cull Distances : Occlusion Culling : 9.关于Realtime Shadows(实时阴影) 实时阴影技术非常棒,但消耗大量计算。为GPU和CPU都带来了昂贵的负担,细节的话参考下面: http://docs.unity3d.com/Documentation/Manual/Shadows.html 10.对GPU优化:采用高效的shader a.需要注意的是有些(built-in)Shader是有mobile版本的,这些大大提高了顶点处理的性能。当然也会有一些限制。 b.自己写的shader请注意复杂操作符计算,类似pow,exp,log,cos,sin,tan等都是很耗时的计算,最多只用一次在每个像素点的计算。不推荐你自己写normalize,dot,inversesqart操作符,内置的肯定比你写的好。 c.需要警醒的是alpha test,这个非常耗时。 d.浮点类型运算:精度越低的浮点计算越快。 在CG/HLSL中-- float :32位浮点格式,适合顶点变换运算,但比较慢。 写Shader优化的小提示: 11.另外的相关优化: a.对Draw Call Batching的优化 b.对Rendering Statistics Window的说明和提示: c.角色模型的优化建议 http://docs.unity3d.com/Documentation/Manual/ModelingOptimizedCharacters.html 优化: 1. 更新不透明贴图的压缩格式为ETC 4bit,因为android市场的手机中的GPU有多种, 2. 对于透明贴图,我们只能选择RGBA 16bit 或者RGBA 32bit。 3. 减少FPS,在ProjectSetting-> Quality中的 4. 当我们设置了FPS后,再调整下Fixed timestep这个参数, 5. 尽量少使用Update LateUpdate FixedUpdate,这样也可以提升性能和节省电量。 6. 待机时,调整游戏的FPS为1,节省电量。 7. 图集大小最好不要高于1024,否则游戏安装之后、低端机直接崩溃、原因是手机系统版本低于2.2、超过1000的图集无法读取、导致。 VSCount 垂直同步 在右侧面板中可以找到VSync Count,把它选成Don't Sync。 现在来说说什么是垂直同步,要知道什么是垂直同步,必须要先明白显示器的工作原理, 什么叫水平同步?什么叫垂直同步? 为什么关闭垂直同步信号会影响游戏中的FPS数值? 而如果我们选择不等待垂直同步信号(也就是我们平时所说的关闭垂直同步),那么游戏中作完一屏画面, 合并材质球unity 3d中每倒入一次模型就多一个材质球,可我的这些模型都是共用一张贴图的就想共用一个材质球,所以每次都要删除再附上,很麻烦。怎么才能合并这些材质球? 需要注意的是:需要合并的纹理应该是物体在场景中距离相近的,如果物体在场景中的距离较远, mesh合并 2.也可以用脚本来合并mesh 。 [C#] 纯文本查看 复制代码
1. 先在 Unity 中建立 空物件 ( Empty ) 后
2、静态实体
3、地形
4、纹理
5、光源
6、粒子特效
7、音频
8、相机
9、碰撞
10、其他
========================================分割线==================================== 移动平台相对于PC机,具有体积小,计算弱,带宽少的特点。 因此做手机游戏的开发,优化的方向,与力度对比PC游戏都有所区别。 必须要做到优化流程,合理利用资源。 目前在手机上面,还不能够像PC游戏那样追求高质量渲染效果,为了让手机不那么容易发烫,还要控制cpu,gpu,不能让他们全速运算。 材质方面: 纹理方面,建议使用压缩纹理, Android上面使用ETC1,苹果上面使用PVRTC。 UV坐标控制在0到1之间,人物模型面数控制在1500内,骨骼控制在30个以内。 场景中使用一个主光(不能再多了)。 尽量减少alphaTest和alphaBlend材质的使用。在手机上,这是很杀效率的。 骨骼动画方面: 在动画方面可以考虑不使用插值,固定的帧率的动画。 如果要做插值,考虑使用四元数(表示旋转)和向量(表示位移)来做插值。 四元数做插值速度比矩阵来的快,Slerp提供了平滑插值。 ========================================分割线==================================== 优化的常规技巧 网格 不要有不必要的网格。 光照 性能占用顺序:聚光灯>点光源>平行光。 点光源和聚光灯只影响它们范围内的网格。 贴图 不要使用低质量的图片。 Shaders ========================================分割线==================================== 在美术制作场景的过程中,会使用到大量的粒子系统。 unity中,在摄像机范围外的粒子系统虽然不会被绘制。 这个设计应该是很不合理的,在我看过的其他引擎中,都会有一个开关,来控制不可见的粒子系统是否需要update。 为了避免不必要的update开销,尤其是最后游戏是要发布到页游平台(web player只能使用一个cpu的核)。 该脚本主要是用到了2个MonoBehaviour的函数。 要这2个函数起作用的前提是,该GameObject绑定了MeshRender组件。 在Start() 的时候,把最GameObject的scale设置为很小,以保证该cube不被看见。 在OnBecameVisible 中 遍历所有child,把active设置为true。 ========================================分割线==================================== Unity 性能优化 Draw Call Unity(或者说基本所有图形引擎)生成一帧画面的处理过程大致可以这样简化描述:引擎首先经过简单的可见性测试,确定摄像机可以看到的物体,然后把这些物体的顶点(包括本地位置、法线、UV等),索引(顶点如何组成三角形),变换(就是物体的位置、旋转、缩放、以及摄像机位置等),相关光源,纹理,渲染方式(由材质/Shader决定)等数据准备好,然后通知图形API——或者就简单地看作是通知GPU——开始绘制,GPU基于这些数据,经过一系列运算,在屏幕上画出成千上万的三角形,最终构成一幅图像。 在Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw Call。这一过程是逐个物体进行的,对于每个物体,不只GPU的渲染,引擎重新设置材质/Shader也是一项非常耗时的操作。因此每帧的Draw Call次数是一项非常重要的性能指标,对于iOS来说应尽量控制在20次以内,这个值可以在编辑器的Statistic窗口看到。 Unity内置了Draw Call Batching技术,从名字就可以看出,它的主要目标就是在一次Draw Call中批量处理多个物体。只要物体的变换和材质相同,GPU就可以按完全相同的方式进行处理,即可以把它们放在一个Draw Call中。Draw Call Batching技术的核心就是在可见性测试之后,检查所有要绘制的物体的材质,把相同材质的分为一组(一个Batch),然后把它们组合成一个物体(统一变换),这样就可以在一个Draw Call中处理多个物体了(实际上是组合后的一个物体)。 但Draw Call Batching存在一个缺陷,就是它需要把一个Batch中的所有物体组合到一起,相当于创建了一个与这些物体加起来一样大的物体,与此同时就需要分配相应大小的内存。这不仅会消耗更多内存,还需要消耗CPU时间。特别是对于移动的物体,每一帧都得重新进行组合,这就需要进行一些权衡,否则得不偿失。但对于静止不动的物体来说,只需要进行一次组合,之后就可以一直使用,效率要高得多。 Unity提供了Dynamic Batching和Static Batching两种方式。Dynamic Batching是完全自动进行的,不需要也无法进行任何干预,对于顶点数在300以内的可移动物体,只要使用相同的材质,就会组成Batch。Static Batching则需要把静止的物体标记为Static,然后无论大小,都会组成Batch。如前文所说,Static Batching显然比Dynamic Batching要高效得多,于是,Static Batching功能是收费的…… 要有效利用Draw Call Batching,首先是尽量减少场景中使用的材质数量,即尽量共享材质,对于仅纹理不同的材质可以把纹理组合到一张更大的纹理中(称为Texture Atlasing)。然后是把不会移动的物体标记为Static。此外还可以通过CombineChildren脚本(Standard Assets/Scripts/Unity Scripts/CombineChildren)手动把物体组合在一起,但这个脚本会影响可见性测试,因为组合在一起的物体始终会被看作一个物体,从而会增加GPU要处理的几何体数量,因此要小心使用。 对于复杂的静态场景,还可以考虑自行设计遮挡剔除算法,减少可见的物体数量同时也可以减少Draw Call。 总之,理解Draw Call和Draw Call Batching原理,根据场景特点设计相应的方案来尽量减少Draw Call次数才是王道,其它方面亦然。 Draw Call Batching (绘制调用批处理) To draw an object on the screen, the engine has to issue a draw call to the graphics API (OpenGL ES in the case of iOS). Every single draw call requires a significant amount of work on the part of the graphics API, causing significant performance overhead on the CPU side. Unity combines a number of objects at runtime and draws them together with a single draw call. This operation is called "batching". The more objects Unity can batch together, the better rendering performance you will get. Built-in batching support in Unity has significant benefit over simply combining geometry in the modeling tool (or using theCombineChildren script from the Standard Assets package). Batching in Unity happensafter visibility determination step. The engine does culling on each object individually, and the amount of rendered geometry is going to be the same as without batching. Combining geometry in the modeling tool, on the other hand, prevents effecient culling and results in much higher amount of geometry being rendered. Materials If you have two identical materials which differ only in textures, you can combine those textures into a single big texture - a process often calledtexture atlasing. Once textures are in the same atlas, you can use single material instead. If you need to access shared material properties from the scripts, then it is important to note that modifyingRenderer.material will create a copy of the material. Instead, you should useRenderer.sharedMaterial to keep material shared. Dynamic Batching Dynamic batching is done automatically and does not require any additional effort on your side. Tips: 2、 If your shader is using Vertex Position, Normal and single UV, then you can batch up to 300 verts and if your shader is using Vertex Position, Normal, UV0, UV1 and 4、 Don't use scale. Objects with scale (1,1,1) and (2,2,2) won't batch. 5、 Uniformly scaled objects won't be batched with non-uniformly scaled ones. 6、 Using different material instances will cause batching to fail. 7、 Objects with lightmaps have additional (hidden) material parameter: offset/scale in lightmap, so lightmapped objects won't be batched (unless they point to same 8、 Multi-pass shaders will break batching. E.g. Almost all unity shaders supports several lights in forward rendering, effectively doing additional pass for them 9、 Using instances of a prefab automatically are using the same mesh and material. Static Batching Static batching, on the other hand, allows the engine to reduce draw calls for geometry of any size (provided it does not move and shares the same material). Static batching is significantly more efficient than dynamic batching. You should choose static batching as it will require less CPU power. In order to take advantage of static batching, you need explicitly specify that certain objects are static and willnot move, rotate or scale in the game. To do so, you can mark objects as static using the Static checkbox in the Inspector: Using static batching will require additional memory for storing the combined geometry. If several objects shared the same geometry before static batching, then a copy of geometry will be created for each object, either in the Editor or at runtime. This might not always be a good idea - sometimes you will have to sacrifice rendering performance by avoiding static batching for some objects to keep a smaller memory footprint. For example, marking trees as static in a dense forest level can have serious memory impact. Static batching is only available in Unity iOS Advanced. 备注:最近一直在研究Unity3D的性能优化问题,这段时间可能会多翻译这方面的文章。 前两天,MadFinger,就是当今iOS与Android上画质最牛逼闪闪的游戏之一——ShadowGun的开发商,令人惊异地放出了一个ShadowGun的样例关卡以及若干可免费使用的Shader,国外同行们的分享精神真的是令人赞叹不已。原文在这里,以下是我的一些摘录和笔记。 首先是一些优化常识。针对图形方面的优化主要包括三角形数量,纹理所占内存,以及Shader,前两项基本没什么好讲的,针对设备机能的限制制定相应的指标即可,所以Shader就成为了图形性能优化的关键。 Alpha blending 在Unity官方文档中讲,由于硬件原因,在iOS设备上使用alpha-test会造成很大的性能开销,应尽量使用alpha-blend代替。这里提到,在同屏使用alpha-blend的面数,尤其是这些面所占屏幕面积的大小,对性能也会造成很大影响。原因是使用alpha-blend的面会造成overdraw的增加,这尤其对低性能设备的影响很大。不过没有购买Pro版,没有Occlusion Culling功能的话,就不必顾虑这一问题了,反正overdraw是必然的。 复杂的Per-pixel shader Per-pixel shader即Fragment shader,顾名思义是要对每个渲染到屏幕上的像素做处理的shader,如果per-pixel shader比较复杂且需要处理的像素很多时,也就是使用该shader的面占屏幕面积很大时,对性能的影响甚至要超过alpha blending。因此复杂的per-pixel shader只适用于小物体。 下面是对几个Shader的逐一讲解: Environment specular maps(Shader Virtual Gloss Per Vertex Additive) 经过优化的动态角色光照和阴影(Light probes和BRDF Shader) Unity本身还提供了一个效果非常棒的专为移动设备优化过的角色Shader,支持Diffuse、Specular和Normal maps,并通过一个特殊的脚本生成贴图用于模仿BRDF光照效果。最终产生的效果堪比次时代大作中的角色光影效果。 雾和体积光(Shader Blinking Godrays) 使用这个Shader的网格需要经过处理: 顶点的alpha值用于决定顶点是否可以移动(在例子中0为不可动,1为可动)。 飞机坠毁的浓烟效果(Shader Scroll 2 Layers Sine Alpha-blended) 带动态效果的天空盒(Shader Scroll 2 Layers Multiplicative) 旗帜和衣服的飘动效果(Shader Lightmap + Wind) 一、程序方面 二、模型方面 三、其它 |
unity几种优化建议相关推荐
- Unity 几种优化建议
原文地址:http://www.narkii.com/club/thread-327263-1.html 最简单的优化建议: 1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于 ...
- Unity 优化建议
转 https://blog.csdn.net/game_jqd/article/details/51899000 使用Profiler工具分析内存占用情况 System.ExecutableAndD ...
- 【146期】面试官问:说一说 RabbitMQ 的几种工作模式和优化建议?
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方留言必回,有问必答! 每天 08:00 更新文章,每天进步一点点... 1.组 ...
- Unity MMORPG游戏优化经验分享
今天由Unity技术支持工程师高岩,根据实际的技术支持工作经验积累,分享如何对Unity MMORPG游戏进行优化. 在优化Unity游戏时,我们一般从四个方面:CPU.GPU.内存.工程配置等入手, ...
- Unity教程之再谈Unity中的优化技术
这是从 Unity教程之再谈Unity中的优化技术 这篇文章里提取出来的一部分,这篇文章让我学到了挺多可能我应该知道却还没知道的知识,写的挺好的 优化几何体 这一步主要是为了针对性能瓶颈中的" ...
- 移动游戏性能优化建议与字体剥离精简工具
/ 在 Unity 中制作游戏时对动态字体的剥离和精简是现在常用的手段,现在有两篇博客是大家阅读和参照较多的,分别是 如何精简Unity中使用的字体文件 和 FontPruner 字体精简工具.他们各 ...
- 【Unity技巧】Unity中的优化技术
写在前面 这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得的~Digital Tutors是一个非常棒的教程网站,包含了多媒体领域很多方面的资料,非常酷!除此之外,还参考了Un ...
- Unity中的优化技术
http://blog.csdn.net/candycat1992/article/details/42127811 写在前面 这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得 ...
- Dockerfile实践优化建议
本文讲的是Dockerfile实践优化建议[编者的话]Dockerfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令.Docke ...
最新文章
- shell中执行脚本并显示到终端和保存到日志文件中
- [New Portal]Windows Azure Virtual Machine (8) Virtual Machine高可用(上)
- U-Boot启动过程--详细版的完全分析
- SAP CRM WebClient UI的cross component navigation跳转
- Linux静默安装oracle
- 什么是类加载器?类加载器有哪些
- xml vs db.properties
- C#中采用OLEDB方式来读取EXCEL文件
- android 版本更新
- python 装饰器实现_Python学习之路:装饰器实现终极版
- PreparedStatement 防止 SQL 注入原理
- 读后感之悟道-一位20年IT高管的职场心得
- Elasticsearch Refresh vs Flush
- 什么是IT和什么是IT行业
- 超详细傻瓜iPhone自定义来电铃声教程
- 服务器数据库查看版本信息,查看服务器数据库版本号
- java 判断手机号_如何用java判断手机号运营商?
- ECIF OCRM ACRM
- 第二节 数据CRUD操作与连接查询和子查询(包含练习)
- 2066: 计算鸡的蛋II