Files
wgpu/examples/boids/boids.comp
Mason 76076d31cf Adds compute-boids example from gpuweb demos
Updates for boids example

Rename example folder
Use chunks_muts when creating initial_particles data
No need for depth
Syntax and minor changes

calculate multiple particles in single compute unit

updates boids example to use framework impl

removed code

fix gpu invocations constants
2019-12-29 12:17:14 -08:00

78 lines
2.3 KiB
Plaintext

#version 450
// this shader expects NUM_PARTICLES and PARTICLES_PER_GROUP
// defines to be inserted by main.rs
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;
}