COSC-3P98-Assigment-3/include/shaders/physics.comp

77 lines
1.8 KiB
Plaintext

#ifdef __cplusplus
#include <string>
std::string shader_physics = R"("
#version 460
// execute 1 shader per particle. 128 executions per group
layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
// due to byte alignment, storing pos and dir as vec4 was required anyways.
struct particle_t {
vec4 pos;
vec4 dir;
};
const int offset_size = 8192;
const float SPEED = 1.0f;
const float SPEED_FACTOR = 25.0f;
const float BOUNCE_FACTOR = 0.75f;
const float SPREAD = 4.5f;
const float particle_lifetime = 120.0f;
const vec2 p_min = vec2(-50, -50);
const vec2 p_max = vec2(50, 50);
const vec3 inital_pos = vec3(0.0f, 1.0f, 0.0f);
const vec4 inital_dir = vec4(0.0f, 1.0f, 0.0f, 0.0f);
const vec4 GRAVITY = vec4(0.0, -9.8, 0.0, 0.0);
layout (std430, binding=0) buffer particle_buffer {
particle_t particles[];
};
layout (std430, binding=1) buffer offset_buffer {
vec4 offsets[offset_size];
};
uniform float deltaSeconds;
void resetParticle(uint i, float w) {
particles[i].dir = inital_dir * SPEED_FACTOR + offsets[i % offset_size] * SPREAD;
particles[i].pos = vec4(inital_pos, w);
}
bool checkBounds(vec2 pos) {
return pos.x > p_min.x && pos.y > p_min.y && pos.x < p_max.x && pos.y < p_max.y;
}
void main() {
uint i = gl_GlobalInvocationID.x;
vec4 pos = particles[i].pos;
vec4 dir = particles[i].dir;
dir.w += deltaSeconds;
if (dir.w > particle_lifetime) {
resetParticle(i, pos.w);
return;
}
pos += vec4(dir.xyz * SPEED * deltaSeconds, 0.0);
dir += vec4(GRAVITY.xyz * deltaSeconds, 0.0);
if (pos.y < 0 && checkBounds(pos.xy)) {
dir.y = -dir.y * BOUNCE_FACTOR;
pos.y = 0;
}
particles[i].dir = dir;
particles[i].pos = pos;
if (pos.y < -50)
resetParticle(i, pos.w);
}
")";
#endif