Loading lessons...
Compute Shaders
Compute Shaders
Compute Shaders are program kernels that execute computations on the GPU, completely bypassing the rendering pipeline.
Shader HLSL Syntax
Create a compute shader (ComputeShader.compute):
#pragma kernel CSMain
// Read/Write Texture
RWTexture2D<float4> Result;
[numthreads(8, 8, 1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
Result[id.xy] = float4(id.x / 512.0, id.y / 512.0, 0.0, 1.0);
}
[numthreads(8,8,1)]: Defines the thread block size. Here, a block processes 64 pixels.
Dispatching from C#
Instantiate a RenderTexture with random write permissions, and launch the kernel:
using UnityEngine;
public class ComputeRunner : MonoBehaviour
{
public ComputeShader computeShader;
private RenderTexture _tex;
void Start()
{
_tex = new RenderTexture(512, 512, 0);
_tex.enableRandomWrite = true;
_tex.Create();
int kernelIndex = computeShader.FindKernel("CSMain");
computeShader.SetTexture(kernelIndex, "Result", _tex);
// Run shader: (512 / 8) groups = 64 groups in X and Y
computeShader.Dispatch(kernelIndex, 64, 64, 1);
}
}
ComputeBuffer
Use a ComputeBuffer to pass arrays of raw structures to and from a compute shader:
// Define and populate buffer
ComputeBuffer buffer = new ComputeBuffer(dataCount, stride);
buffer.SetData(myDataArray);
// Pass to shader
computeShader.SetBuffer(kernelIndex, "myBufferName", buffer);
// Release GPU memory when finished
buffer.Release();
TL;DR
- Compute shaders execute code in parallel directly on the GPU.
- Output results to a
RenderTextureor read/write with aComputeBuffer. - Always call
Release()on ComputeBuffers to avoid GPU memory leaks.