koel/resources/assets/js/visualizers/fluid-cube/shaders.ts
2024-10-14 00:37:01 +07:00

110 lines
2.9 KiB
TypeScript

export default {
vertex: (cubeSize: number) => `
attribute vec3 a_pos;
uniform vec2 u_res;
uniform float u_frame;
uniform int u_spectrumValue[128];
varying float v_frame;
varying vec3 vv_pos;
void main () {
v_frame = u_frame;
float pi = 3.141592653589793;
float rad = u_frame / 2.0 / 180.0 * pi;
int spectrumIndex = 12 + int(mod(a_pos.x + ${Math.floor(cubeSize / 2)}.0, ${cubeSize}.0) + mod(a_pos.y + ${Math.floor(cubeSize / 2)}.0, ${cubeSize ** 2}.0) + (a_pos.z + ${Math.floor(cubeSize / 2)}.0) / ${cubeSize ** 2}.0);
float value = float(u_spectrumValue[spectrumIndex]) / 100.0;
vec3 v_pos = a_pos;
vec3 t = vec3(1, 1, 1);
vv_pos = v_pos;
float dist = abs(${Math.floor(cubeSize / 2)}.0 - sqrt(vv_pos.x * vv_pos.x + vv_pos.y * vv_pos.y + vv_pos.z * vv_pos.z));
t.x = v_pos.x * cos(rad) + v_pos.z * sin(rad);
t.y = v_pos.y;
t.z = - v_pos.x * sin(rad) + v_pos.z * cos(rad);
v_pos = t;
t.x = v_pos.x * cos(rad) - v_pos.y * sin(rad);
t.y = v_pos.x * sin(rad) + v_pos.y * cos(rad);
t.z = v_pos.z;
v_pos = t;
t.x = v_pos.x;
t.y = v_pos.y * cos(rad) - v_pos.z * sin(rad);
t.z = v_pos.y * sin(rad) + v_pos.z * cos(rad);
v_pos = t;
v_pos.z -= 20.0;
// Make reaction on spectrum
v_pos.z += value * dist;
v_pos.y += value / 100.0;
v_pos.x += sin(u_frame / 30.0 + v_pos.y / 4.0) * 1.2;
v_pos.y += cos(u_frame / 20.0 + v_pos.z / 5.0) * 1.0;
v_pos.x /= v_pos.z;
v_pos.y /= v_pos.z;
v_pos.x /= u_res.x / u_res.y;
gl_Position = vec4(v_pos.xy, 0.0, 1.0);
gl_PointSize = dist;
}`,
fragment: () => `
precision mediump float;
uniform vec4 u_color;
varying float v_frame;
varying vec3 vv_pos;
float hue2rgb(float f1, float f2, float hue) {
if (hue < 0.0)
hue += 1.0;
else if (hue > 1.0)
hue -= 1.0;
float res;
if ((6.0 * hue) < 1.0)
res = f1 + (f2 - f1) * 6.0 * hue;
else if ((2.0 * hue) < 1.0)
res = f2;
else if ((3.0 * hue) < 2.0)
res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0;
else
res = f1;
return res;
}
vec3 hsl2rgb(vec3 hsl) {
vec3 rgb;
if (hsl.y == 0.0) {
rgb = vec3(hsl.z); // Luminance
} else {
float f2;
if (hsl.z < 0.5)
f2 = hsl.z * (1.0 + hsl.y);
else
f2 = hsl.z + hsl.y - hsl.y * hsl.z;
float f1 = 2.0 * hsl.z - f2;
rgb.r = hue2rgb(f1, f2, hsl.x + (1.0/3.0));
rgb.g = hue2rgb(f1, f2, hsl.x);
rgb.b = hue2rgb(f1, f2, hsl.x - (1.0/3.0));
}
return rgb;
}
vec3 hsl2rgb(float h, float s, float l) {
return hsl2rgb(vec3(h, s, l));
}
void main () {
float dist = sqrt(vv_pos.x * vv_pos.x + vv_pos.y * vv_pos.y + vv_pos.z * vv_pos.z);
float i_frame = mod(v_frame + dist * 20.0, 360.0);
gl_FragColor = vec4(hsl2rgb((i_frame) / 360.0, 1.0, .5), 1.0);
}`,
}