Simulating 100K Boids with Compute Shaders in Godot - Part 1

preview_player
Показать описание
This is a tutorial on how to simulate Boids with a compute shader in Godot. Resource links below.
Please provide comments on how I can improve in the future.

Other compute shader examples:

Intro (0:00)
Overview (0:52)
Setup (3:45)
Particle Shader (6:23)
CPU Simutation (10:29)
GPU Simulation (15:20)
Outro (27:59)
Рекомендации по теме
Комментарии
Автор

This is great! Thanks so much for putting this out!

rob-not-bob
Автор

Thank you sooo much for sharing, this is what I need to do as well.
Same for me, I've been experimenting with boids for years but I'm not that comfortable with compute shaders yet.

huraqan
Автор

I think this code for generating the velocity is better:
```
* 2 * PI) * sqrt(randf()) * max_vel)
```
since it gives a uniformly distributed random vector in the closed ball of radius `max_vel`. The `squrt` here makes sure that the velocities are not specifically concentrated around 0.
If we want a vector of size `max_vel` exactly, we can just remove the `sqrt(randf())`.

The code in the video is also uniformly distributed, but in a square where the maximum velocity is actually `sqrt(2)*max_vel`. The normalization in the simulation ameliorates this, but it means that at the beginning of the simulation more boids will be moving diagonally.


One thing for the shader itself: It's unnecessary to divide by the number of friends/avoids there for the velocity/separation, since that value will be normalized after the fact either way. We only need the number of friends/avoids to realize whether we have encountered any.


One problem I don't immediately have an idea for is that the world is a torus, but distance and thus the closest environment of the boids is calculated as on a plane, meaning that the swarm “tears” at the edges of the screen. I guess it should be simple enough…
Ah, all differences between vectors should be replaced with calls to this function:
```glsl
vec2 cdiff (vec2 a, vec2 b) {
float mx = params.viewport_x;
float hx = mx / 2;
float my = params.viewport_y;
float hy = my / 2;
return vec2(mod(a.x - b.x + hx, mx) - hx, mod(a.y - b.y + hy, my) - hy);
}
```

and instead of `distance` use
```glsl
float cdist (vec2 a, vec2 b) {
return length(cdiff(a, b));
//vec2 diff = cdiff(a, b);
//return sqrt(diff.x * diff.x + diff.y * diff.y);
}
```



Thank you for the video! I may be able to do the math for boid simulation, but I am really not versed with compute shaders.

AntsanParcher
Автор

Thanks! Using textures like this definitely looks much more ergonomic than passing uniform storage buffers.

jRsqILVOY
Автор

This was exactly what I've been looking for! You've more than earned a sub.

dfunited
Автор

Awesome quality content, very helpful in navigating compute shaders!!

ericalfaro
Автор

This is awesome, hit all of the points I've been thinking I'll need to implement on my project

dantheman
Автор

This is cool, I wanna make a zen-like aquarium simulator now like you'd see in flash games from the mid 2000's where you feed them pellets to get coins or whatever.

wolcamophone
Автор

Extremely interesting series! Compute shaders are such different way to approach algos and how to deal with data.

wukerplank
Автор

Cool. I followed along and at the end modified it to be a gravity simulator and it worked, and was thousands of times faster than my cpu version.
For a lot of the tutorial I felt like I was copying and only barely understanding, but I guess the vid would be extremely long if you explained it all. Compute shader boilerplate seems really excessive.
Looking forward to future parts.

keepeetron
Автор

An idea I had while watching the end was trying to come up with some way to colour by affinity. I'm not sure what the best way to achieve it would be. The simplest implementation I can think of is to have some arbitrary proportion of boids be "hero" boids with a fixed colour value, then have their flockmates' colours shift in that direction, but this doesn't seem like a good solution, as it makes no guarantees that a local area will have one "hero", rather than none or many. It would be better to have local flocks settle on a colour in some decentralised emergent fashion. I suppose it could use similar separation and cohesion mechanics to the movement of the boids: "steer" colour towards local neighbours with a similar heading, and away from mid-range neighbours and those with a different heading.

I guess it might just turn out looking fairly similar to the direction colouring.


This seems like the sort of thing I assume I can quickly throw together, then proceed to spend hours and hours struggling with.

TheJamesM
Автор

Fantastic and helpful devlog series! I am currently messing around with fluid simulation with compute shaders which is surprisingly similar to Boids algorithim. just instead of "alignment" its called "viscosity". Was using image Store in compute shader to render to a writable texture cause I thought it would be simpler and more performant to do everything in one dispatch. but am suprised how much faster the fixed function dedicated rasterization pipeline the GPUParticles2d uses is. Im guessing the flexibility of the hardware compute shaders utilize come at a cost?

funut
Автор

Very cool can you please make a video for compute shaders but with slime mould that would be very cool and also a good video for compute shaders and textures.

ahmadrazek
Автор

hello! thank you so much for creating this. I've just started learning about compute shaders and I'm using this video as a starting point to step-by-step decompose different aspects of the engine and using shaders, particle shaders, etc. I'm trying to understand the transformation matrix at the moment. at 3:40 in your video, the first column states:
RotZ * ScaleX
RotZ * ScaleX.
've used a matrix calculator and assumed that the scaling in X and Y are not uniform (e.g, 1 and 2), the result for the first column is, if represented the way you did it:
RotZ * ScaleX
RotZ * ScaleY
Is there something I'm missing or is it a mistake in your table? I'm just trying to wrap my head around it as it seems very useful for implementing custom particle systems.

Thanks again for the amazing video (that forced me to think about this stuff :) ) and keep up the good work!

chegusta
Автор

I've been working on a compute shader project, and I was wondering if you might know how to get mouse position use that in a compute shader. I got it working in a normal shader but I think I'm doing something wrong. I seen you mention that in the end and I desperately need the answer for that to continue on my project. I've been stuck for over a week

jeremiahmcelroy
Автор

I got the error "Can't create a shader from an errored bytecode. Check errors in source bytecode" and was going crazy trying to figure it out. I eventually just closed Godot and reopened it and it worked!

dw
Автор

really nice stuff ! do you think this could work with y sorted sprites too?

-lunte.
Автор

Does this mean I can make a Huegene-esque predator prey boids ecosystem with coevolving colors vs preferences?

revimfadli
Автор

May I know the glsl extension on vscode

simplycodee