Skip to content

Commit aeafce5

Browse files
authored
[examples] Added: shaders_mandelbrot_set (#5282)
* [examples] Added: `shaders_mandelbrot_set` * Simplified shader code and added comments * Comments starting with a capital letter, and some minor fixes to adhere to the convention
1 parent 9ef3448 commit aeafce5

File tree

7 files changed

+973
-0
lines changed

7 files changed

+973
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#version 100
2+
3+
#define PI 3.1415926535897932384626433832795
4+
5+
precision highp float;
6+
7+
// Input vertex attributes (from vertex shader)
8+
varying vec2 fragTexCoord;
9+
varying vec4 fragColor;
10+
11+
uniform vec2 offset; // Offset of the scale
12+
uniform float zoom; // Zoom of the scale
13+
// NOTE: Maximum number of shader for-loop iterations depend on GPU,
14+
// For example, on RasperryPi for this examply only supports up to 60
15+
uniform int maxIterations; // Max iterations per pixel
16+
17+
const float max = 4.0; // We consider infinite as 4.0: if a point reaches a distance of 4.0 it will escape to infinity
18+
const float max2 = max*max; // Square of max to avoid computing square root
19+
20+
void main()
21+
{
22+
// The pixel coordinates are scaled so they are on the mandelbrot scale
23+
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
24+
vec2 c = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
25+
c.x += offset.x;
26+
c.y += offset.y;
27+
float a = 0.0;
28+
float b = 0.0;
29+
30+
// The Mandelbrot set is a two-dimensional set defined in the complex plane on which the iteration of the function
31+
// Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
32+
// Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
33+
34+
int iter = 0;
35+
while (iter < maxIterations)
36+
{
37+
float aa = a*a;
38+
float bb = b*b;
39+
if (aa + bb > max2)
40+
break;
41+
42+
float twoab = 2.0*a*b;
43+
a = aa - bb + c.x;
44+
b = twoab + c.y;
45+
46+
++iter;
47+
}
48+
49+
if (iter >= maxIterations)
50+
{
51+
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
52+
}
53+
else
54+
{
55+
float normR = float(iter - (iter/55)*55)/55.0;
56+
float normG = float(iter - (iter/69)*69)/69.0;
57+
float normB = float(iter - (iter/40)*40)/40.0;
58+
59+
gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
60+
}
61+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#version 120
2+
3+
#define PI 3.1415926535897932384626433832795
4+
5+
// Input vertex attributes (from vertex shader)
6+
varying vec2 fragTexCoord;
7+
varying vec4 fragColor;
8+
9+
uniform vec2 offset; // Offset of the scale
10+
uniform float zoom; // Zoom of the scale
11+
// NOTE: Maximum number of shader for-loop iterations depend on GPU,
12+
// For example, on RasperryPi for this examply only supports up to 60
13+
uniform int maxIterations; // Max iterations per pixel
14+
15+
const float max = 4.0; // We consider infinite as 4.0: if a point reaches a distance of 4.0 it will escape to infinity
16+
const float max2 = max*max; // Square of max to avoid computing square root
17+
18+
void main()
19+
{
20+
// The pixel coordinates are scaled so they are on the mandelbrot scale
21+
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
22+
vec2 c = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
23+
c.x += offset.x;
24+
c.y += offset.y;
25+
float a = 0.0;
26+
float b = 0.0;
27+
28+
// The Mandelbrot set is a two-dimensional set defined in the complex plane on which the iteration of the function
29+
// Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
30+
// Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
31+
32+
int iter = 0;
33+
while (iter < maxIterations)
34+
{
35+
float aa = a*a;
36+
float bb = b*b;
37+
if (aa + bb > max2)
38+
break;
39+
40+
float twoab = 2.0*a*b;
41+
a = aa - bb + c.x;
42+
b = twoab + c.y;
43+
44+
++iter;
45+
}
46+
47+
if (iter >= maxIterations)
48+
{
49+
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
50+
}
51+
else
52+
{
53+
float normR = float(iter - (iter/55)*55)/55.0;
54+
float normG = float(iter - (iter/69)*69)/69.0;
55+
float normB = float(iter - (iter/40)*40)/40.0;
56+
57+
gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
58+
}
59+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#version 330
2+
3+
#define PI 3.1415926535897932384626433832795
4+
5+
// Input vertex attributes (from vertex shader)
6+
in vec2 fragTexCoord;
7+
in vec4 fragColor;
8+
9+
// Output fragment color
10+
out vec4 finalColor;
11+
12+
uniform vec2 offset; // Offset of the scale
13+
uniform float zoom; // Zoom of the scale
14+
uniform int maxIterations; // Max iterations per pixel
15+
16+
const float max = 4.0; // We consider infinite as 4.0: if a point reaches a distance of 4.0 it will escape to infinity
17+
const float max2 = max*max; // Square of max to avoid computing square root
18+
19+
void main()
20+
{
21+
// The pixel coordinates are scaled so they are on the mandelbrot scale
22+
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
23+
vec2 c = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
24+
c.x += offset.x;
25+
c.y += offset.y;
26+
float a = 0.0;
27+
float b = 0.0;
28+
29+
// The Mandelbrot set is a two-dimensional set defined in the complex plane on which the iteration of the function
30+
// Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
31+
// Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
32+
33+
int iter = 0;
34+
for (iter = 0; iter < maxIterations; ++iter)
35+
{
36+
float aa = a*a;
37+
float bb = b*b;
38+
if (aa + bb > max2)
39+
break;
40+
41+
float twoab = 2.0*a*b;
42+
a = aa - bb + c.x;
43+
b = twoab + c.y;
44+
}
45+
46+
if (iter >= maxIterations)
47+
{
48+
finalColor = vec4(0.0, 0.0, 0.0, 1.0);
49+
}
50+
else
51+
{
52+
float normR = float(iter%55)/55.0;
53+
float normG = float(iter%69)/69.0;
54+
float normB = float(iter%40)/40.0;
55+
56+
finalColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
57+
}
58+
}

0 commit comments

Comments
 (0)