67 lines
1.7 KiB
GLSL
67 lines
1.7 KiB
GLSL
#version 450
|
|
|
|
layout(set = 0, binding = 0) uniform SceneData
|
|
{
|
|
mat4 view;
|
|
mat4 proj;
|
|
mat4 viewproj;
|
|
} sceneData;
|
|
|
|
struct Particle
|
|
{
|
|
vec4 pos_age;
|
|
vec4 vel_life;
|
|
vec4 color;
|
|
vec4 misc;
|
|
};
|
|
|
|
layout(std430, set = 1, binding = 0) readonly buffer ParticlePool
|
|
{
|
|
Particle particles[];
|
|
} pool;
|
|
|
|
layout(location = 0) out vec4 v_color;
|
|
layout(location = 1) out vec2 v_uv;
|
|
|
|
vec2 quad_corner(uint vidx)
|
|
{
|
|
// Two triangles (6 verts) in a unit quad centered at origin.
|
|
const vec2 corners[6] = vec2[6](
|
|
vec2(-0.5, -0.5),
|
|
vec2( 0.5, -0.5),
|
|
vec2( 0.5, 0.5),
|
|
vec2(-0.5, -0.5),
|
|
vec2( 0.5, 0.5),
|
|
vec2(-0.5, 0.5)
|
|
);
|
|
return corners[vidx % 6u];
|
|
}
|
|
|
|
void main()
|
|
{
|
|
uint particle_index = gl_InstanceIndex;
|
|
Particle p = pool.particles[particle_index];
|
|
|
|
float life = max(p.vel_life.w, 1e-6);
|
|
float remaining = clamp(p.pos_age.w, 0.0, life);
|
|
float t = remaining / life; // remaining fraction
|
|
|
|
float fade_out = smoothstep(0.0, 0.15, t);
|
|
float fade_in = smoothstep(0.0, 0.05, 1.0 - t);
|
|
float fade = fade_in * fade_out;
|
|
|
|
vec2 corner = quad_corner(uint(gl_VertexIndex));
|
|
v_uv = corner + vec2(0.5);
|
|
|
|
// Camera right/up in world-local space from view matrix rows.
|
|
vec3 cam_right = vec3(sceneData.view[0][0], sceneData.view[1][0], sceneData.view[2][0]);
|
|
vec3 cam_up = vec3(sceneData.view[0][1], sceneData.view[1][1], sceneData.view[2][1]);
|
|
|
|
float size = max(p.misc.x, 0.0);
|
|
vec3 pos = p.pos_age.xyz + (cam_right * corner.x + cam_up * corner.y) * size;
|
|
|
|
v_color = vec4(p.color.rgb * fade, p.color.a * fade);
|
|
gl_Position = sceneData.viewproj * vec4(pos, 1.0);
|
|
}
|
|
|