赞
踩
当场景中有大量使用 相同材质和网格 的物体时,通过GPU Instancing可以大幅降低Draw Call数量。
GPU Instancing是指由GPU和图形API支持的,用一个Draw Call同时绘制多个Geometry相同的物体的技术。
上圖中的場景有數千塊隕石,但只有三種隕石模型,這種情況下使用Instancing之後只需要幾十個Draw Call。
在D3D11中,Instanced Draw Call API如下所示:
注意前兩個參數:IndexCountPerInstance和InstanceCount,這是不同於一般Draw Call API的地方。你需要告訴D3D每個Instance用到多少個頂點索引以及這個Draw Call要畫多少個Instances。
那麼如何做到像上圖中那樣每塊石頭都有不同的位置、旋轉和大小呢?
在使用Instancing時,我們一般會把世界矩陣這種每個Instance獨有的資料放到一個額外的Buffer中以供Shader呼叫,可以是第二個Vertex Buffer,也可以是Constant Buffer。
Instancing 技术并不一定能提高性能。所以必须知道Instancing技术可以和不能做什么。
Instancing能做什么
Instancing不能做什么
具体来说,如果你的场景具有以下条件,那么使用Instancing可能会给你带来性能提升:
在实际的游戏项目中,最合适使用Instancing来优化的是植物植被。
因此通常这系统需要绘制大量相同的树木和草。
使用Instancing技术之后DrawCall的消耗会大幅度降低。
在Unity 5.4中使用Instancing需要注意:
Static / Dynamic Batching
,Instancing 也是一种降低(合并)的方式;MeshRenderer
组件和 Graphics.DrawMesh()
Instancing的實現步骤如下:
下面的程序展示了如何把一个简单的 Unlit Shader 修改为支持Instancing的版本。
红色字体的部分是在已有Shader的基础上进行修改或者增加的部分。
下面我们来逐一看看每一处修改的意思:
#pragma multi_compile_instancing
UNITY_INSTANCE_ID
UNITY_INSTANCING_CBUFFER_START(name) / UNITY_INSTANCING_CBUFFER_END
UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
UNITY_SETUP_INSTANCE_ID(v)
UNITY_TRANSFER_INSTANCE_ID(v, o)
UnityObjectToClipPos
如果想把一個Surface Shader改寫成支持Instancing的版本,你只需要加上“#pragma multi_compile_instancing” 就可以了。
下列情况不能使用 Instancing:
另外,由於Constant Buffer的尺寸限制,一個Instanced Draw Call能畫的物體數量是有上限的(參見UnityInstancing.cginc中的UNITY_MAX_INSTANCE_COUNT)
最後需要再次強調的是,Instancing在Shader上有額外的開銷,並不代表一定能提高FPS。永遠要以實際Profiling結果為準!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。