nova-shell/modules/hex_wave.frag

104 lines
2.5 KiB
GLSL

#version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
vec2 uResolution;
float uSize;
float uWavePhase;
vec4 uC0;
vec4 uC1;
vec4 uC2;
vec4 uSpinners0;
vec4 uSpinners1;
vec4 uSpinners2;
vec4 uSpinners3;
vec4 uSpinners4;
vec4 uSpinners5;
vec4 uSpinners6;
vec4 uSpinners7;
vec4 uSpinners8;
vec4 uSpinners9;
vec4 uSpinners10;
vec4 uSpinners11;
};
float sdHexFlat(vec2 p, float r) {
const vec3 k = vec3(0.5, 0.8660254, 0.5773503);
p = abs(p);
p -= 2.0 * min(dot(k.yx, p), 0.0) * k.yx;
p -= vec2(clamp(p.x, -k.z * r, k.z * r), r);
return length(p) * sign(p.y);
}
void main() {
vec2 frag = qt_TexCoord0 * uResolution;
float dx = uSize * 1.5;
float dy = uSize * 1.7320508;
float col = round(frag.x / dx);
float yoff = mod(col, 2.0) != 0.0 ? dy * 0.5 : 0.0;
float row = round((frag.y - yoff) / dy);
vec2 center = vec2(col * dx, row * dy + yoff);
// Wave factor
float dist = center.x - uWavePhase;
float wf = exp(-dist * dist / 9000.0);
float baseR = uSize * 0.48;
float inradius = baseR * (1.0 + 0.35 * wf);
// Check spinners
float spinAngle = 0.0;
vec4 spinners[12] = vec4[12](
uSpinners0, uSpinners1, uSpinners2, uSpinners3,
uSpinners4, uSpinners5, uSpinners6, uSpinners7,
uSpinners8, uSpinners9, uSpinners10, uSpinners11
);
for (int i = 0; i < 12; i++) {
if (distance(center, spinners[i].xy) < 1.0) {
spinAngle = spinners[i].z;
break;
}
}
vec2 p = frag - center;
if (spinAngle != 0.0) {
float ca = cos(spinAngle);
float sa = sin(spinAngle);
p = mat2(ca, -sa, sa, ca) * p;
}
float d = sdHexFlat(p, inradius);
if (d > 0.0) {
fragColor = vec4(0.0);
return;
}
// Gradient color
float fx = clamp(center.x / uResolution.x, 0.0, 1.0);
vec3 rgb = fx < 0.5
? mix(uC0.rgb, uC1.rgb, fx * 2.0)
: mix(uC1.rgb, uC2.rgb, (fx - 0.5) * 2.0);
// Alpha from distance to center
float fy = clamp(center.y / uResolution.y, 0.0, 1.0);
float dc = length(vec2(fx - 0.5, fy - 0.5));
float a = 0.03 + dc * 0.06;
// Wave brighten
rgb = min(rgb + vec3(0.3 * wf), vec3(1.0));
a += 0.12 * wf;
// Anti-alias
float aa = 1.0 - smoothstep(-1.0, 0.0, d);
a *= aa;
fragColor = vec4(rgb * a, a) * qt_Opacity;
}