Revision Difference
Compute_Shaders#547060
<cat>Code.Shader</cat>⤶
<title>Compute Shaders</title>⤶
⤶
<note>⤶
TODO - this isn't finished, it's not an exhaustive example.. there's lots more to add here.⤶
</note>⤶
⤶
You can use compute shaders to do stuff. ⤶
Here's how you can write a really simple compute texture to generate a texture on the GPU at runtime.⤶
⤶
## C# side⤶
⤶
You'll first need to create a `SceneCustomObject` so that you can call `Dispatch` within the render loop:⤶
⤶
```⤶
public class MySceneObject : SceneCustomObject⤶
{⤶
private MyTextureGenerator myTextureGenerator;⤶
⤶
public MySceneObject( SceneWorld sceneWorld ) : base( sceneWorld )⤶
{⤶
myTextureGenerator = new();⤶
}⤶
⤶
public override void RenderSceneObject()⤶
{⤶
base.RenderSceneObject();⤶
myTextureGenerator.Render();⤶
}⤶
}⤶
```⤶
⤶
You'll also probably want to wrap your compute stuff in a nice class so that everything's nice and tidy:⤶
⤶
```⤶
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 Render()⤶
{⤶
computeShader.Attributes.Set( "Texture", texture );⤶
computeShader.Dispatch( texture.Width, texture.Height, 1 );⤶
}⤶
```⤶
⤶
You also want to actually use that scene object in an entity... here's how you can do that:⤶
⤶
```⤶
public class MyModel : ModelEntity⤶
{⤶
private MySceneObject mySceneObject;⤶
⤶
public override void Spawn()⤶
{⤶
base.Spawn();⤶
⤶
Transmit = TransmitType.Always;⤶
}⤶
⤶
public override void ClientSpawn()⤶
{⤶
mySceneObject = new( Map.Scene )⤶
{⤶
Transform = this.Transform,⤶
Position = this.Position,⤶
Bounds = this.CollisionBounds + this.Position⤶
};⤶
}⤶
⤶
protected override void OnDestroy()⤶
{⤶
base.OnDestroy();⤶
⤶
mySceneObject?.Delete();⤶
}⤶
}⤶
```⤶
⤶
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⤶
{⤶
CompileTargets = ( IS_SM_50 && ( PC || VULKAN ) );⤶
DevShader = true;⤶
Description = "My Cool Compute Shader";⤶
}⤶
⤶
//=========================================================================================================================⤶
// Optional⤶
//=========================================================================================================================⤶
FEATURES⤶
{⤶
}⤶
⤶
//=========================================================================================================================⤶
MODES⤶
{⤶
Default();⤶
}⤶
⤶
//=========================================================================================================================⤶
COMMON⤶
{⤶
#include "common/shared.hlsl"⤶
}⤶
⤶
//=========================================================================================================================⤶
CS⤶
{⤶
// Output texture⤶
RWTexture2D<float4> g_tOutput< Attribute( "Texture" ); >;⤶
⤶
[numthreads(8, 8, 1)] ⤶
void MainCs( uint uGroupIndex : SV_GroupIndex, uint3 vThreadId : SV_DispatchThreadID )⤶
{⤶
g_tOutput[vThreadId.xy] = float4( 1, 0, 1, 1 );⤶
}⤶
}⤶
```⤶
⤶
## Tips⤶
⤶
If you're writing a compute shader you probably want to see its contents. You can do that really easily using `Render.Draw2D.Quad`.⤶
⤶
```⤶
public void RenderHud()⤶
{⤶
var draw = Render.Draw2D;⤶
⤶
draw.Texture = texture;⤶
draw.Color = Color.White;⤶
⤶
draw.Quad( new Vector2( 0, 0 ),⤶
new Vector2( 512, 0 ),⤶
new Vector2( 512, 512 ),⤶
new Vector2( 0, 512 ) );⤶
}⤶
```⤶
⤶
This'll draw your generated texture in the top left of the screen.