【风宇冲】Unity3D性能优化:DrawCall优化

(2013-03-05 15:39:27)

原创文章如需转载请注明:转载自风宇冲Unity3D教程学院

            DrawCall优化
 
一 Mesh Renderer
二 Skinned Mesh Renderer
三 合并要求对比
四 总结
五 场景制作建议
 
DrawCall优化合并,也叫批处理,即DrawCall Batching. 通过减少Draw call数提高性能。
 
一 Mesh Renderer
分为Dynamic Batching和 Static Batching
Dynamic Batching
不需要任何操作,只要共享材质(即使是不同的Mesh模型也可以),就会自动被合并。可以自由移动旋转。但有以下使用要求:
(1)单个Mesh的vertex attribute总数不超过900.
即 vertex* attributeCount < 900
例如一个Mesh有pos,uv,normal,那么attributeCount为3,
也就是顶点数量不超过300个。
(2)游戏对象使用相同模型和材质时,只有相同缩放(即xyz等比缩放,浮点尾数可以有细微差)的会被合并。
(1,1,1)与(1,1,1)
(2,2,2)与(2,2,2)
(0.5,0.5,0.5)与 (0.5,0.5,0.5)
(2,2,2)与(2,2,2.0001)
(3)场景烘焙:烘焙后同材质将不会被烘焙。lightmap 有隐藏的材质参数:offset/scale, 所以使用lightmap的物体不会被合并
(4)Shader不能使用多Pass:多Pass的Shader会破坏Dynamic Batching
 
Static Batching
 
原理:
运行游戏后将一组游戏对象的多个模型会被动态合并为1个。这组游戏对象所有使用同一材质的在一个DrawCall来完成。这些游戏对象运行后无法移动缩放旋转。但是Drawcall一定是最大化合并的,并且不受动态合并的诸多限制(见下文详述)。
注意:即使物体都使用了同样的模型,在batch后每一个物体都会创建一份模型对应的geometry,在新的Combined Mesh里。所以过多的batch会增加内存占用。例如场景里的树群就不适合Static Batch,而适合动态合并。
实现方法:
(1)MeshRenderer勾选Batching Static: 勾了即可
(2)代码中使用UnityEngine.StaticBatchingUtility实现(可以在任何平台调用):
      1)将所有要合并的静态物体(不须勾Batching Static)放入统一一个root
      2)StaticBatchingUtility.Combine(root);
      之后就合并好了!
区别:
勾选Batching Static:
完全自动合并,在MeshFilter里显示的是 Combined Mesh(root:scene)。合并后不能移动
StaticBatchingUtility:
合并到一个游戏对象下。合并后可以移动父节点游戏对象
 
二 Skinned Mesh Renderer
Unity对Skinned Mesh Renderer没有任何batching, 但插件Mesh Baker可以对Skinned Mesh进行合并。
注意:
(1)修改Renderer.material将会创建一份新的material,应使用Renderer.sharedMaterial来保持材质公用。
(2)可以使用Mesh.Optimize() 优化模型。导入模型不需要调用此接口,在导入模型至Unity3d时已自动处理。
代码创建的模型有可能需要调用此接口来优化。
 
 
三 合并要求对比
要求    动态 静态
1 只能是MeshRenderer不能是SkinnedMeshRenderer 要求 要求
2 Shader必须是单Pass 要求 不要求
3 不能被场景烘焙(不能标注为Light map static) 要求 不要求
4 网格模型文件总点数要求 要求 不要求
5 网格模型单个文件点数要求 要求 不要求
6 限制缩放 要求 不要求
7 限制位移旋转 不要求 要求
 
另外Unity中任何Mesh的面 有65536的面数限制
 
四 总结
三种方式:
1 动态合并
    优点:
        内存消耗小
        可以自由位移旋转
    缺点:
        要求众多()
2 标记Light map static合并
    优点:
        最方便快捷,要求最少
    缺点:
        完全不能移动
        内存有消耗
        只能处理在Scene中默认放置的物体
3 代码StaticBatchingUtility合并
    优点:

        方便快捷,要求少
        可整体移动
        可处理代码动态加载的场景或物体
    缺点:
        内存有消耗
 
代码合并是要求最少的,并可以整体移动。而动态合并可以移动旋转,并做Animation动画。故推荐StaticBatchingUtility + 动态合并。
 

五 场景制作建议
美术人员在制作某场景时,尽量:
静态物体:使用静态合并
条件
   1 用Mesh Renderer,也就是不绑定骨骼
   2 不是Wrap循环UV的贴图,尽量合并到一张大图集
方法
   标注Batching Static即可
 
动态物体:使用动态合并,动画可以用Unity的动画去做
条件
   1 无骨骼
   2 不参与场景烘焙
   3 相同物体相同缩放
   4 单个Mesh的vertex attribute总数不超过900.
   5 Shader单Pass
方法
   满足条件Unity自动优化
(不满足动态合并要求的。场景动画可以用骨骼动画去做。但应尽量避免或者少的使用这种方式。因为没有Drawcall优化效率较低)

PS:
要关闭动态合并在subshader里加以下代码即可
Tags { "DisableBatching" = "true" }

如果是非Mobile端可以考虑使用GPU Instancing
如果是有超级多的人,可考虑使用顶点动画提高性能。

参考
Draw call batching

 

mesh合并的更多相关文章

  1. Unity3d mesh合并,网格合并具体用法教程

    Unity开发Mesh合并网格 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分 ...

  2. unity中的mesh合并

    在分析shadowgun时,无意中发现所有的环境建筑运行后,都被合并成一个叫做 "Combined Mesha (root: scene)" 的mesh了,但是没有发现任何合并的脚 ...

  3. Unity mesh 合并

    簡介: 基本上就是把 很多物體結合成一個物體 的作法,這種做法有很多優點,例如:1. 提高效能2. 統一材質 (只要建立一個材質,就能控制.分配給所有物體)3. 動畫控制方便 (像是你要在 Unity ...

  4. unity 合并skinnedMeshRenderer中遇到的一个大坑

    将多个skinnedMeshRenderer合并成一个skinnedMeshRenderer,主要涉及的mesh合并.骨骼列表合并.重定向顶点骨骼索引.其中重定向顶点骨骼索引只是通过加偏值即可完成,所 ...

  5. Unity 网格合并

    从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网格合并.材质合并.如果是人物的换装,那么需要合并SkinnedMeshRenderer, ...

  6. Unity网格合并_材质合并

    [转]Unity网格合并_材质合并 原帖请戳:Unity网格合并_材质合并 写在前面: 从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网 ...

  7. 【转】Unity网格合并_材质合并

    原帖请戳:Unity网格合并_材质合并 写在前面: 从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网格合并.材质合并.如果是人物的换装, ...

  8. unity3d android 优化

    最近项目进入收尾阶段,之前对项目做了很多优化,mesh合并 ,减少DrawCall和模型骨骼以及物理计算,合并材质球,优化代码等等,在IOS上还好,但是android上,试过几款手机,从低端到高端,发 ...

  9. Unity热门插件推荐

    前言 Unite2015的笔记 ,本文所提到的扩展主要针对 mobile上使用. 文中资源在Asset Store描述的截图日期:2016-04-28 Mesh Baker https://www.a ...

随机推荐

  1. Spring cloud开发内存占用过高解决方法

    https://blog.csdn.net/wanhuiguizong/article/details/79289986 版权声明:本文为博主原创文章,转载请声明文章来源和原文链接. https:// ...

  2. System.getSecurityManager()

    https://www.cnblogs.com/yiwangzhibujian/p/6207212.html java安全管理器SecurityManager入门   一.文章的目的 这是一篇对Jav ...

  3. 多选插件multiselect.js

    官方网址:http://loudev.com/ html: <html> <head> <link href="path/to/multiselect.css& ...

  4. Django后端项目----restful framework 认证源码流程

    一.请求到来之后,都要先执行dispatch方法,dispatch方法方法根据请求方式的不同触发get/post/put/delete等方法 注意,APIView中的dispatch方法有很多的功能 ...

  5. Qt QTextEdit根据行号移动光标

    QTextEdit* p = new QTextEdit; QTextBlock block = p->document()->findBlockByNumber(nLineNum); p ...

  6. MyEclipse配置默认自带的XML代码格式化

    1.XML中的注释保持原样,不格式化为一行(Join lInes)内

  7. 算法竞赛入门经典训练指南——UVA 11300 preading the Wealth

    A Communist regime is trying to redistribute wealth in a village. They have have decided to sit ever ...

  8. JavaScript笔记 #08# 用Regex辅助生成文章目录 V2.0

    索引 简介 测试用例 代码 简介 * 用Regex辅助生成文章目录 2.0 * 1.提高了功能的通用性(假定的文章格式更加普遍,即按照h2h3h4分级) * 2.改善了代码的可读性(稍微牺牲了一点点性 ...

  9. Eloquent JavaScript #02# program_structure

    第一章中作者介绍了各种值,但是这些独立的值是没有意义的,只有当值放在更大的框架的时候才会彰显它们的价值.所以第二章开始介绍程序结构. 1.var VS. let 以及 const 作者推荐用 let ...

  10. LNMP 添加 memcached服务

    LNMP 添加 memcached服务   由于memcached具有更多的功能和服务,已经不推荐使用memcache了.(缺少个字母d) 1. 首先安装memcached服务端. 这里使用yum源安 ...