unity computer shader多线程计算与编辑器扩展

VS中插件

在这里插入图片描述

unity computershader编写

在这里插入代码片
// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain

//线程组
#define thread_group_x 2
#define thread_group_y 2
//线程
#define thread_x 2
#define thread_y 2

//可读写缓冲区
RWStructuredBuffer<float3> inputBuffer_A;
RWStructuredBuffer<float3> inputBuffer_B;

RWStructuredBuffer<float3> result;

//单个线程组包含的线程数
[numthreads(2,2,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // TODO: insert actual code here!

	int index = id.x + (id.y * thread_x * thread_group_x) + (id.z * thread_group_x * thread_group_y * thread_x * thread_y);
	result[index] = inputBuffer_A[index]+inputBuffer_B[index];

}

unity cs编写实现计算结果在面板的显示

在这里插入代码片
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CaculateEromShader : MonoBehaviour
{
    // Start is called before the first frame update
    //设置为public的属性会在unity面板显示,此处获取computershader
    public ComputeShader computeShader;

    #region buffer

    private ComputeBuffer inputBuffer_A;
    private ComputeBuffer inputBuffer_B;
    private ComputeBuffer result;
    private int kernel;

    #endregion buffer

    #region input

    public Vector2 thread_group = new Vector2(2, 2);

    public Vector3[] array1;
    public Vector3[] array2;
    public Vector3[] resultArr;

    #endregion input

    private void OnEnable()
    {
        InitBuffers();
    }

    private void OnDestory()
    {
    }

    public void ComputeResult()
    {
        if (array1.Length == array2.Length)
        {
            resultArr = new Vector3[array1.Length];
            InitBuffers();
            GetResult();
        }
    }

    public void InitBuffers()
    {
        //set
        inputBuffer_A = new ComputeBuffer(array1.Length, 12);//分配缓存
        inputBuffer_A.SetData(array1);//获取数据

        inputBuffer_B = new ComputeBuffer(array2.Length, 12);
        inputBuffer_B.SetData(array2);

        result = new ComputeBuffer(resultArr.Length, 12);

        //init
        //实现computershader中缓冲与本文件中缓冲区的映射
        kernel = computeShader.FindKernel("CSMain");//找到对应的kernel
        computeShader.SetBuffer(kernel, "inputBuffer_A", inputBuffer_A);//引号中参数为computershader中的缓冲区,其后的参数为本文件中的缓冲区
        computeShader.SetBuffer(kernel, "inputBuffer_B", inputBuffer_B);
        computeShader.SetBuffer(kernel, "result", result);
    }

    public void GetResult()
    {
        computeShader.Dispatch(kernel, 2, 2, 1);//此处参数表示线程组
        result.GetData(resultArr);
        result.Release();
    }

    // private void Start()
    //{
    // }

    // Update is called once per frame
    private void Update()
    {
        ComputeResult();
    }
}

结果展示

在这里插入图片描述
cs中为在update函数中调用ComputeResult函数
可通过播放得到计算结果
或者通过在cs脚本添加实现编辑模式下显示计算结果
在这里插入图片描述

编辑器扩展

在Editor文件夹下创建cs脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(CaculateEromShader))]//表明是calculatefromshader的Editor
[CanEditMultipleObjects]
public class CalculateEromShaderEditor : Editor
{
    // Start is called before the first frame update
    private CaculateEromShader caculateEromShader;

    private SerializedObject obj;

    private void OnEnable()
    {
        obj = new SerializedObject(target);
    }

    public override void OnInspectorGUI()
    {
        //控件位置与代码中声明顺序一致
        caculateEromShader = (CaculateEromShader)target;
        obj.Update();
        DrawDefaultInspector();//绘制默认面板
        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("计算", GUILayout.Width(80)))
        {
            if (caculateEromShader.array1.Length == caculateEromShader.array2.Length)
            {
                caculateEromShader.resultArr = new Vector3[caculateEromShader.array1.Length];
                caculateEromShader.InitBuffers();
                caculateEromShader.GetResult();
            }
        }
        if (GUILayout.Button("初始化", GUILayout.Width(80)))
        {
            caculateEromShader.resultArr = new Vector3[caculateEromShader.array1.Length];
            caculateEromShader.InitBuffers();
        }
        EditorGUILayout.EndHorizontal();

        if (caculateEromShader.array1.Length == caculateEromShader.array2.Length)
        {
            EditorGUILayout.HelpBox("可以计算", MessageType.Info);
        }
        else
        {
            EditorGUILayout.HelpBox("???", MessageType.Error);
        }
    }
}

效果展示

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值