Unity3d开发编辑器DrawCall参数解析

Posted 松阳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3d开发编辑器DrawCall参数解析相关的知识,希望对你有一定的参考价值。

对于Unity运行场景中,有许多可以标记场景状况的参数。这篇文章主要探讨这些参数的意义,其中如果有错误欢迎指正。

Game Stats

点击游戏Tab下的Stats可以展开如下界面,可以方便我们查看游戏运行状态。
技术分享

FPS & Time per frame

FPS是通常说的帧率。每帧用时指的是渲染一帧需要消耗的用时,这个值只包含每帧更新游戏视图的时间,不受其他在编辑器中功能的影响,例如Profiler。FPS是这个数字的倒数。值得注意的是,这个值会比我们通常说的帧率要高,因为我们是直接计算两帧之间的时间差的。我猜想手机打包之后两个值的差会变小,但也不会绝对一样。

技术分享

Batches & DrawCall

这个是绘制图像的重要指标,可以作为衡量场景绘制效率的首要参考。

一个 Draw Call,等于呼叫一次 DrawIndexedPrimitive (DX) or glDrawElements (OGL),等于一个 Batch。

NVIDIA 在GDC上曾提出 25k batch/sec的渲染量会使1GHz的CPU达到100%的使用率,因此使用公式

25K?n(GHZ)?Percentage/Framerate=Batch/Frame

可以推算出某些CPU可以抗多少Batch。例如红米手机CPU为1.5GHz,假设分出20%资源供渲染,希望游戏跑到30帧。那么能抗多少DrawCall? 25k * 1.5 * 0.2 / 30 = 250。因此从这方面也能看出,如果CPU不能分出更多的资源供渲染计算,能抗的DrawCall就会变少。

在Stats面板中看到的Batches是渲染的总Batch这个值等于同于DrawCall。但Unity中可以获取到未批次处理之前的DrawCall。因此需要注意不要混淆概念。

Saved By Batching

这个值是由于Batch减少的DrawCall,可以间接的看到场景优化的效果。这个值由两部分组成:Static BatchingDynamic Batching。这个由Unity内建自动合并虽然优点多多,但也不是没有缺陷。静态合并会引发内存和存储的额外开销,动态合并会增加CPU的负担。 这部分内容参考Unity官方文档

总体上讲所以希望批次渲染的元素要有相同的材质。通常两个材质如果只有贴图不同,可以将贴图合并到一张大图中,这就是所谓的和图。另外在使用ShadowCaster时,只要材质相同,即使贴图不同也可以合并渲染。

Dynamic Batches

动态合并在满足以下条件时是自动完成的:

  • 模型总顶点数小于900。
  • 不包含镜像transform改变。不改变Scale。
  • 如果使用动态lightmap需要指定正确。
  • 不使用多Pass的Shader.

由于需要在合并时通过CPU计算转为世界坐标,这项技术只在CPU消耗比DrawCall消耗“便宜”时才值得。这个衡量标准会根据平台产生差异,例如苹果平台上DrawCall的消耗便宜,就不应该使用这项技术。这个功能可以在Editor->Project Setting->Player中进行设置打开与关闭。

Static Batches

场景中不能移动的物件可以使用静态合并,它不受顶点数的限制,可以大幅减少DrawCall。但为了将元素合并到一个大模型中,这项技术需要额外的内存。主要的内存消耗在于共享多边形会在内存中重复创建。因此有时候需要牺牲渲染效率来避免静态合并,来保证内存够小。例如在茂密的树林中使用这项技术会导致大量的内存消耗。

Tris & Verts

摄像机下的所有三角形和顶点这个在低端硬件上也是主要瓶颈。

脚本获取值

其他数据暂时先不关注了,有必要以后可以再单写一篇。在编辑模式下这些数据是可以通过脚本获取到的,不过打出包来不太成。简单写了一下,效果如下:

技术分享

其中所有的立方体使用静态合并,面片使用动态合并。场景UI一共17个Batch。动态批次1个,静态批次2个(不知拆分规则),批次渲染一共20。每一个动态物体1个DrawCall,共20个,4个动态物体1个DrawCall,17个UI产生的DrawCall,共38个。

相关代码如下:

using UnityEngine;
using System.Collections;
using UnityEditor;

public class testDC : MonoBehaviour 
{
    #region Unity Messages

    void OnGUI()
    {
        GUILayout.TextField("Total DrawCall: " + UnityStats.drawCalls);
        GUILayout.TextField("Batch: " + UnityStats.batches);
        GUILayout.TextField("Static Batch DC: " + UnityStats.staticBatchedDrawCalls);
        GUILayout.TextField("Static Batch: " + UnityStats.staticBatches);
        GUILayout.TextField("DynamicBatch DC: " + UnityStats.dynamicBatchedDrawCalls);
        GUILayout.TextField("DynamicBatch: " + UnityStats.dynamicBatches);

        GUILayout.TextField("Tri: " + UnityStats.triangles);
        GUILayout.TextField("Ver: " + UnityStats.vertices);
    }

    #endregion
}

以上是关于Unity3d开发编辑器DrawCall参数解析的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D插件NGUI基础学习笔记

unity3d 如何UI优化和减少DC(DrawCall)

unity3d编辑器怎么清除本地存储呀?

[干货分享]Unity3D 深入解析Timeline编辑器

Unity3D中Layers和LayerMask解析

为了让开发者写MaxCompute SQL更爽,DataWorks 增强SQL 编辑器功能