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

Unity GPU Instancing 自己写个简单的测试用例4 - DrawInstanced + IJobParallelFor

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

这里先说明一下,我是在下班时间,挤牙膏的时间出来半小时,写了这2、3、4篇的内容

其实还有一大堆打杂期间学习的内容没有写到博客

上班学习的速度,确实没有猫在家里学习的速度快

前一篇:

  • Unity GPU Instancing 自己写个简单的测试用例1 实现了 Unity 中最简单的 Instancing draw 的方式
  • Unity GPU Instancing 自己写个简单的测试用例2 在1的基础上做了一丢丢优化
  • Unity GPU Instancing 自己写个简单的测试用例3 在2的基础上做了一丢丢优化

这一篇直接使用 Graphics.DrawInstanced API + IJobParallelFor 并行执行多线程来 update 数据

Shader

沒改过,和第3篇的一模一样

主要是 CSharp update 数据的方式变了,改用 IJobParallelFor

CSharp
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Rendering;

/// 
/// author  :   jave.lin
/// Unity GPU Instancing 方案3
/// 
public class InstancedScript_Solution3 : MonoBehaviour
{
    public struct ParallelUpdateDataJob : IJobParallelFor
    {
        public NativeArray colors;
        public NativeArray colors_vec4;
        public NativeArray angle_offset;
        public NativeArray pos_offset;
        public NativeArray model_mats;
        public Matrix4x4 parent_model_mat;

        public void Execute(int index)
        {
            colors_vec4[index] = colors[index];
            var angle = angle_offset[index];
            angle += 1.0f;
            angle = angle % 360.0f;
            angle_offset[index] = angle;

            var t = Matrix4x4.Translate(pos_offset[index]);
            var r = Matrix4x4.Rotate(Quaternion.Euler(new Vector3(0, angle_offset[index], 0)));

            model_mats[index] = parent_model_mat * t * r;
        }
    }

    private static int _Color = Shader.PropertyToID("_Color");
    private static MaterialPropertyBlock mpb;

    public int instance_count = 5;
    public Mesh mesh;           // 用于 GPU instance 的 Mesh
    public Material mat;        // 用于 GPU instance 的 Material
    public Camera cam;          // 指定要渲染的相机,如果 cam == null,那意味着所有相机都会渲染,如果需要在多个指定的相机渲染,这里可以声明为:Camera[] 数组即可
    //public LayerMask layer;     // Instancing 每个实例对象所属的 LayerMask 层级,配合对应的 Camera 使用,如:Camera 需要渲染 YourLayerName 层,那么 LayerMask 就加上 YourLayerName 层即可
    public int layer;           // 上面的 LayerMask 是无效的,因为获取layermask 的数值,而不是索引值,这里 Graphics.DrawInstanced 的 layer 参数值索引值,官方文档只是一句注释:to use,WTF,太不负责任的,WTF
    public ShadowCastingMode castShadow;

    public bool procedurce_fill_data;
    private bool last_fill_data = true;

    public Color[] col;
    public float[] angle_offset;
    public Vector3[] pos_offset;

    private Matrix4x4[] model_mats;
    private Vector4[] colors_vec4;

    private ParallelUpdateDataJob job = new ParallelUpdateDataJob();

    private int last_instance_count = 0;

    private void Start()
    {
        mpb = new MaterialPropertyBlock();
        UpdateDatas();
    }

    private void Update()
    {
        CheckSupport();
        UpdateDatas();
        RenderCoins();
    }

    private void OnDestroy()
    {
        if (job.colors.IsCreated) job.colors.Dispose();
        if (job.colors_vec4.IsCreated) job.colors_vec4.Dispose();
        if (job.angle_offset.IsCreated) job.angle_offset.Dispose();
        if (job.pos_offset.IsCreated) job.pos_offset.Dispose();
        if (job.model_mats.IsCreated) job.model_mats.Dispose();
    }

    private void CheckSupport()
    {
        if (!SystemInfo.supportsInstancing)
        {
            Debug.LogError("can not support GPU INSTANCING!");
        }
    }

    private void ProcedureFillData()
    {
        for (int i = 0; i             
关注
打赏
1688896170
查看更多评论
0.1470s