137 lines
3.6 KiB
GLSL
137 lines
3.6 KiB
GLSL
#version 300 es
|
|
|
|
precision highp float;
|
|
|
|
layout(location = 0) in vec2 inPosition;
|
|
layout(location = 1) in vec2 inVelocity;
|
|
layout(location = 2) in float inTime;
|
|
layout(location = 3) in float inDuration;
|
|
|
|
out vec2 outPosition;
|
|
out vec2 outVelocity;
|
|
out float outTime;
|
|
out float outDuration;
|
|
|
|
out float alpha;
|
|
|
|
uniform float reset;
|
|
uniform float time;
|
|
uniform float deltaTime;
|
|
uniform vec2 size;
|
|
uniform float r;
|
|
uniform float seed;
|
|
uniform float noiseScale;
|
|
uniform float noiseSpeed;
|
|
uniform float noiseMovement;
|
|
uniform float dampingMult;
|
|
uniform float forceMult;
|
|
uniform float velocityMult;
|
|
uniform float longevity;
|
|
uniform float maxVelocity;
|
|
|
|
float rand(vec2 n) {
|
|
return fract(sin(dot(n,vec2(12.9898,4.1414-seed*.42)))*43758.5453);
|
|
}
|
|
vec4 loop(vec4 p) {
|
|
p.xy = fract(p.xy / noiseScale) * noiseScale;
|
|
p.zw = fract(p.zw / noiseScale) * noiseScale;
|
|
return p;
|
|
}
|
|
vec3 loop(vec3 p) {
|
|
p.xy = fract(p.xy / noiseScale) * noiseScale;
|
|
return p;
|
|
}
|
|
float mod289(float x){return x-floor(x*(1./(289.+seed)))*(289.+seed);}
|
|
vec4 mod289(vec4 x){return x-floor(x*(1./(289.+seed)))*(289.0+seed);}
|
|
vec4 perm(vec4 x){return mod289(((x*34.)+1.)*x);}
|
|
float noise(vec3 p){
|
|
|
|
vec3 a = floor(p);
|
|
vec3 d = p - a;
|
|
d = d * d * (3. - 2. * d);
|
|
|
|
vec4 b = a.xxyy + vec4(0., 1., 0., 1.);
|
|
vec4 k1 = perm(loop(b.xyxy));
|
|
vec4 k2 = perm(loop(k1.xyxy + b.zzww));
|
|
|
|
vec4 c = k2 + a.zzzz;
|
|
vec4 k3 = perm(c);
|
|
vec4 k4 = perm(c + 1.0);
|
|
|
|
vec4 o3 = fract(k4 / 41.0) * d.z + fract(k3 / 41.0) * (1.0 - d.z);
|
|
vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
|
|
|
|
return o4.y * d.y + o4.x * (1.0 - d.y);
|
|
}
|
|
vec3 grad(vec3 p) {
|
|
const vec2 e = vec2(.1, .0);
|
|
return vec3(
|
|
noise(loop(p + e.xyy)) - noise(loop(p - e.xyy)),
|
|
noise(loop(p + e.yxy)) - noise(loop(p - e.yxy)),
|
|
noise(loop(p + e.yyx)) - noise(loop(p - e.yyx))
|
|
) / (2.0 * e.x);
|
|
}
|
|
vec3 curlNoise(vec3 p) {
|
|
p.xy /= size;
|
|
p.x *= (size.x / size.y);
|
|
p.xy = fract(p.xy);
|
|
p.xy *= noiseScale;
|
|
|
|
const vec2 e = vec2(.01, .0);
|
|
return grad(loop(p)).yzx - vec3(
|
|
grad(loop(p + e.yxy)).z,
|
|
grad(loop(p + e.yyx)).x,
|
|
grad(loop(p + e.xyy)).y
|
|
);
|
|
}
|
|
|
|
void main() {
|
|
vec2 position = inPosition;
|
|
vec2 velocity = inVelocity;
|
|
float particleDuration = inDuration;
|
|
float particleTime = inTime + deltaTime * particleDuration / longevity;
|
|
|
|
if (reset > 0.) {
|
|
particleTime = rand(vec2(-94.3, 83.9) * vec2(gl_VertexID, gl_VertexID));
|
|
particleDuration = .5 + 2. * rand(vec2(gl_VertexID) + seed * 32.4);
|
|
position = size * vec2(
|
|
rand(vec2(42., -3.) * vec2(cos(float(gl_VertexID) - seed), gl_VertexID)),
|
|
rand(vec2(-3., 42.) * vec2(time * time, sin(float(gl_VertexID) + seed)))
|
|
);
|
|
velocity = vec2(0.);
|
|
} else if (particleTime >= 1.) {
|
|
particleTime = 0.0;
|
|
particleDuration = .5 + 2. * rand(vec2(gl_VertexID) + position);
|
|
velocity = vec2(0.);
|
|
}
|
|
|
|
float msz = min(size.x, size.y);
|
|
vec2 force = normalize(curlNoise(
|
|
vec3(
|
|
position + time * (noiseMovement / 100. * msz),
|
|
time * noiseSpeed + rand(position) * 2.5
|
|
)
|
|
).xy);
|
|
|
|
velocity += force * forceMult * deltaTime * msz * .1;
|
|
velocity *= dampingMult;
|
|
float vlen = length(velocity);
|
|
float maxVelocityPx = maxVelocity / 100. * msz;
|
|
if (vlen > maxVelocityPx) {
|
|
velocity = velocity / vlen * maxVelocityPx;
|
|
}
|
|
|
|
position += velocity * velocityMult * deltaTime;
|
|
position = fract(position / size) * size;
|
|
|
|
outPosition = position;
|
|
outVelocity = velocity;
|
|
outTime = particleTime;
|
|
outDuration = particleDuration;
|
|
|
|
gl_PointSize = r;
|
|
gl_Position = vec4((position / size * 2.0 - vec2(1.0)), 0.0, 1.0);
|
|
alpha = sin(particleTime * 3.14) * (.6 + .4 * rand(vec2(gl_VertexID)));
|
|
}
|
|
|
|
// @dkaraush |