mightymandel v16

GPU-based Mandelbrot set explorer

fp32_step_vert.glsl
Go to the documentation of this file.
1 // mightymandel -- GPU-based Mandelbrot Set explorer
2 // Copyright (C) 2012,2013,2014,2015 Claude Heiland-Allen
3 // License GPL3+ http://www.gnu.org/licenses/gpl.html
4 
5 uniform float er2;
6 in vec4 cne0;
7 #ifdef DE
8 in vec4 zdz0;
9 #else
10 in vec2 zdz0;
11 #endif
12 out vec4 cne;
13 #ifdef DE
14 out vec4 zdz;
15 #else
16 out vec2 zdz;
17 #endif
18 
19 // interior checking
20 // https://en.wikipedia.org/wiki/Mandelbrot_set#Cardioid_.2F_bulb_checking
21 bool interior(vec2 c) {
22  // check period 1 cardioid
23  float x = c.x - 0.25;
24  float q = x * x + c.y * c.y;
25  bool cardioid = q * (q + x) < 0.25 * c.y * c.y;
26  if (cardioid) {
27  return true;
28  }
29  // check period 2 circle
30  x = c.x + 1.0;
31  bool circle = x * x + c.y * c.y < 0.0625;
32  if (circle) {
33  return true;
34  }
35  // don't check any others, for now
36  return false;
37 }
38 
39 void main() {
40  vec2 c = cne0.xy;
41  float n = cne0.z;
42  float e = cne0.w;
43  vec2 z = zdz0.xy;
44 #ifdef DE
45  vec2 dz = zdz0.zw;
46 #endif
47  // check interior on first iteration only, use n < 0 as a sentinel later
48  if (n == 0.0 && interior(c)) {
49  n = -1.0;
50  } else if (n >= 0.0) {
51  int j = 0;
52  for (int i = 0; i < FP32_STEP_ITERS; ++i) {
53  if (e <= 0.0) {
54  j += 1;
55 #ifdef DE
56  dz = 2.0 * cmul(z, dz) + vec2(1.0, 0.0);
57 #endif
58  z = csqr(z) + c;
59  e = cmag2(z) - er2;
60  } else {
61  break;
62  }
63  }
64  n += float(j);
65  }
66  cne = vec4(c, n, e);
67 #ifdef DE
68  zdz = vec4(z, dz);
69 #else
70  zdz = vec2(z);
71 #endif
72 }