https://github.com/jasonjmcghee/compute-shaders
Learning compute shaders in public, in Godot 4
https://github.com/jasonjmcghee/compute-shaders
compute-shaders creative-coding godot4
Last synced: 5 months ago
JSON representation
Learning compute shaders in public, in Godot 4
- Host: GitHub
- URL: https://github.com/jasonjmcghee/compute-shaders
- Owner: jasonjmcghee
- License: mit
- Created: 2023-05-30T02:23:36.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2023-06-09T04:44:46.000Z (about 2 years ago)
- Last Synced: 2024-11-12T16:44:24.903Z (7 months ago)
- Topics: compute-shaders, creative-coding, godot4
- Language: C#
- Homepage:
- Size: 1.56 MB
- Stars: 34
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Experiments with Compute Shaders
Projects within:
| Slime | Life |
| ----------- | ----------- |
|  |  |## How this could be useful to you
- Has a couple of rather different examples leveraging compute shaders (both 2D)
- Has a special `ComputeManager` that creates nice abstraction on top of Godot Compute Shader `RenderingDevice` pattern.So, what is this `ComputeManager`?
## `ComputeManager`
The abstraction layer I built to dramatically simplify the complexity of compute shaders, from my perspective.
I can only keep so much complexity in my head, and this approach simplifies so much.
- (Almost) No thinking about how to turn data in C# into data GLSL will understand - essentially, only use `struct` with
primitive fields, or lists of them.
- Write any number of pipelines which will be sequentially executed when you call `execute()` on the `ComputeManager`
- You can signify buffers with ids, for example, from an `enum` to simplify your code and not deal with `Rid`.
- Easily read from, update, or clear buffers using the above ids pattern.### Notes
- Currently only supports `StructuredBuffer`, but could easily be extended to others with the same pattern.
- Currently does not support using a portion of a buffer (all or nothing), but again, easy to modify this.
- You can always dip down to the lower layer of abstraction (Godot layer).### Example
Writing pipelines using this pattern is easy.
This is a slightly simplified version of what is in `Slime.cs`.
It's a multi-pipeline / multi-shader compute pipeline and easily fits on a screen.
```csharp
public override void _Ready() {
computeManager = new ComputeManager();// Prepare our texture that represents the world
var trailMapImage = Image.Create(width, height, false, Image.Format.Rgba8);
trailMapDisplayTexture = ImageTexture.CreateFromImage(trailMapImage);
trailMapReadData = trailMapImage.GetData();
// Main Pipeline
computeManager
.AddPipeline("res://Slime/slime.glsl", agentManager.settings.numAgents, 1, 1)
.StoreAndAddStep((int) Buffers.Agents, agentManager.InitializeAgents())
.StoreAndAddStep((int) Buffers.AgentParams, agentManager.settings)
.StoreAndAddStep((int) Buffers.TrailMapReadData, trailMapReadData)
.StoreAndAddStep((int) Buffers.TrailMapWriteData, trailMapReadData)
.Build();// Diffuse Pipeline
computeManager
.AddPipeline("res://Slime/slime_diffuse.glsl", (uint) (width * height), 1, 1)
.StoreAndAddStep((int) Buffers.DiffuseParams, diffusionManager.settings)
.AddStep((int) Buffers.TrailMapWriteData)
.AddStep((int) Buffers.TrailMapReadData)
.Build();
displayTexture = GetNode("Sprite").Texture as ImageTexture;
}public override void _Process(double delta) {
time += delta;// Because of our double buffer + swap + double buffer, we're back to TrailMapWriteData
computeManager.UpdateBuffer((int) Buffers.TrailMapWriteData, trailMapReadData);computeManager.UpdateBuffer((int) Buffers.AgentParams, agentManager.settings with {
delta = (float) delta, time = (float) time,
});computeManager.UpdateBuffer((int) Buffers.DiffuseParams, diffusionManager.settings with {
delta = (float) delta
});// Execute the pipeline
computeManager.Execute();trailMapReadData = computeManager.GetDataFromBuffer((int) Buffers.TrailMapReadData);
// Update the texture
displayTexture.Update(
Image.CreateFromData(width, height, false, Image.Format.Rgba8, trailMapReadData)
);
}
```## Slime
Heavily used: [Coding Adventure: Ant and Slime Simulations](https://www.youtube.com/watch?v=X-iSQQgOd1A) by Sebastian
Lague
for learning / foundation.Updates:
- [x] Added mouse behavior to allow drawing slime

## Life
Heavily inspired by: https://particle-life.com/
Todo
- [ ] Spend more time on this one to figure out how to optimize the behavior.
- Right now it compares every particle to every other particle while executing the compute shader, which is crazy.
- [ ] Add a UI for modifying the Attraction Matrix and how many types of particles there are.Not sure that using MultiMesh2D is the right approach either.
