mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
79 lines
2.3 KiB
Plaintext
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;
|
|
}
|