Revision Difference
Compute_Shaders#551293
<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 );⤶
}⤶
}⤶
## Using compute shaders from C#⤶
⤶
Here's an example of creating a compute shader and populating a texture with it.⤶
⤶
```csharp⤶
// Create a compute shader from a .shader file⤶
var computeShader = new ComputeShader( "my_compute_shader" );
⤶
// Create a texture for the compute shader to use⤶
var texture = Texture.Create( 512, 512 )
.WithUAVBinding() // Needs to have this if we're using it in a compute shader⤶
.WithFormat( ImageFormat.RGBA16161616F ) // Use whatever you need⤶
.Finish();
⤶
// Attach texture to OutputTexture attribute in shader⤶
computeShader.Attributes.Set( "OutputTexture", texture );⤶
⤶
// Dispatch
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:⤶
⤶
## HLSL Shader⤶
⤶
Compute shaders are HLSL like normal shaders, except everything goes in a CS block and runs a method named MainCs.⤶
⤶
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⤶
⤶
COMMON⤶
{
#include "common/shared.hlsl"
}
⤶
//=========================================================================================================================⤶
CS⤶
⤶
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 );
}
}
```