export const PARAMS = {
power: { value: 8.0, min: 2, max: 16, step: 0.1, label: "Fractal Power", folder: "Structure" },
bailout: { value: 4.0, min: 1, max: 32, step: 0.5, label: "Bailout", folder: "Structure" },
iterations:{ value: 8, min: 2, max: 14, step: 1, label: "Iterations", folder: "Structure" },
glow: { value: 0.6, min: 0, max: 2, step: 0.01, label: "Glow", folder: "Appearance" },
hue: { value: 30, min: 0, max: 360, step: 1, label: "Hue Center", folder: "Appearance" },
};
export const SHARE = { bookmarked: ["power","bailout","iterations","glow","hue"] };
export function shaderUniforms(params, seed) {
return {
u_power: { value: params.power },
u_bailout: { value: params.bailout },
u_iterations: { value: params.iterations },
u_glow: { value: params.glow },
u_hue: { value: params.hue },
};
}
export function shaderAnimate(uniforms, params, time) {
uniforms.u_power.value = params.power;
uniforms.u_bailout.value = params.bailout;
uniforms.u_iterations.value = params.iterations;
uniforms.u_glow.value = params.glow;
uniforms.u_hue.value = params.hue;
}
export function fragmentShader() {
return `
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_power;
uniform float u_bailout;
uniform float u_iterations;
uniform float u_glow;
uniform float u_hue;
float DE(vec3 p) {
vec3 z = p;
float dr = 1.0;
float r = 0.0;
for (int i = 0; i < 14; i++) {
if (float(i) >= u_iterations) break;
r = length(z);
if (r > u_bailout) break;
float theta = acos(z.z / r);
float phi = atan(z.y, z.x);
dr = pow(r, u_power - 1.0) * u_power * dr + 1.0;
float zr = pow(r, u_power);
theta *= u_power;
phi *= u_power;
z = zr * vec3(sin(theta) * cos(phi), sin(phi) * sin(theta), cos(theta));
z += p;
}
return 0.5 * log(r) * r / dr;
}
vec3 palette(float t, float baseHue) {
float h = (baseHue / 360.0 + t * 0.4);
vec3 a = vec3(0.5);
vec3 b = vec3(0.5);
vec3 c = vec3(1.0);
vec3 d = vec3(0.00, 0.10, 0.20) + h;
return a + b * cos(6.2831853 * (c * t + d));
}
void main() {
vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution) / u_resolution.y;
vec3 ro = vec3(2.5 * cos(u_time * 0.2), 0.5, 2.5 * sin(u_time * 0.2));
vec3 ta = vec3(0.0);
vec3 ww = normalize(ta - ro);
vec3 uu = normalize(cross(vec3(0.0, 1.0, 0.0), ww));
vec3 vv = cross(ww, uu);
vec3 rd = normalize(uv.x * uu + uv.y * vv + 1.5 * ww);
float t = 0.0;
float steps = 0.0;
bool hit = false;
for (int i = 0; i < 200; i++) {
vec3 p = ro + rd * t;
float d = DE(p);
if (d < 0.0005) { hit = true; break; }
if (t > 8.0) break;
t += d;
steps += 1.0;
}
vec3 col = vec3(0.02, 0.02, 0.04);
if (hit) {
col = palette(0.5 + 0.5 * cos(t * 1.0), u_hue);
}
col += u_glow * vec3(steps / 200.0) * palette(steps / 200.0, u_hue);
col = pow(col, vec3(1.0 / 2.2));
gl_FragColor = vec4(col, 1.0);
}
`;
}