前一篇:Unity GPU Instancing 自己写个简单的测试用例1
用了最简单的方式在 Unity 中实现 GPU Instancing Draw 的功能
这次,我们稍微再加以修改,优化出另一个版本的使用方式
判断是否支持 GPU Instancing
if (SystemInfo.supportsInstancing)
{
// 如果支持,我们就开启
}
else
{
// 如果不支持,我们就关闭
}
属性更新的开关
public bool enabled_update = false;
private void Update()
{
if (enabled_update)
{
_Inner_Update();
}
}
private void _Inner_Update()
{
mpb.SetMatrix(_MMat, transform.localToWorldMatrix);
mpb.SetColor(_Color, col);
mpb.SetFloat(_AngleOffset, angle_offset);
mesh_renderer.SetPropertyBlock(mpb);
}
这样可以减少 CPU 层的消耗
完整的 CSharp 脚本
using UnityEngine;
[ExecuteInEditMode]
public class InstancedScript_Solution1 : MonoBehaviour
{
private static int _MMat = Shader.PropertyToID("_MMat");
private static int _Color = Shader.PropertyToID("_Color");
private static int _AngleOffset = Shader.PropertyToID("_AngleOffset");
private static MaterialPropertyBlock mpb;
public Color col;
public float angle_offset;
public bool enabled_update = false;
private MeshRenderer mesh_renderer;
private void Awake()
{
mesh_renderer = GetComponent<MeshRenderer>();
if (mpb == null) mpb = new MaterialPropertyBlock();
if (SystemInfo.supportsInstancing)
{
// 如果支持,我们就开启
if (!mesh_renderer.sharedMaterial.enableInstancing)
{
mesh_renderer.sharedMaterial.enableInstancing = true;
}
}
else
{
// 如果不支持,我们就关闭
if (mesh_renderer.sharedMaterial.enableInstancing)
{
mesh_renderer.sharedMaterial.enableInstancing = false;
}
}
_Inner_Update();
}
private void Update()
{
if (enabled_update)
{
_Inner_Update();
}
}
private void _Inner_Update()
{
mpb.SetMatrix(_MMat, transform.localToWorldMatrix);
mpb.SetColor(_Color, col);
mpb.SetFloat(_AngleOffset, angle_offset);
mesh_renderer.SetPropertyBlock(mpb);
}
}
更新位置改进
另外,如果你再金币更新时,与其他的交互对象显示看起来更新不及时,可以将 Update 的内容挪到:LateUpdate,如下:
//private void Update()
//{
// if (enabled_update)
// {
// _inner_update();
// }
//}
private void LateUpdate()
{
if (enabled_update)
{
_inner_update();
}
}
开关更新标识的区别
下面是绘制 1000 个小金币
然后在分别控制 update 的开关,看看 FPS 的变化情况
开了 Update 大概降低了 100 FPS
所以 GPU Instancing 非常适合绘制那些静止不动的相同材质、相同网格的情况,像那些不需要风力摆动的树、草、石头、等场景物件
虽然也可以绘制 动起来 对象,但是相对来说,update 更新的 CPU 消耗会增加(当前,你也可以将这部分的 update 写在 GPU 中处理,如 vertex shader 或是 computer shader)
Project
backup : GPU_Instancing_DEMO_v2