S&box Wiki

Compute Shaders

What can you do with compute shaders?

You can use compute shaders to do lots of things, but their most common use is to generate textures at blazing fast speeds; here's an example that shows you how you can do that.

C# side

Let's wrap our compute stuff in a class so it's nice and tidy:

// This is what contains our compute shader instance, as well as the texture // we're going to be rendering to. public class MyTextureGenerator { private ComputeShader computeShader; public Texture Texture { get; } public MyTextureGenerator() { // Create a texture that we can use Texture = Texture.Create( 512, 512 ) .WithUAVBinding() // Needs to have this if we're using it in a compute shader .WithFormat( ImageFormat.RGBA16161616F ) // Other formats are available :-) .Finish(); computeShader = new ComputeShader( "my_compute_shader" ); // This should be the name of your shader } public void Dispatch() { // Set up the shader... computeShader.Attributes.Set( "OutputTexture", Texture ); // ...and run it! computeShader.Dispatch( Texture.Width, Texture.Height, 1 ); } }

You then want to actually use that class in an entity:

// This is the game entity we use to draw a model with our generated texture. public class MyModel : ModelEntity { private MyTextureGenerator myTextureGenerator; public override void Spawn() { base.Spawn(); Transmit = TransmitType.Always; } public override void ClientSpawn() { // Set up our dispatching class. myTextureGenerator = new(); } [Event.PreRender] public void OnFrame() { // You can call this wherever you want, but we'll update it every frame for now. myTextureGenerator.Dispatch(); // Here's where we assign our generated texture to this entity's model. SceneObject.Attributes.Set( "Albedo", myTextureGenerator.Texture ); } }

Spawn your entity somewhere, make sure it's visible.

Shader

Compute shaders are similar to normal VS/FS shaders, but they're a bit shorter and you can forego a lot of the includes. Here's a really simple one that'll generate a solid pink texture:

//========================================================================================================================= // Optional //========================================================================================================================= HEADER { DevShader = true; Description = "My Cool Compute Shader"; } //========================================================================================================================= // Optional //========================================================================================================================= FEATURES { } //========================================================================================================================= MODES { Default(); } //========================================================================================================================= COMMON { #include "common/shared.hlsl" } //========================================================================================================================= CS { // Output texture RWTexture2D<float4> g_tOutput< Attribute( "OutputTexture" ); >; [numthreads(8, 8, 1)] void MainCs( uint uGroupIndex : SV_GroupIndex, uint3 vThreadId : SV_DispatchThreadID ) { g_tOutput[vThreadId.xy] = float4( 1, 0, 1, 1 ); } }