Unity GPU Instancing 自己写个简单的测试用例2 - IsSupport? and Update?

前一篇: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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值