Files
wgpu/examples/boids/boids.comp
2020-04-18 01:04:28 -02:30

79 lines
2.3 KiB
Plaintext

#version 450
// These should match the Rust constants defined in main.rs
#define NUM_PARTICLES 1500
#define PARTICLES_PER_GROUP 64
layout(local_size_x = PARTICLES_PER_GROUP) in;
struct Particle {
vec2 pos;
vec2 vel;
};
layout(std140, set = 0, binding = 0) uniform SimParams {
float deltaT;
float rule1Distance;
float rule2Distance;
float rule3Distance;
float rule1Scale;
float rule2Scale;
float rule3Scale;
} params;
layout(std140, set = 0, binding = 1) buffer SrcParticles {
Particle particles[NUM_PARTICLES];
} srcParticles;
layout(std140, set = 0, binding = 2) buffer DstParticles {
Particle particles[NUM_PARTICLES];
} dstParticles;
void main() {
// https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp
uint index = gl_GlobalInvocationID.x;
if (index >= NUM_PARTICLES) { return; }
vec2 vPos = srcParticles.particles[index].pos;
vec2 vVel = srcParticles.particles[index].vel;
vec2 cMass = vec2(0.0, 0.0);
vec2 cVel = vec2(0.0, 0.0);
vec2 colVel = vec2(0.0, 0.0);
int cMassCount = 0;
int cVelCount = 0;
vec2 pos;
vec2 vel;
for (int i = 0; i < NUM_PARTICLES; ++i) {
if (i == index) { continue; }
pos = srcParticles.particles[i].pos.xy;
vel = srcParticles.particles[i].vel.xy;
if (distance(pos, vPos) < params.rule1Distance) {
cMass += pos;
cMassCount++;
}
if (distance(pos, vPos) < params.rule2Distance) {
colVel -= (pos - vPos);
}
if (distance(pos, vPos) < params.rule3Distance) {
cVel += vel;
cVelCount++;
}
}
if (cMassCount > 0) {
cMass = cMass / cMassCount - vPos;
}
if (cVelCount > 0) {
cVel = cVel / cVelCount;
}
vVel += cMass * params.rule1Scale + colVel * params.rule2Scale + cVel * params.rule3Scale;
// clamp velocity for a more pleasing simulation.
vVel = normalize(vVel) * clamp(length(vVel), 0.0, 0.1);
// kinematic update
vPos += vVel * params.deltaT;
// Wrap around boundary
if (vPos.x < -1.0) vPos.x = 1.0;
if (vPos.x > 1.0) vPos.x = -1.0;
if (vPos.y < -1.0) vPos.y = 1.0;
if (vPos.y > 1.0) vPos.y = -1.0;
dstParticles.particles[index].pos = vPos;
// Write back
dstParticles.particles[index].vel = vVel;
}