frag.glsl (3160B)
1 /* see LICENSE for licensing details */ 2 #version 460 core 3 4 out vec4 colour; 5 6 uniform uvec2 u_screen_dim; 7 uniform vec2 u_top_left; 8 uniform vec2 u_bottom_right; 9 10 uniform vec2 u_z_n[300]; 11 uniform bool u_use_approx = false; 12 13 const int iterations = 300; 14 const float escape_radius = 4.0; 15 16 /* input: h [0,360] | s,v [0, 1] * 17 * output: rgb [0,1] */ 18 vec3 hsv2rgb(vec3 hsv) 19 { 20 vec3 k = mod(vec3(5, 3, 1) + hsv.x / 60, 6); 21 k = max(min(min(k, 4 - k), 1), 0); 22 return hsv.z - hsv.z * hsv.y * k; 23 } 24 25 vec3 wavelength2rgb(float lambda) 26 { 27 vec3 rgb = vec3(0); 28 float t; 29 /* red */ 30 if (lambda >= 400 && lambda < 410) { 31 t = (lambda - 400) / 10; 32 rgb.x = 0.33 * t - (0.20 * t * t); 33 } else if (lambda >= 410 && lambda < 475) { 34 t = (lambda - 410) / 65; 35 rgb.x = 0.14 - (0.13 * t * t); 36 } else if (lambda >= 545 && lambda < 595) { 37 t = (lambda - 545) / 50; 38 rgb.x = 1.98 * t - ( t * t); 39 } else if (lambda >= 595 && lambda < 650) { 40 t = (lambda - 595) / 65; 41 rgb.x = 0.98 + 0.06 * t - (0.40 * t * t); 42 } else if (lambda >= 650 && lambda < 700) { 43 t = (lambda - 650) / 50; 44 rgb.x = 0.65 - 0.84 * t + (0.20 * t * t); 45 } 46 47 /* green */ 48 if (lambda >= 415 && lambda < 475) { 49 t = (lambda - 415) / 60; 50 rgb.y = + (0.80 * t * t); 51 } else if (lambda >= 475 && lambda < 585) { 52 t = (lambda - 475) / 115; 53 rgb.y = 0.80 + 0.76 * t - (0.80 * t * t); 54 } else if (lambda >= 585 && lambda < 639) { 55 t = (lambda - 585) / 54; 56 rgb.y = 0.84 - 0.84 * t ; 57 } 58 59 /* blue */ 60 if (lambda >= 400 && lambda < 475) { 61 t = (lambda - 400) / 75; 62 rgb.z = 2.20 * t - (1.50 * t * t); 63 } else if (lambda >= 475 && lambda < 560) { 64 t = (lambda - 475) / 85; 65 rgb.z = 0.70 + t + (0.30 * t * t); 66 } 67 return rgb; 68 } 69 70 vec2 map_mandelbrot(vec2 v) 71 { 72 vec2 scale = abs(u_top_left - u_bottom_right); 73 return vec2(u_top_left.x, u_bottom_right.y) + v * scale; 74 } 75 76 vec2 complex_mult(vec2 a, vec2 b) 77 { 78 vec2 result; 79 result.x = a.x * a.x - b.y * b.y; 80 result.y = 2 * a.x * b.y; 81 return result; 82 } 83 84 void main() 85 { 86 vec2 vf = gl_FragCoord.xy / u_screen_dim.xy; 87 vec2 d = map_mandelbrot(vf); 88 89 int i; 90 vec2 z = u_use_approx ? u_z_n[0] : d; 91 vec2 e = vec2(0); 92 float xx = 0, yy = 0; 93 94 if (u_use_approx) { 95 for (i = 0; i < iterations && xx + yy < escape_radius; i++) { 96 xx = z.x * z.x; 97 yy = z.y * z.y; 98 e = complex_mult(2 * u_z_n[i], e) + complex_mult(e, e) + d; 99 z = u_z_n[i] + e; 100 } 101 } else { 102 for (i = 0; i < iterations && xx + yy < escape_radius; i++) { 103 xx = z.x * z.x; 104 yy = z.y * z.y; 105 z = vec2(xx - yy + d.x, 2 * z.x * z.y + d.y); 106 } 107 } 108 109 /* extra iterations to reduce error in escape calculation */ 110 /* fun value j = 5 */ 111 for (int j = 0; j < 2; j++) { 112 xx = z.x * z.x; 113 yy = z.y * z.y; 114 z = vec2(xx - yy + d.x, 2 * z.x * z.y + d.y); 115 } 116 117 float zmag = sqrt(xx + yy); 118 float mu = i - log(log(zmag)) / log(2.0); 119 mu = clamp(mu, 0, iterations); 120 float q = pow(mu / iterations, 0.8); 121 //float q = pow(mu / iterations, 0.69); 122 //float q = mu / iterations; 123 //colour = vec4(hsv2rgb(vec3(q, 0.8, 0.8)), 1.0); 124 colour = vec4(wavelength2rgb(400.0 + 300 * q).xyz, 1.0); 125 }