unity3d 共享骨骼_unity3d骨骼怎么在3dmax - CSDN
  • 换材质,骨骼挂接,共享骨骼.用的比较多的是骨骼挂接和共享骨骼. 1.骨骼挂接 没有动作的骨骼挂接,适合武器. 有动作的骨骼挂接,适合坐骑. 2.共享骨骼 共享骨骼,适合身体部件.主模型(身体)包含整个骨骼,部件模型只包含...

    游戏的换装,一般分为3种.换材质,骨骼挂接,共享骨骼.用的比较多的是骨骼挂接和共享骨骼.

    1.骨骼挂接

    没有动作的骨骼挂接,适合武器.

    有动作的骨骼挂接,适合坐骑.

    2.共享骨骼

    共享骨骼,适合身体部件.主模型(身体)包含整个骨骼,部件模型只包含自己部分的骨骼,应用的时候,部件模型的骨骼共享主模型的骨骼.这样的话,只需要播放主模型的动画,部件会跟着动.

    Unity的换装呢,你要百度一下,能搜出一堆文章,方法也是多种多样.有参考价值的却不多.

    比如主流推荐的官方demo提供的换装方式.合并mesh,多此一举又麻烦.

    比如avatar的方式 ...不适合Legacy动画

    其实用以前端游的方式,共享骨骼就行了,Ogre引擎直接提供函数OGRE::shareSkeletonInstanceWith()来实现.而Unity引擎没有这个函数,怎么办呢,自己写一个呗.命名我也取一样的,表示对Unity自己不封装这个函数的鄙视.

            // 共享骨骼
            public static void ShareSkeletonInstanceWith(SkinnedMeshRenderer selfSkin, GameObject target)
            {
                Transform[] newBones = new Transform[selfSkin.bones.Length];
                for (int i = 0; i < selfSkin.bones.GetLength(0); ++i)
                {
                    GameObject bone = selfSkin.bones[i].gameObject;
                    // 目标的SkinnedMeshRenderer.bones保存的只是目标mesh相关的骨骼,要获得目标全部骨骼,可以通过查找的方式.
                    newBones[i] = FindChildRecursion(target.transform, bone.name);
                }
                selfSkin.bones = newBones;   
            }
    
            // 递归查找
            public static Transform FindChildRecursion(Transform t, string name)
            {
                foreach (Transform child in t)
                {
                    if (child.name == name)
                    {
                        return child;
                    }
                    else
                    {
                        Transform ret = FindChildRecursion(child, name);
                        if (ret != null)
                            return ret;
                    }
                }
                return null;
            }

    代码很简单,原理我再结合Unity仔细分析下.

    第一步 :

    假设整个模型分两部分,身体和翅膀,身体作为主模型,翅膀作为部件模型,身体30根骨骼,翅膀6根骨骼,总数量36根骨骼.

    1.导出身体模型的时候,选中身体和整个骨骼(注意是整个骨骼),这样身体也包含了翅膀的骨骼.

    2.导出翅膀模型的时候,选中翅膀和翅膀骨骼(翅膀不用导整个骨骼).

    第二步:

    模型有哪些骨骼,可以放入Unity查看root下面的节点 ,这里有个注意的地方,通过SkinnedMeshRenderer.bones查看的骨骼数量总是比通过root节点查看的数个数量少,因为SkinnedMeshRenderer.bones保存的模型真正用到的骨骼,而不是整个骨骼,比如身体模型的SkinnedMeshRenderer.bones只有30,而不是36.

    第三步:

    平级挂接2个模型到同一个父节点下测试,播放身体模型的动画,身体会动,翅膀不会,很正常,因为动的是身体模型的骨骼,翅膀模型的骨骼根本就没动.接下来把翅膀模型的6个骨骼设置成身体模型对应的那6个骨骼的transform,再播放,就发现翅膀也跟着动了,所谓共享,就是对应的把自己的骨骼设置成目标的骨骼.

    函数调用很简单 ShareSkeletonInstanceWith(翅膀, 身体)

    展开全文
  • 1) 导出资源时,只导出一个文件,保留模型,骨骼和所有的动作帧(把所有的动作,比如idle,attack,hit等等全部做成一个长动画),导出之后,放 入unity3d,在project 窗口中选中FBX文件,在Inspector 窗口中,找到...
     
    1.首先,Unity3d 中,导出带动画的资源有2种导出方式可以选择:
       1) 导出资源时,只导出一个文件,保留模型,骨骼和所有的动作帧(把所有的动作,比如idle,attack,hit等等全部做成一个长动画),导出之后,放 入unity3d,在project 窗口中选中FBX文件,在Inspector 窗口中,找到Split Animations选项,在该子选项下,拆分整个长动作为数个子动作。
            
       2) 导出的资源是分成模型,和多个动作的文件。一个FBX是模型,其他的是动作文件。导出模型时候,删除所有的动画,注意,是删除所有的动画哦,连T-POS 都要删掉,然后导出成一个FBX文件。这个FBX就是模型资源。然后同样的max资源,把其中的模型删除,保留骨骼和其中某一段动作,比如idle的30 帧,删除其他的动作帧,然后再导出成一个FBX,这个FBX就是该骨骼的一个动作。
     
     
          注意,动作文件是跟着骨骼走的,相同的骨骼可以使用同一个动作资源。一般项目中,同职业啊,或者同种族等,男生一套骨骼,女生一套骨骼,这样动作资源就共享了。
     
    方法一的优缺点:
    优点:操作简单,美术操作起来不易出错。
            如果项目中,不需要游戏中切换动画,比如只有一个人,而且不需要后期更新。那么这么做比方法2省掉了每个动作中的骨骼大小
    缺点:不灵活,单个资源太大,更新,修改,和加载都是问题
     
    方法二的优缺点:
    优点:组合方式灵活,单个资源控制到很小,加载,更新,修改的代价都很小。而且如果项目中,角色非常多,而         且这些角色是相同的骨骼,那么动作文件就全部可以共享。和方法1相比,改一个动作只需要更新一个小小的动作FBX文件,而上面的方式,需要更新所有的角色的所有FBX文件。
    缺点:导出操作复杂,美术操作易出错
            如果项目中,不需要游戏中切换动画,比如只有一个人,而且不需要后期更新。那么这么做比下面的方法省   掉了每个动作中的骨骼大小
     
     
    2.各种设置
      1.Bake Animation
         Bake Animation 要勾选上
      2.Curve Filters 勾选上
      3.Constant Key Reducer 勾选上
        动画的制作一般分为手K,和真人动作捕捉,前者一般是动画师手动可以控制每秒帧的数目(一般30帧每秒),倒出来的资源大小还是比较合适的,《忍》就属于这样的项目。这样在美术们导出动作文件时,可以不,用选择Reducer,但是跳舞项目中,动作是真人捕捉的,不勾选一套动画导出有8M,勾选上之后立马编程2M,然后根据美术的要求适当的调高Reducer下面的4个滑条。
        动画帧是记录的是每一帧骨骼的位移啊。旋转等等信息。当本帧的位置,和上一帧的位置差小于Translation Precision的大小。那么就删掉这个关键帧,同理其他的3个就是旋转,缩放和其他(比如顶点动画等)。
      4.Cameras 不勾选
      5.Light 不勾选 
      6.要导出贴图和材质,需要勾选Embed Media 

     

     
     

    转载于:https://www.cnblogs.com/colourstar/p/7872630.html

    展开全文
  • Unity3D性能优化--- 收集整理的一堆 官方优化文档--优化图像性能 http://docs.unity3d.com/Documentation/Manual/OptimizingGraphicsPerformance.html Unity3D性能优化专题 性能优化是一个异常繁琐而又涉及到...


    官方优化文档--优化图像性能
    http://docs.unity3d.com/Documentation/Manual/OptimizingGraphicsPerformance.html

    Unity3D性能优化专题
    性能优化是一个异常繁琐而又涉及到项目开发的方方面面的一个过程,它的本质是在运行时的一个时间里尽可能完美展现丰富的内容。
    实现优化可以通过优化资源、渲染、粒子、物理等模式;
    也可以通过修改模型大小、减少纹理尺寸并结合Unity3D的一些相关特性来提升游戏的性能。
    随着移动端的设备硬件能力的提升,如何使用尽可能优化的资源和程序效率来展现出更多的细节内容就成为了每个开发者都应该思考的内容,这也使得优化变成了项目开发中非常重要的一环。
    ***********
    首先介绍下draw call(这个东西越少你的游戏跑的越快):
    在游戏中每一个被展示的独立的部分都被放在了一个特别的包中,我们称之为“描绘指令”(draw call),然后这个包传递到3D部分在屏幕上呈现出来。这就和你希望你的亲友收到准备好的圣诞礼物需要包装好然后穿过城市准时放在他应该出现的地方一样没什么不同。你的CPU来完成包装和传递他们的活,同时会消耗很多的带宽,所以最终分配好这些关键性资源很重要。目前,真正可怕的事情是从描绘指令消耗远景开始,每一个独立的飞溅到地板上的血迹和一个角色或者一具死尸消耗的字节是一样的多的:他们都消耗同样的描绘指令。除此之外,没有什么更多的差别。
    那么如何降低 draw call 呢??那么我们就用到Culling(剔除)技术。如果不应用这个技术,电脑是不管3721把场景里所有的东西都送去渲染的。看得见的也渲染,看不见得照样也送去渲染。很傻是吧,那咋办呢。得告诉电脑,那个你
    看得见的渲染,看不见的就算了。于是就有了
    1.视锥体剔除(Frustum Culling)这个unity系统自带了好像,就不用操心了。
    2.遮挡剔除(Occlusion Culling)
    Unity 3专业版内置了一个强大的 Occlusion Culling 插件 Umbra免费的
    遮挡剔除(Occlusion Culling)
    遮挡剔除是一种什么样的特性呢, 当一个物体被其他物体遮挡住而不在摄像机的可视范围内时不对其进行渲染。. 遮挡剔除在3D图形计算中并不是自动进行的。因为在绝大多数情况下离 camera 最远的物体首先被渲染,靠近摄像机的物体后渲染并覆盖先前渲染的物体(这被称为重复渲染,无效渲染"overdraw"). 遮挡剔除不同于视锥体剔除. 视锥体剔除只是不渲染摄像机视角范围外的物体而对于被其他物体遮挡但依然在视角范围内的物体则不包括在内. 注意当你使用遮挡剔除时你依然受益于视锥体剔除(Frustum Culling).
    ***********
    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时间。特别是对于移动的物体,每一帧都得重新进行组合,这就需要进行一些权衡,否则得不偿失。但对于静止不动的物体来说,只需要进行一次组合,之后就可以一直使用,效率要高得多。 - See more at: http://ravenw.com/blog/2011/10/14/unity-optimization-of-draw-call/#sthash.0WfH4KnX.dpuf
    ***********

    输出设置相关:
    1:最终输出的时候,在unity - edit - project setting - player 里, 把 other settings - script call optimization 改成 快速, 但没有例外. fast but no exceptions
    2: unity - edit - project setting - time 里, 把 maximum allowed timestep 改成0.1
    3:

    常规优化
    1: 联结(combine)优化
    显卡对于一个含100个面片的物体的和含1500个面片的物体的渲染消耗几乎是等价的。所以如果你有N个同一材质的东西,那么把他们联成同一个物体再统一用一个material那么对于显卡的渲染消耗就要降低N倍。
    在unity里再联结,这个要怎么做呢,其实也挺简单的,经常看Island Demo项目的人应该很早就注意到里面的石头这些都是连在一起的,原因就在这里,他提供了现成就脚本实现联结。
    先到Island Demo的Assets/Script下找到CombineChildren.cs和MeshCombineUtility.cs两个脚本复制到自己的项目文件(我们要用的只是前者,但他会调用后者,没有后者unity会报错,所以把后者扔到项目里不管就好)
    然后把你项目里那些用同一Materials的东西扔到一个空物体里面去,再把CombineChildren.cs贴到那个空物体上,搞定!
    2: 模型
    (1)只用一个mesh renderer, 少用多materials, 最多3个
    每个角色尽量使用一个 Skinned Mesh Renderer
    这是因为当角色仅有一个 Skinned Mesh Renderer 时, Unity 会 使用可见性裁剪和包围体更新的方法来优化角色的运动,而这种优化只有在角色仅含有一个 Skinned Mesh Renderer 时才会启动。
    (2)模型骨骼不超过30个.
    (3)尽量减少面 300-1500
    (4)模型尽量不要分开, 如果多个模块, 会多次调用dc
    (5)一般角色应该没有 IK 结点
    这是因为角色的动作大多数都是事先设定好的,并不需要经过 IK 操作来进行实时计算( Rogdoll 除外),所以在模型导入时,不要将 IK 结点一起导入。
    (6) 不要附加 Animation Component 在静态实体上附加 Animation 部件虽然对结果没有影响,但却会增加一定的 CPU 开销来调用这一组件,所以尽量去掉该组件。

    3:尽量不用像素光(pixels Lights)
    4:不用 软阴影(soft shadow), 或者不用阴影(No Shadows)
    灯光能不用就不用, 阴影可以用面来代替.
    5:少用实时灯光, 尽量使用lightmap
    http://blog.sina.com.cn/s/blog_409cc4b00100no8y.html
    动态实时灯光相比静态灯光,非常耗费资源。所以除了能动的角色和物体(比如可以被打的到处乱飞的油桶)静态的地形和建筑,通通使用Lightmap。
    强大的Unity内置了一个强大的光照图烘焙工具Beast,这个东东是Autodesk公司的产品
    6:transform和OnGUI (运算上的优化远比不上 绘制效率上的优化,少个dc可能就比得上这些了)
    http://fredxxx123.wordpress.com/2013/05/22/unity%E6%80%A7%E8%83%BD%E5%84%AA%E5%8C%96%E4%B9%8B%E5%B0%8F%E6%B8%AC%E8%A9%A6/
    // transfrom
    少用transform, 多用 myCachedTransform
    頻繁使用該物件的地方,就是先把該物件cache起來,理論上就會避免這種不必的開銷。
    ※這也可延伸至其他是property的變數。例如:transform.position。
    ***直接使用的版本:
    public class TestUnit : MonoBehaviour
    {
    void Update()
    {
    var t = this.transform;
    t = this.transform;
    t = this.transform;
    t = this.transform;
    t = this.transform;
    }
    }
    ***cache 使用的版本:
    public class TestUnit : MonoBehaviour
    {
    Transform myTransform;
    void Start()
    {
    myTransform = transform;
    }

    void Update ()
    {
    var t = this.myTransform;
    t = this.myTransform;
    t = this.myTransform;
    t = this.myTransform;
    t = this.myTransform;
    }
    }
    // OnGUI
    空物件版本:
    public class TestUnit : MonoBehaviour
    {
    }
    外加一個空白OnGUI的版本:
    public class TestUnit : MonoBehaviour
    {
    void OnGUI()
    { }
    }
    實際上是被GUI.Begin()和GUI.End()所佔據,function本身是無辜的~~
    非必要避免使用OnGUI(),即使它裡面甚麼事情都沒做!
    如需使用,請盡可能集中到同一個OnGUI()底下執行繪製,好避免Begin End的開銷。

    7:动态物体的相关优化

    优化主要分为两个方向,一个是资源相关优化和引擎相关的优化。资源相关的优化,大概分为动态物体、静态物体、纹理数据、音频数据、程序包数据。对于动态物体比如NPC、怪物等,需要对面片数量的控制,大概在300到2000面。1500面就可以体现人物细节,但如果是人物比较多,可能要降低面数,不要低于300。另外,一方面是控制Skinned Mesh Renderer的数量;另一方面是控制材质数量在1到3种。人物最好用小于30根骨骼,如果你用的骨骼越多,耗费的CPU就更多,所以在移动平台上尽量少于30根。现在我们看其他动态物体,利用Dynamic Batching进行合批。这个下雨特效并不是系统做的,是包含很多雨点的网格进行重复拷贝,然后错乱移动实现的。每一个雨点并不是一个粒子,这样能减少很多CPU的消耗,每一个整体网格都会有一个顶点的控制,通过控制顶点数量,对系统实现雨点效果来说,这是一个相当省时省力的方法。

    8:静态物体的相关优化

    下面我们来看静态物体,静态物体也是要控制面数和顶点数,顶点数少于500个。static是不会进行移动缩放、旋转的,把它标记为static,当然他们的材质是一样的。不要添加animation组建,对于静态物体来说,这个组件毫无意义,能把他丢掉就丢掉,因为这对CPU的消耗是非常客观的。
    9:音频程序的优化
    关于音频时间的播放,比如背景音乐,建议使用MP3压缩格式,比如音效,要求数据尽快加载,这些数据比较小就可以,使用WAV和AIF未压缩音频格式。关于程序包的优化,很多开发者会埋怨说打出来的包太大,现在介绍减少程序包的方法,首先使用压缩格式的纹理,以显卡的压缩格式保存,使用压缩网格和动画数据。网格压缩是先采用量化处理,当然这个压缩是保证在包里面的数据小,但运行时占用的内存没有减少,因为我们并没有把顶点删除,但是对动画数据来说,动画数据经过压缩处理后降低,可以减少游戏列层。

    关于代码尽量不要使用System.xml,我们建议使用Mono.xml。启用Stripping来减少库的大小,使用剥离方式。

    10:引擎相关优化和物理相关优化
    下来是引擎相关的优化,例如光照设置、相继设置、粒子特效、物理特效等。那拿光照设置来说,光源全部的实时光照这是很恐怖的,每一次实施光照代表着每一次使用消耗,怎么优化?有人使用LightMapping来制作静态场景,他的好处是不需要用多张实施光照,而给场景很好的光照效果。有人使用Light Probes代替实时光照,好处是完全不用怎么消耗,而且运作性能也非常高。在有些时候使用Light Probes代替光照,他能跟场景很好的融合,在一个角落里,这个任务会被阴影打得暗一些。如果说场景中确实需要一些实时光源,那么肯定是需要做过优化设置的实时光源,控制important的光源个数。如果说光源有些地方产生了交叉光,这个时候你可以通过设置Pxel Light,控制每一个光源都只接受一个动态光照,数目大概是1—2个。对于关闭光源的实时阴影,并不是所有平台都支持实时阴影,消耗也非常大,不建议大家使用。关于相机方面的设置,平面越近,渲染越少。我们更建议使用分层,比如远处的建筑,对于建筑物的裁减平面远一些,如果是花草,就可以使用平面就近一些。现在看一下粒子特效,粒子也是游戏中需要优化的东西,建议屏幕中最大的粒子数不要超过200,同时每个发射器发射的最大粒子数不要超过50。粒子尺寸也要尽可能小,最终在屏幕有多少像素。他们中间的像素可能会被渲染很多次,至少四五次,这时发现粒子系统仅像素就填充了更多屏幕,这时候对游戏来说非常耗费,对游戏的其他功能性能也有所影响。另外一方面,对于非常小的粒子,尽量不要开启粒子碰撞功能。

    现在我们看一下物理相关优化,物理尽可能使用Sphere Coillider、Box Coillider等,尽量避免使用Meh Colllider等。渲染设置,避免使用Alpha Test,因为非常耗时,性价比很低。关于Sttic Batching,对静态物体进行Batch,对几何数据的大小没有限制。物体被合并后会带来一些内存消耗,比如说有控制网格的物体,用Batch会合并成大物体。Dynamic Batching目前仅支持小于900顶点的网格物体。如何理解900呢,其实就相当于900个顶点数据大小的物体,如果说使用Position、Normal和UV三种属性,那么你只能Batch300个顶点。整体缩放的物体不能被Batch,除非他们的缩放值相同。之前有一个客户做特效,使用Batch机制把面片合并,最终让所有面片共享一个纹理,这时候发现这些面片没有被Batch出来,导致运行游戏时大概放三个技能就10多个招套。对于非整体用户体,他们的Batch是需要很好利用到。

    11:纹理合并优化
    现在来看纹理合并,纹理合并就是为了特到Batch数量,合并物体首先需要合并工具,还要修改使用纹理的网格的UV,使他们使用纹理。合并纹理主要是参照Batch,提高渲染性能。但在合并材质后需要注意的是脚本访问Renderer被拷贝。/*安挡剔除,建议使用PVS技术。建议大家使用自定义shader,例如高光效果,高光效果可能不需要做一些入射线的检测,只是简单把他的值放大也可以模拟高光效果,从而减少一些消耗。
    另外一个是用profiler,通过他给的数据进行针对性的优化。以上是跟大家介绍优化的内容,如何作出良好优化,一定要做好良好的规划,到后期就不会很麻烦,如果规划没有做好有可能会给程序带来很大压力,结果可能很不乐观。*/最后,要不断实验不断总结才能达到自己满意的效果。

    12:
    要想降低Drawcal的话,有如下两点小建议
    (1)不要用Unity自带UI或者iGUI, 用NUI 或者EZ GUI
    (2)创建好的GameObject不用了就最好及时 删除 / 设置active为false/移出屏幕 。 这几种方法都可以去掉该物体导致增加的Drawcall

    13:

    *********************************
    *********************************
    *********************************
    最近一段时间一直在做Unity 在IOS设备上的资源优化,结合Unity的官方文档以及自己遇到的实际问题,我把自己认为一些重要的信息罗列在下面,并尽可能对将其量化,以方便更多需要做优化的朋友。
    1、 角色
    每个角色尽量使用一个 Skinned Mesh Renderer
    这是因为当角色仅有一个 Skinned Mesh Renderer 时, Unity 会 使用可见性裁剪和包围体更新的方法来优化角色的运动,而这种优化只有在角色仅含有一个 Skinned Mesh Renderer 时才会启动。
    角色 Material 数量
    2-3 个
    骨骼数量
    小于 30 个
    面片数量
    300-1500
    一般角色应该没有 IK 结点
    这是因为角色的动作大多数都是事先设定好的,并不需要经过 IK 操作来进行实时计算( Rogdoll 除外),所以在模型导入时,不要将 IK 结点一起导入。
    2、 静态实体
    不要附加 Animation Component
    在静态实体上附加 Animation 部件虽然对结果没有影响,但却会增加一定的 CPU 开销来调用这一组件,所以尽量去掉该组件。
    网格顶点数
    小于 500
    UV 值范围尽量不要超过( 0, 1 )区间
    尽量保证 UV 值不越界,这对于将来的纹理拼合优化很有帮助。
    3、 地形
    地形的分辨率大小
    长宽均尽量小于 257 。这是因为地形太大,会造成大量顶点数据,给你的内存带宽造成一定的影响,在目前的 ios 设备中,内存带宽是非常有限的,需要尽量节省。同时,如果用 Unity 自带的地形,一定也要使用 Occlusion Culling ,因为 Unity 的刷地形工具虽然方便,但却是 framekiller ,刷过之后,你会发现 drawcall 增加的非常多。
    混合纹理数量
    不要超过 4 。地形的混合操作是很耗时的,应该尽量避免。能合并的纹理尽量合并。
    4、 纹理
    纹理格式
    建议 png 或 tga 。不用转成 ios 硬件支持的 PVRTC 格式,因为 Unity 在发布时会帮你自动转的。
    纹理尺寸
    长宽小于 1024 。同时应该尽可能地小,够用就好,以保证纹理对内存带宽的影响达到最小。
    支持 Mipmap
    建议生成 Mipmap 。虽然这种做法会增加一些应用程序的大小,但在游戏运行时,系统会根据需求应用 Mipmap 来渲染,从而减少内存带宽。
    检查 Alpha 值
    如果纹理的 alpha 通道均为 1 ,则用 RGB 的 24 位纹理来代替 RGBA 的 32 位纹理。(据说 Unity 内部会进行自动检测)
    5、 光源
    光源“ Important ”个数
    建议 1 个,一般为方向光。“ Important ”个数应该越小越少。个数越多, drawcall 越多。
    Pixel Light 数目
    1-2 个。
    6、 粒子特效
    屏幕上的最大粒子数
    建议小于 200 个粒子。
    每个粒子发射器发射的最大粒子数
    建议不超过 50 个。
    粒子大小
    如果可以的话,粒子的 size 应该尽可能地小。因为 Unity 的粒子系统的 shader 无论是 alpha test 还是 alpha blending 都是一笔不小的开销。同时,对于非常小的粒子,建议粒子纹理去掉 alpha 通道。
    尽量不要开启粒子的碰撞功能。
    非常耗时。
    7、 音频
    游戏中播放时间较长的音乐(如背景音乐)
    使用 .ogg 或 .mp3 的压缩格式。
    较短音乐(如枪声)
    使用 .wav 和 .aif 的未压缩音频格式。
    8、 相机
    裁剪平面
    将远平面设置成合适的距离。远平面过大会将一些不必要的物体加入渲染,降低效率。
    根据不同的物体设置不同的远裁剪平面
    Unity 提供了可以根据不同的 layer 来设置不同的 view distance ,所以我们可以实现将物体进行分层,大物体层设置的可视距离大些,而小物体层可以设置地小些,另外,一些开销比较大的实体(如粒子系统)可以设置得更小些等等。
    9、 碰撞
    尽量不用 MeshCollider
    如果可以的话,尽量不用 MeshCollider ,以节省不必要的开销。如果不能避免的话,尽量用减少 Mesh 的面片数,或用较少面片的代理体来代替。
    10、 其他
    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 。
    展开全文
  • unity3d 各种优化综合

    2014-09-15 14:49:24
    [基础知识]Unity3d优化与检测方式   本帖最后由 诸葛高原 于 2014-5-21 11:34 编辑  检测方式:  一,unity3d 渲染统计窗口  Game视窗的Stats去查看渲染统计的信息: ...
     



      检测方式:

      一,unity3d 渲染统计窗口

      Game视窗的Stats去查看渲染统计的信息:

      1、FPS

      fps其实就是 frames per second,也就是每一秒游戏执行的帧数,这个数值越小,说明游戏越卡。

      2、Draw calls

      batching之后渲染mesh的数量,和当前渲染到的网格的材质球数量有关。

      3、Saved by batching

      渲染的批处理数量,这是引擎将多个对象的绘制进行合并从而减少GPU的开销;

      很多GUI插件的一个好处就是合并多个对象的渲染,从而降低DrawCalls ,保证游戏帧数。

      4、Tris 当前绘制的三角面数

      5、Verts 当前绘制的顶点数

      6、Used Textures 当前帧用于渲染的图片占用内存大小

      7、Render Textures 渲染的图片占用内存大小,也就是当然渲染的物体的材质上的纹理总内存占用

      8、VRAM usage 显存的使用情况,VRAM总大小取决于你的显卡的显存

      9、VBO Total 渲染过程中上载到图形卡的网格的数量,这里注意一点就是缩放的物体可能需要额外的开销。

      10、Visible Skinned Meshes 蒙皮网格的渲染数量

      11、Animations 播放动画的数量

      注意事项:

      1,运行时尽量减少 Tris 和 Draw Calls

      预览的时候,可点开 Stats,查看图形渲染的开销情况。特别注意 Tris 和 Draw Calls 这两个参数。

      一般来说,要做到:

      Tris 保持在 7.5k 以下,有待考证。

      Draw Calls 保持在 20 以下,有待考证。

      2,FPS,每一秒游戏执行的帧数,这个数值越小,说明游戏越卡。

      3,Render Textures 渲染的图片占用内存大小。

      4,VRAM usage 显存的使用情况,VRAM总大小取决于你的显卡的显存。

      二,代码优化

      1. 尽量避免每帧处理

      比如:

      function Update() { DoSomeThing(); }

      可改为每5帧处理一次:

      function Update() { if(Time.frameCount % 5 == 0) { DoSomeThing(); } }

      2. 定时重复处理用 InvokeRepeating 函数实现

      比如,启动0.5秒后每隔1秒执行一次 DoSomeThing 函数:

      function Start() { InvokeRepeating(“DoSomeThing”, 0.5, 1.0); }

      3. 优化 Update, FixedUpdate, LateUpdate 等每帧处理的函数

      函数里面的变量尽量在头部声明。

      比如:

      function Update() { var pos: Vector3 = transform.position; }

      可改为

      private var pos: Vector3; function Update(){ pos = transform.position; }

      4. 主动回收垃圾

      给某个 GameObject 绑上以下的代码:

      function Update() { if(Time.frameCount % 50 == 0) { System.GC.Collect(); } }

      5. 优化数学计算

      比如,如果可以避免使用浮点型(float),尽量使用整形(int),尽量少用复杂的数学函数比如 Sin 和 Cos 等等

      6,减少固定增量时间

      将固定增量时间值设定在0.04-0.067区间(即,每秒15-25帧)。您可以通过Edit->Project Settings->Time来改变这个值。这样做降低了FixedUpdate函数被调用的频率以及物理引擎执行碰撞检测与刚体更新的频率。如果您使用了较低的固定增量时间,并且在主角身上使用了刚体部件,那么您可以启用插值办法来平滑刚体组件。

      7,减少GetComponent的调用

      使用 GetComponent或内置组件访问器会产生明显的开销。您可以通过一次获取组件的引用来避免开销,并将该引用分配给一个变量(有时称为“缓存”的引用)。例如,如果您使用如下的代码:

    [AppleScript] 纯文本查看 复制代码
      function Update () {
    
      transform.Translate(0, 1, 0);
    
      }


      通过下面的更改您将获得更好的性能:

    [AppleScript] 纯文本查看 复制代码
      var myTransform : Transform;
    
      function Awake () {
    
      myTransform = transform;
    
      }
    
      function Update () {
    
      myTransform.Translate(0, 1, 0);
    
      }


      8,避免分配内存

      您应该避免分配新对象,除非你真的需要,因为他们不再在使用时,会增加垃圾回收系统的开销。您可以经常重复使用数组和其他对象,而不是分配新的数组或对象。这样做好处则是尽量减少垃圾的回收工作。同时,在某些可能的情况下,您也可以使用结构(struct)来代替类(class)。这是因为,结构变量主要存放在栈区而非堆区。因为栈的分配较快,并且不调用垃圾回收操作,所以当结构变量比较小时可以提升程序的运行性能。但是当结构体较大时,虽然它仍可避免分配/回收的开销,而它由于“传值”操作也会导致单独的开销,实际上它可能比等效对象类的效率还要低。

      9,使用iOS脚本调用优化功能

      UnityEngine 命名空间中的函数的大多数是在 C/c + +中实现的。从Mono的脚本调用 C/C++函数也存在着一定的性能开销。您可以使用iOS脚本调用优化功能(菜单:Edit->Project Settings->Player)让每帧节省1-4毫秒。此设置的选项有:

      Slow and Safe – Mono内部默认的处理异常的调用

      Fast and Exceptions Unsupported –一个快速执行的Mono内部调用。不过,它并不支持异常,因此应谨慎使用。它对于不需要显式地处理异常(也不需要对异常进行处理)的应用程序来说,是一个理想的候选项。

      10,

      优化垃圾回收

      如上文所述,您应该尽量避免分配操作。但是,考虑到它们是不能完全杜绝的,所以我们提供两种方法来让您尽量减少它们在游戏运行时的使用:

      如果堆比较小,则进行快速而频繁的垃圾回收

      这一策略比较适合运行时间较长的游戏,其中帧率是否平滑过渡是主要的考虑因素。像这样的游戏通常会频繁地分配小块内存,但这些小块内存只是暂时地被使用。如果在iOS系统上使用该策略,那么一个典型的堆大小是大约 200 KB,这样在iPhone 3G设备上,垃圾回收操作将耗时大约 5毫秒。如果堆大小增加到1 MB时,该回收操作将耗时大约 7ms。因此,在普通帧的间隔期进行垃圾回收有时候是一个不错的选择。通常,这种做法会让回收操作执行的更加频繁(有些回收操作并不是严格必须进行的),但它们可以快速处理并且对游戏的影响很小:

    [AppleScript] 纯文本查看 复制代码
      if (Time.frameCount % 30 == 0)
    
      {
    
      System.GC.Collect();
    
      }


      但是,您应该小心地使用这种技术,并且通过检查Profiler来确保这种操作确实可以降低您游戏的垃圾回收时间

      如果堆比较大,则进行缓慢且不频繁的垃圾回收

      这一策略适合于那些内存分配 (和回收)相对不频繁,并且可以在游戏停顿期间进行处理的游戏。如果堆足够大,但还没有大到被系统关掉的话,这种方法是比较适用的。但是,Mono运行时会尽可能地避免堆的自动扩大[url=http://www.unitymanual.com/forum-develop-1.html]unity 3d开发心得[/url] 因此,您需要通过在启动过程中预分配一些空间来手动扩展堆(ie,你实例化一个纯粹影响内存管理器分配的“无用”对象):

    [AppleScript] 纯文本查看 复制代码
      function Start() {
    
      var tmp = new System.Object[1024];
    
      // make allocations in smaller blocks to avoid them to be treated in a special way, which is designed for large blocks
    
      for (var i : int = 0; i < 1024; i++)
    
      tmp[i] = new byte[1024];
    
      // release reference
    
      tmp = null;
    
      }


      游戏中的暂停是用来对堆内存进行回收,而一个足够大的堆应该不会在游戏的暂停与暂停之间被完全占满。所以,当这种游戏暂停发生时,您可以显式请求一次垃圾回收:

      System.GC.Collect();

      另外,您应该谨慎地使用这一策略并时刻关注Profiler的统计结果,而不是假定它已经达到了您想要的效果。

      三,模型

      1,压缩 Mesh

      导入 3D 模型之后,在不影响显示效果的前提下,最好打开 Mesh Compression。

      Off, Low, Medium, High 这几个选项,可酌情选取。

      2,避免大量使用 Unity 自带的 Sphere 等内建 Mesh

      Unity 内建的 Mesh,多边形的数量比较大,如果物体不要求特别圆滑,可导入其他的简单3D模型代替。
            游戏蛮牛:http://www.unitymanual.com






    最简单的优化建议:

    1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与CPU。
    2.如果你用U3D自带的SHADER,在表现不差的情况下选择Mobile或Unlit目录下的。它们更高效。
    3.尽可能共用材质。
    4.将不需要移动的物体设为Static,让引擎可以进行其批处理。
    5.尽可能不用灯光。
    6.动态灯光更加不要了。
    7.尝试用压缩贴图格式,或用16位代替32位。
    8.如果不需要别用雾效(fog)
    9.尝试用OcclusionCulling,在房间过道多遮挡物体多的场景非常有用。若不当反而会增加负担。
    10.用天空盒去“褪去”远处的物体。
    11.shader中用贴图混合的方式去代替多重通道计算。
    12.shader中注意float/half/fixed的使用。
    13.shader中不要用复杂的计算pow,sin,cos,tan,log等。
    14.shader中越少Fragment越好。
    15.注意是否有多余的动画脚本,模型自动导入到U3D会有动画脚本,大量的话会严重影响消耗CPU计算。
    16.注意碰撞体的碰撞层,不必要的碰撞检测请舍去。


    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

    需要注意的是:
    在GPU中显示的RenderTexture.SetActive()占用率很高,是因为你同时打开了编辑窗口的原因,而不是U3D的BUG。

    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:
    http://docs.unity3d.com/Documentation/Components/RenderTech-ForwardRendering.html

    e.使用相关剔除数量直接减少Draw Call数量,下文有相关提及。


    5.优化几何模型

    最基本的两个优化准则:
    a.不要有不必要的三角面。
    b.UV贴图中的接缝和硬边越少越好。

    需要注意的是,图形硬件需要处理顶点数并跟硬件报告说的并不一样。不是硬件说能渲染几个点就是几个点。模型处理应用通展示的是几何顶点数量。例如,一个由一些不同顶点构成的模型。在显卡中,一些集合顶点将会被分离(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 :
    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.关于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位浮点格式,适合顶点变换运算,但比较慢。
    half:16位浮点格式,适合贴图和UV坐标计算,是highp类型计算的两倍。
    fixed: 10位浮点格式,适合颜色,光照,和其他。是highp格式计算的四倍。

    写Shader优化的小提示:
    http://docs.unity3d.com/Documentation/Components/SL-ShaderPerformance.html


    11.另外的相关优化:

    a.对Draw Call Batching的优化
    http://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html

    b.对Rendering Statistics Window的说明和提示:
    http://docs.unity3d.com/Documentation/Manual/RenderingStatistics.html

    c.角色模型的优化建议
    用单个蒙皮渲染、尽量少用材质、少用骨骼节点、移动设备上角色多边形保持在300~1500内(当然还要看具体的需求)、PC平台上1500~4000内(当然还要看具体的需求)。

    http://docs.unity3d.com/Documentation/Manual/ModelingOptimizedCharacters.html









    [Unity3D]图形渲染优化、渲染管线优化、图形性能优化
       
             
     
     
    转载请留下本文原始链接,谢谢。本文会不定期更新维护,最近更新于2013.11.09

    主要内容也可以参考:
    http://docs.unity3d.com/Documentation/Manual/OptimizingGraphicsPerformance.html

    最简单的优化建议:

    1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与CPU。
    2.如果你用U3D自带的SHADER,在表现不差的情况下选择Mobile或Unlit目录下的。它们更高效。
    3.尽可能共用材质。
    4.将不需要移动的物体设为Static,让引擎可以进行其批处理。
    5.尽可能不用灯光。
    6.动态灯光更加不要了。
    7.尝试用压缩贴图格式,或用16位代替32位。
    8.如果不需要别用雾效(fog)
    9.尝试用OcclusionCulling,在房间过道多遮挡物体多的场景非常有用。若不当反而会增加负担。
    10.用天空盒去“褪去”远处的物体。
    11.shader中用贴图混合的方式去代替多重通道计算。
    12.shader中注意float/half/fixed的使用。
    13.shader中不要用复杂的计算pow,sin,cos,tan,log等。
    14.shader中越少Fragment越好。
    15.注意是否有多余的动画脚本,模型自动导入到U3D会有动画脚本,大量的话会严重影响消耗CPU计算。
    16.注意碰撞体的碰撞层,不必要的碰撞检测请舍去。


    1.为什么需要针对CPU(中央处理器)与GPU(图形处理器)优化?

    CPU和GPU都有各自的计算和传输瓶颈,不同的CPU或GPU他们的性能都不一样,所以你的游戏需要为你目标用户的CPU与GPU能力进行针对开发。


    2.CPU与GPU的限制

    GPU一般具有填充率(Fillrate)和内存带宽(MemoryBandwidth)的限制,如果你的游戏在低质量表现的情况下会快很多,那么,你很可能需要限制你在GPU的填充率。

    CPU一般被所需要渲染物体的个数限制,CPU给GPU发送渲染物体命令叫做DrawCalls。一般来说DrawCalls数量是需要控制的,在能表现效果的前提下越少越好。通常来说,电脑平台上DrawCalls几千个之内,移动平台上DrawCalls几百个之内。这样就差不多了。当然以上并不是绝对的,仅作一个参考。

    往往渲染(Rendering)并不是一个问题,无论是在GPU和CPU上。很可能是你的脚本代码效率的问题,用Profiler查看下。

    关于Profiler介绍:http://docs.unity3d.com/Documentation/Manual/Profiler.html

    需要注意的是:
    在GPU中显示的RenderTexture.SetActive()占用率很高,是因为你同时打开了编辑窗口的原因,而不是U3D的BUG。

    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 callbatching)。具体方法和注意事项查看以下链接:

    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:
    http://docs.unity3d.com/Documentation/Components/RenderTech-ForwardRendering.html

    e.使用相关剔除数量直接减少Draw Call数量,下文有相关提及。


    5.优化几何模型

    最基本的两个优化准则:
    a.不要有不必要的三角面。
    b.UV贴图中的接缝和硬边越少越好。

    需要注意的是,图形硬件需要处理顶点数并跟硬件报告说的并不一样。不是硬件说能渲染几个点就是几个点。模型处理应用通展示的是几何顶点数量。例如,一个由一些不同顶点构成的模型。在显卡中,一些集合顶点将会被分离(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 、 OcclusionCulling

    LOD (Level Of Detail)是很常用的3D游戏技术了,其功能理解起来则是相当于多重纹理贴图。在以在屏幕中显示模型大小的比例来判断使用高或低层次的模型来减少对GPU的传输数据,和减少GPU所需要的顶点计算。

    摄像机分层距离剔除(Per-Layer CullDistances):为小物体标识层次,然后根据其距离主摄像机的距离判断是否需要显示。

    遮挡剔除(OcclusionCulling)其实就是当某个物体在摄像机前被另外一个物体完全挡住的情况,挡住就不发送给GPU渲染,从而直接降低DRAWCALL。不过有些时候在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.关于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位浮点格式,适合顶点变换运算,但比较慢。
    half:16位浮点格式,适合贴图和UV坐标计算,是highp类型计算的两倍。
    fixed: 10位浮点格式,适合颜色,光照,和其他。是highp格式计算的四倍。

    写Shader优化的小提示:
    http://docs.unity3d.com/Documentation/Components/SL-ShaderPerformance.html


    11.另外的相关优化:

    a.对Draw Call Batching的优化
    http://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html

    b.对Rendering Statistics Window的说明和提示:
    http://docs.unity3d.com/Documentation/Manual/RenderingStatistics.html

    c.角色模型的优化建议
    用单个蒙皮渲染、尽量少用材质、少用骨骼节点、移动设备上角色多边形保持在300~1500内(当然还要看具体的需求)、PC平台上1500~4000内(当然还要看具体的需求)。

    http://docs.unity3d.com/Documentation/Manual/ModelingOptimizedCharacters.html








    展开全文
  • Unity3D 优化总篇

    2015-05-08 09:35:32
    转载【整理】unity3d优化总结篇 -- yxriyin 对项目优化有很多点,如:mesh合并 ,减少DrawCall和模型骨骼以及物理计算,合并材质球,优化代码等等, 优化:  1. 更新不透明贴图的压缩格式为ETC 4bit,...
  • 2.导入图形或者MESH的方法无非两种,一种是直接拷贝到文件目录下的Assets文件夹下面,Unity3d引擎会自动找到添加的文件,并且能在PROJECT面板中找到它。另一种是我们在PROJECT面板中用右键菜单,导入素材。当然,我...
  • unity3d优化总结篇

    2018-07-31 17:42:11
    对项目优化有很多,如:mesh合并 ,减少DrawCall和模型骨骼以及物理计算,合并材质球,优化代码等等, 现在继续补上,该内容为本人经验以及网上收集整理,希望大家有更好的优化方法,能够继续跟帖,一起探讨,共同...
  • Unity3d面试题

    2018-06-25 15:16:20
    这个是我刚刚整理出的Unity面试题,为了帮助大家面试,同时帮助大家更好地复习Unity知识点,如果大家发现有什么错误,(包括错别字和知识点),或者发现哪里描述的不清晰,请在下面留言,我会重新更新,希望大家共同...
  • Unity3D常见技术笔试题

    2017-07-03 22:22:24
    网上和实际当中出现较多,遇到较多的Unity3D游戏开发笔试题,不是特别全,但是出现频率较高.
  • UNITY3d在移动设备上的一些优化资源的方法1.使用assetbundle,实现资源分离和共享,将内存控制到200m之内,同时也可以实现资源的在线更新2.顶点数对渲染无论是cpu还是gpu都是压力最大的贡献者,降低顶点数到8万以下...
  • Unity3d_Stats和优化

    2015-06-03 00:09:50
    一,Unity3D 渲染统计窗口 Game视窗的Stats去查看渲染统计的信息: 1、FPS fps其实就是 frames per second,也就是每一秒游戏执行的帧数,这个数值越小,说明游戏越卡。   2、Draw calls batching...
  • 大家好,我是孙广东。 转载请注明出处:http://blog.csdn.net/u010019717更全的内容请看我的游戏蛮牛地址:...使用此工具可以创建 2D 骨骼、皮肤你的人物的骨头,并创建真
  • Unity3D优化--

    2017-03-31 18:34:30
    项目进入了中期后就需要对程序在移动设备上的表现做分析评估和针对性的优化了,首先前期做优化,很多瓶颈没表现出来,能做的东西不多,而且很多指标会凭预想,如果后期做优化又会太晚,到时候发现一些问题改起来返工...
  • http://docs.unity3d.com/Documentation/Manual/OptimizingGraphicsPerformance.html 最简单的优化建议: 1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与...
  • 项目进入了中期之后,就需要对程序在移动设备上的表现做分析评估和针对性的优化了,首先前期做优化,很多瓶颈没表现出来,能做的东西不多,而且很多指标会凭预想,如果太后期做优化又会太晚,到时发现一些问题改起来...
  • Unity3D中网格合并示例的研究:为了实现游戏人物外形的定制,专门研究了Unity示例程序 。 首先需要了解几个基本对象的结构 一、 SkinedMeshRender:该对象负责网格绘制。 主要数据成员包括: var bones : ...
  • 到现在我大概用了四年多u3d,期间掉过无数坑,遇到过各种问题,2015年底的时候想着应该将其整理出来,方便大家查阅,于是有了这篇东西。但是实际整理完发现,有些问题我已经...我会把所有问题全部整理好在共享给大家
1 2 3 4 5 ... 20
收藏数 607
精华内容 242
关键字:

unity3d 共享骨骼