Files
Cool-shaders-and-stuff/shaders/mandelbrot.frag
2026-01-13 20:07:21 +00:00

75 lines
2.0 KiB
GLSL

#version 100
precision highp float;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_zoom;
uniform vec2 u_center; // Unused if using perturbation?
uniform sampler2D u_ref_orbit; // Stores Reference Z (Real=Luminance, Imag=Alpha)
// Sliders
uniform float u_exponent; // Perturbation usually assumes Z^2.
uniform vec2 u_z_start;
uniform vec2 u_c_offset;
// Complex Math helpers
vec2 complex_mul(vec2 a, vec2 b) {
return vec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x);
}
vec2 complex_sq(vec2 a) {
return vec2(a.x*a.x - a.y*a.y, 2.0*a.x*a.y);
}
void main() {
// Current pixel coordinate relative to screen center
vec2 p = (gl_FragCoord.xy - u_resolution.xy * 0.5) / u_resolution.y;
// Delta C (Difference from Reference Point)
vec2 dc = p / u_zoom;
// Apply C Offset from sliders (as Delta C)
dc += u_c_offset;
// Initial Delta Z
vec2 dz = vec2(0.0);
float iter = 0.0;
float max_iter = 1000.0;
for (float i = 0.0; i < 1000.0; i++) {
// Fetch Reference Z from Texture
vec4 ref = texture2D(u_ref_orbit, vec2((i + 0.5) / 1024.0, 0.5));
// Decode Range [0, 1] -> [-4, 4]
// Z = Val * 8 - 4
// Use R and G channels (was R and A)
vec2 Zn = vec2(ref.r * 8.0 - 4.0, ref.g * 8.0 - 4.0);
// dz = 2*Zn*dz + dz^2 + dc
vec2 two_Zn_dz = complex_mul(2.0 * Zn, dz);
vec2 dz_sq = complex_sq(dz);
dz = two_Zn_dz + dz_sq + dc; // Perturbation formula
// Check Escape: |Zn + dz|^2 > 4
vec2 current_z = Zn + dz;
if (dot(current_z, current_z) > 4.0) {
iter = i;
break;
}
}
// Coloring
float t = iter / max_iter;
// Standard Black Interior
if (iter >= 999.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
} else {
// Original "Generic" Palette
gl_FragColor = vec4(sqrt(t), t*t, sin(t * 3.14), 1.0);
}
}