17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-22 23:31:10 +02:00
Files
maszyna/shaders/particles_precipitation.vert

59 lines
2.1 KiB
GLSL

// rain and snow of the gpu (opengl46_gpu_particles): a streak per drop or flake the compute pass added to the draw, from where
// it is to where it was a moment ago as the moving camera saw it, turned to face the camera, rounded at its ends. a particle
// thinner than a pixel and a half is drawn that wide and as much fainter, so the distant ones don't flicker
layout(location = 0) in vec4 v_place; // xyz: the head, metres from the camera (world axes), w: width
layout(location = 1) in vec4 v_shape; // xyz: from the head to the tail
layout(location = 2) in vec4 v_color; // rgb: lit colour, a: opacity
out vec4 f_pos;
out vec4 f_color;
// x: across the streak, y: along it from the head, metres; z: its radius, w: its length
out vec4 f_streak;
out float f_soft;
out vec4 f_clip_pos;
out vec4 f_clip_future_pos;
#include <common>
// x: metres it fades out over in front of the scene, 0: none
layout(location = 0) uniform vec4 particle_soft;
// x: width of a pixel one metre in front of the camera, metres
layout(location = 1) uniform vec4 particle_pixel;
void main()
{
vec3 head = (modelview * vec4(v_place.xyz, 1.0)).xyz;
vec3 axis = mat3(modelview) * v_shape.xyz;
float span = length(axis);
vec3 direction = (span > 1e-5) ? axis / span : vec3(0.0, -1.0, 0.0);
vec3 middle = head + 0.5 * axis;
float width = v_place.w;
float alpha = v_color.a;
float least = 1.5 * particle_pixel.x * max(-middle.z, 1e-3);
if (width < least)
{
alpha *= width / least;
width = least;
}
float radius = 0.5 * width;
vec3 side = cross(direction, normalize(-middle));
float sidelength = length(side);
side = (sidelength > 1e-4) ? side / sidelength : vec3(1.0, 0.0, 0.0);
// a triangle strip of four corners: across, along
vec2 corner = vec2(float(gl_VertexID & 1), float(gl_VertexID >> 1));
float across = (corner.x * 2.0 - 1.0) * radius;
float along = mix(-radius, span + radius, corner.y);
f_pos = vec4(head + direction * along + side * across, 1.0);
f_clip_pos = projection * f_pos;
f_clip_future_pos = (projection * future) * f_pos;
gl_Position = f_clip_pos;
f_streak = vec4(across, along, radius, span);
f_color = vec4(v_color.rgb, alpha);
f_soft = particle_soft.x;
}