您当前的位置: 首页 >  Jave.Lin unity

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

Jave.Lin 发布时间:2020-12-02 21:17:22 ,浏览量:4

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

关注
打赏
1688896170
查看更多评论

Jave.Lin

暂无认证

  • 4浏览

    0关注

    546博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0497s