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);
}
}
}