S&box Wiki

Revision Difference

Compute_Shaders#548209

<cat>Material.ShaderBasic</cat> <title>Compute Shaders</title> ⤶ # 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 ); } } ```