fragmentShader = {
const shader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(shader, `
precision highp float;
const float pi = 3.14159265359;
const float width = ${(width + 28).toFixed(1)}; // TODO uniform?
const float height = ${height.toFixed(1)}; // TODO uniform?
const vec2 center = vec2(width, height) / 2.0;
float value(float x, float y) {
return (${value});
}
vec3 cubehelix(vec3 c) {
float a = c.y * c.z * (1.0 - c.z);
float cosh = cos(c.x + pi / 2.0);
float sinh = sin(c.x + pi / 2.0);
return vec3(
(c.z + a * (1.78277 * sinh - 0.14861 * cosh)),
(c.z - a * (0.29227 * cosh + 0.90649 * sinh)),
(c.z + a * (1.97294 * cosh))
);
}
vec3 cubehelixDefault(float t) {
return cubehelix(vec3(mix(300.0 / 180.0 * pi, -240.0 / 180.0 * pi, t), 0.5, t));
}
vec3 cubehelixRainbow(float t) {
if (t < 0.0 || t > 1.0) t -= floor(t);
float ts = abs(t - 0.5);
return cubehelix(vec3((360.0 * t - 100.0) / 180.0 * pi, 1.5 - 1.5 * ts, 0.8 - 0.9 * ts));
}
void main(void) {
vec2 z = (gl_FragCoord.xy - center) / ${scale.toFixed(1)};
gl_FragColor = vec4(cubehelixRainbow(value(z.x, z.y)), 1.0);
}
`);
gl.compileShader(shader);
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) return shader;
throw new Error(gl.getShaderInfoLog(shader));
}