120 lines
4.8 KiB
GLSL
120 lines
4.8 KiB
GLSL
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// ) ( //
|
|
// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
|
|
// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
|
|
// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
|
|
// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
|
|
// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
|
|
// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
|
|
// |__/ //
|
|
// Copyright (c) 2021 Simon Schneegans //
|
|
// Released under the GPLv3 or later. See LICENSE file for details. //
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// The content from common.glsl is automatically prepended to each shader effect.
|
|
|
|
uniform bool uAdditiveBlending;
|
|
uniform vec2 uSeed;
|
|
uniform float uScale;
|
|
uniform float uLineWidth;
|
|
uniform vec4 uGlowColor;
|
|
uniform vec4 uLineColor;
|
|
|
|
// This methods generates a procedural hexagonal pattern. It returns four values:
|
|
// result.xy: This contains cell-relative coordinates for the given point.
|
|
// [0, 0] is in the center of a cell, [0, 1] at the upper edge,
|
|
// [sqrt(4.0 / 3.0), 0] at the right tip and so on.
|
|
// result.z: This is the distance to the closest edge. This is used for shrinking
|
|
// of the tiles and the sharp overlay lines.
|
|
// result.w: This is the distance to the closest cell center. This is used for
|
|
// the glow effect.
|
|
vec4 getHexagons(vec2 p) {
|
|
|
|
// Length of a cell's edge.
|
|
const float edgeLength = sqrt(4.0 / 3.0);
|
|
|
|
// The hexgrid repeats after this distance.
|
|
const vec2 scale = vec2(3.0 * edgeLength, 2.0);
|
|
|
|
// This is a repeating grid of scale-sized cells. Y-values are in the
|
|
// interval [-1...1], X-value in [-1.5*edgeLength...1.5*edgeLength].
|
|
vec2 a = mod(p, scale) - scale * 0.5;
|
|
vec2 aAbs = abs(a);
|
|
|
|
// This is the same as above, but offset by half scale.
|
|
vec2 b = mod(p + scale * 0.5, scale) - scale * 0.5;
|
|
vec2 bAbs = abs(b);
|
|
|
|
// Distance to closer edge, diagonally or horizontally.
|
|
// Once for cell set A and once for cell set B.
|
|
float distA = max(aAbs.x / edgeLength + aAbs.y * 0.5, aAbs.y);
|
|
float distB = max(bAbs.x / edgeLength + bAbs.y * 0.5, bAbs.y);
|
|
|
|
// Minimum of both is distance to closest edge.
|
|
float dist = 1.0 - min(distA, distB);
|
|
|
|
// We use the radial distance to the center for glow.
|
|
float glow = min(dot(a, a), dot(b, b)) / 1.5;
|
|
|
|
// Take cell-relative coordinates from the closer cell.
|
|
vec2 cellCoords = distA < distB ? a : b;
|
|
|
|
return vec4(cellCoords, dist, glow);
|
|
}
|
|
|
|
void main() {
|
|
// We simply inverse the progress for opening windows.
|
|
float progress = uForOpening ? 1.0 - uProgress : uProgress;
|
|
|
|
// Add some smooth noise to the progress so that not every tile behaves the
|
|
// same.
|
|
float noise = simplex2D(iTexCoord.st + uSeed);
|
|
progress = clamp(mix(noise - 1.0, noise + 1.0, progress), 0.0, 1.0);
|
|
|
|
// glowProgress fades in in the first half of the animation, tileProgress fades
|
|
// in in the second half.
|
|
float glowProgress = smoothstep(0, 1, clamp(progress / 0.5, 0, 1));
|
|
float tileProgress = smoothstep(0, 1, clamp((progress - 0.5) / 0.5, 0, 1));
|
|
|
|
vec2 texScale = 0.1 * uSize / uScale;
|
|
vec4 hex = getHexagons(iTexCoord.st * texScale);
|
|
|
|
vec4 oColor = vec4(0.0);
|
|
|
|
// Crop outer parts of the shrinking tiles.
|
|
if (tileProgress < hex.z) {
|
|
|
|
// Make the tiles shrink by offsetting the texture lookup towards the edge
|
|
// of the cell.
|
|
vec2 lookupOffset = tileProgress * hex.xy / texScale / (1.0 - tileProgress);
|
|
oColor = getInputColor(iTexCoord.st + lookupOffset);
|
|
|
|
vec4 glow = uGlowColor;
|
|
vec4 line = uLineColor;
|
|
|
|
// For the glow, we accumulate a few exponentially scaled versions of hex.w.
|
|
glow.a *= pow(hex.w, 20.0) * 10.0 + pow(hex.w, 10.0) * 5.0 + pow(hex.w, 2.0) * 0.5;
|
|
|
|
// Using step(uLineWidth, hex.z) would be simpler, but the below creates some
|
|
// fake antialiasing.
|
|
line.a *= 1.0 - smoothstep(uLineWidth * 0.02 * 0.5, uLineWidth * 0.02, hex.z);
|
|
|
|
// Fade in the glowing lines.
|
|
glow.a *= glowProgress;
|
|
line.a *= glowProgress;
|
|
|
|
// Do not add the hexagon lines onto transparent parts of the window.
|
|
glow *= oColor.a;
|
|
line *= oColor.a;
|
|
|
|
if (uAdditiveBlending) {
|
|
oColor.rgb += glow.rgb * glow.a;
|
|
oColor.rgb += line.rgb * line.a;
|
|
} else {
|
|
oColor.rgb = mix(oColor.rgb, glow.rgb, glow.a);
|
|
oColor.rgb = mix(oColor.rgb, line.rgb, line.a);
|
|
}
|
|
}
|
|
|
|
setOutputColor(oColor);
|
|
} |