mirror of
https://github.com/Dark98/SliceBeam.git
synced 2026-07-03 00:38:53 +00:00
Public source code release
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
#version 300 es
|
||||
|
||||
precision highp float;
|
||||
|
||||
uniform vec4 top_color;
|
||||
uniform vec4 bottom_color;
|
||||
uniform vec2 resolution;
|
||||
uniform float time;
|
||||
uniform float progress;
|
||||
|
||||
in vec2 tex_coord;
|
||||
|
||||
out vec4 fragment_color;
|
||||
|
||||
//
|
||||
// 2-D tiling simplex noise with rotating gradients and analytical derivative.
|
||||
// "vec2 x" is the point (x,y) to evaluate,
|
||||
// "vec2 period" is the desired periods along x and y, and
|
||||
// "float alpha" is the rotation (in radians) for the swirling gradients.
|
||||
// The "float" return value is the noise value, and
|
||||
// the "out vec2 gradient" argument returns the x,y partial derivatives.
|
||||
//
|
||||
// Setting either period to 0.0 or a negative value will skip the wrapping
|
||||
// along that dimension. Setting both periods to 0.0 makes the function
|
||||
// execute about 15% faster.
|
||||
//
|
||||
// Not using the return value for the gradient will make the compiler
|
||||
// eliminate the code for computing it. This speeds up the function
|
||||
// by 10-15%.
|
||||
//
|
||||
// The rotation by alpha uses one single addition. Unlike the 3-D version
|
||||
// of psrdnoise(), setting alpha == 0.0 gives no speedup.
|
||||
//
|
||||
float psrdnoise(vec2 x, vec2 period, float alpha, out vec2 gradient) {
|
||||
|
||||
// Transform to simplex space (axis-aligned hexagonal grid)
|
||||
vec2 uv = vec2(x.x + x.y*0.5, x.y);
|
||||
|
||||
// Determine which simplex we're in, with i0 being the "base"
|
||||
vec2 i0 = floor(uv);
|
||||
vec2 f0 = fract(uv);
|
||||
// o1 is the offset in simplex space to the second corner
|
||||
float cmp = step(f0.y, f0.x);
|
||||
vec2 o1 = vec2(cmp, 1.0-cmp);
|
||||
|
||||
// Enumerate the remaining simplex corners
|
||||
vec2 i1 = i0 + o1;
|
||||
vec2 i2 = i0 + vec2(1.0, 1.0);
|
||||
|
||||
// Transform corners back to texture space
|
||||
vec2 v0 = vec2(i0.x - i0.y * 0.5, i0.y);
|
||||
vec2 v1 = vec2(v0.x + o1.x - o1.y * 0.5, v0.y + o1.y);
|
||||
vec2 v2 = vec2(v0.x + 0.5, v0.y + 1.0);
|
||||
|
||||
// Compute vectors from v to each of the simplex corners
|
||||
vec2 x0 = x - v0;
|
||||
vec2 x1 = x - v1;
|
||||
vec2 x2 = x - v2;
|
||||
|
||||
vec3 iu, iv;
|
||||
vec3 xw, yw;
|
||||
|
||||
// Wrap to periods, if desired
|
||||
if(any(greaterThan(period, vec2(0.0)))) {
|
||||
xw = vec3(v0.x, v1.x, v2.x);
|
||||
yw = vec3(v0.y, v1.y, v2.y);
|
||||
if(period.x > 0.0)
|
||||
xw = mod(vec3(v0.x, v1.x, v2.x), period.x);
|
||||
if(period.y > 0.0)
|
||||
yw = mod(vec3(v0.y, v1.y, v2.y), period.y);
|
||||
// Transform back to simplex space and fix rounding errors
|
||||
iu = floor(xw + 0.5*yw + 0.5);
|
||||
iv = floor(yw + 0.5);
|
||||
} else { // Shortcut if neither x nor y periods are specified
|
||||
iu = vec3(i0.x, i1.x, i2.x);
|
||||
iv = vec3(i0.y, i1.y, i2.y);
|
||||
}
|
||||
|
||||
// Compute one pseudo-random hash value for each corner
|
||||
vec3 hash = mod(iu, 289.0);
|
||||
hash = mod((hash*51.0 + 2.0)*hash + iv, 289.0);
|
||||
hash = mod((hash*34.0 + 10.0)*hash, 289.0);
|
||||
|
||||
// Pick a pseudo-random angle and add the desired rotation
|
||||
vec3 psi = hash * 0.07482 + alpha;
|
||||
vec3 gx = cos(psi);
|
||||
vec3 gy = sin(psi);
|
||||
|
||||
// Reorganize for dot products below
|
||||
vec2 g0 = vec2(gx.x,gy.x);
|
||||
vec2 g1 = vec2(gx.y,gy.y);
|
||||
vec2 g2 = vec2(gx.z,gy.z);
|
||||
|
||||
// Radial decay with distance from each simplex corner
|
||||
vec3 w = 0.8 - vec3(dot(x0, x0), dot(x1, x1), dot(x2, x2));
|
||||
w = max(w, 0.0);
|
||||
vec3 w2 = w * w;
|
||||
vec3 w4 = w2 * w2;
|
||||
|
||||
// The value of the linear ramp from each of the corners
|
||||
vec3 gdotx = vec3(dot(g0, x0), dot(g1, x1), dot(g2, x2));
|
||||
|
||||
// Multiply by the radial decay and sum up the noise value
|
||||
float n = dot(w4, gdotx);
|
||||
|
||||
// Compute the first order partial derivatives
|
||||
vec3 w3 = w2 * w;
|
||||
vec3 dw = -8.0 * w3 * gdotx;
|
||||
vec2 dn0 = w4.x * g0 + dw.x * x0;
|
||||
vec2 dn1 = w4.y * g1 + dw.y * x1;
|
||||
vec2 dn2 = w4.z * g2 + dw.z * x2;
|
||||
gradient = 10.9 * (dn0 + dn1 + dn2);
|
||||
|
||||
// Scale the return value to fit nicely into the range [-1,1]
|
||||
return 10.9 * n;
|
||||
}
|
||||
|
||||
float bounceOut(in float t) {
|
||||
const float a = 4.0 / 11.0;
|
||||
const float b = 8.0 / 11.0;
|
||||
const float c = 9.0 / 10.0;
|
||||
|
||||
const float ca = 4356.0 / 361.0;
|
||||
const float cb = 35442.0 / 1805.0;
|
||||
const float cc = 16061.0 / 1805.0;
|
||||
|
||||
float t2 = t * t;
|
||||
|
||||
return t < a
|
||||
? 7.5625 * t2
|
||||
: t < b
|
||||
? 9.075 * t2 - 9.9 * t + 3.4
|
||||
: t < c
|
||||
? ca * t2 - cb * t + cc
|
||||
: 10.8 * t * t - 20.52 * t + 10.72;
|
||||
}
|
||||
|
||||
vec2 rot(vec2 v, float a){
|
||||
return mat2x2(
|
||||
cos(a), -sin(a),
|
||||
sin(a), cos(a)
|
||||
) * v;
|
||||
}
|
||||
|
||||
float bounceIn(in float t) {
|
||||
return 1.0 - bounceOut(1.0 - t);
|
||||
}
|
||||
|
||||
void main() {
|
||||
float PI = radians(180.0);
|
||||
|
||||
vec2 st = tex_coord;
|
||||
st = rot(st, -PI / 2.0);
|
||||
|
||||
vec2 gradient;
|
||||
float n = psrdnoise(vec2(3.) * st, vec2(0.), 3.0 * time, gradient);
|
||||
float lines = cos((st.x + n * 0.05 + progress * 0.8 + 0.1) * PI);
|
||||
|
||||
if (tex_coord.y < 0.1 + progress * 0.9) {
|
||||
fragment_color = bottom_color;
|
||||
} else {
|
||||
fragment_color = mix(top_color, bottom_color, bounceIn(lines * 0.5 + 0.5));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user