Introduction to code examples
This is an example Create a new array , The values in this array are GPU A calculation is performed in the , And save the results back CPU, The final output comes out . The code is as follows :
c# script :
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class ComputeScript : MonoBehaviour {
//ComputeShader Object definition , You need to assign a value to it computeShader Of shader resources public ComputeShader
computeShader; //ComputeBuffer,
c# Duanyu gpu Container for data communication , We need to organize our data ( In this case, yes inOutBuffer), Put it here buffer inside , And then put this buffer Plug into
//computeShader inside , by gpu Calculate and prepare data private ComputeBuffer buffer; // How many data do we have in total public
int count = 128; // The method we want to calculate is in computeShader Index in , This index is in binding buffer It will be used in the future private int
kernal; // We define the data ourselves , Use this object to load the data we want , And then I'll give it to you ComputeBuffer // be careful , The data in the array must be blittable
Type of data , It can be said that it must be c# Foundation type , Or it's made up of base types struct type MixData[] inOutBuffer; struct MixData {
public int myVal; public float myFloat; } // Start is called before the first
frame update void Start() { Debug.Log($" Do you support it compute
shader:{SystemInfo.supportsComputeShaders}"); // Prepare our own data inOutBuffer = new
MixData[count]; for(int i = 0; i < count; i++) { inOutBuffer[i].myFloat = 1.0f;
inOutBuffer[i].myVal = i; }
// Here is the data of our fortress MixData Total length of , You can see that ,MixData One by int And one float form , The length is 8 int stride =
sizeof(int) + sizeof(float); // initialization ComputeBuffer buffer = new
ComputeBuffer(count, stride); // Put the data we've got in place Buffer in buffer.SetData(inOutBuffer);
// find GPU What's the real way to do it computeShader Index in kernal = computeShader.FindKernel("CSMain");
Debug.Log($"Kernal:{kernal}");
// Take what we've prepared buffer Data to computeShader, That's how it's built gpu reach cpu Data connection for ,gpu In calculation
// Will use the current one buffer Data in the library . // be careful : The second parameter in the following method Must be with shader The one in the picture buffer The variable names are as like as two peas.
computeShader.SetBuffer(kernal, "inOutBuffer", buffer); } // Update is called
once per frame void Update() { if (Input.GetKeyDown(KeyCode.T)) {
//c# Layer trigger computeShader conduct gpu Core computing
// The first parameter is the corresponding method index , Brother 2,3,4 Each parameter represents the name of the thread group x,y,z, It corresponds to computeShader In
//thread_group_x,thread_group_y and thread_group_z computeShader.Dispatch(kernal,
2, 2, 1); } if (Input.GetKeyDown(KeyCode.C)) {
// from Buffer Get the full data from , load inOutBuffer In this object buffer.GetData(inOutBuffer); foreach(var
val in inOutBuffer) { Debug.Log($"index:{val.myVal};value:{val.myFloat}"); } }
} private void OnDestroy() { // release Buffer buffer?.Release(); //Dispose Buffer
buffer?.Dispose(); } }
computeShader:
// definition computeShader The main calculation function of , This function will be in the c# Layer debinding
// every last computeShader There can be one or more such definitions , But there must be at least one #pragma kernel CSMain
// Thread group define, corresponding c# Call inside ComputeShader.Dispatch Method thread group parameters #define thread_group_x 2
#define thread_group_y 2 #define thread_group_z 1
// Thread definition in each thread group , We can think of a thread group as composed of x,y,z Three dimensional is defined by the number of threads // The following definition represents : A thread group includes 8*4*1 Threads
#define thread_x 8 #define thread_y 4 #define thread_z 1 // Definition of data structure struct
MixData { int myVal; float myFloat; };
// Encapsulation of incoming data , It is related to c# Layered ComputeShader.SetBuffer Methods correspond ,c# The data layer is ready
// And then it's passed in buffer in .c# The name parameter of the layer method must match the name of the following variable RWStructuredBuffer<MixData>
inOutBuffer; // The number of threads in a thread group , among x = 8, y = 4, z = 1 [numthreads(8,4,1)] void
CSMain (uint3 id : SV_DispatchThreadID) { // TODO: insert actual code here!
//Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0);
// there idx It means that I want to calculate the index of the current processing thread in the data , After finding the index, you can modify it accordingly buffer There's no more data in the database int idx = id.x + (id.y *
thread_group_x * thread_x) + (id.z * thread_group_x * thread_x * thread_group_y
* thread_y); MixData d; d.myFloat = inOutBuffer[idx].myFloat + 1.0; d.myVal =
inOutBuffer[idx].myVal; // Modify the data we want to modify inOutBuffer[idx] = d; }
Technology