From cb8c6cbfdad3a9a1e6c5ef569ec356a6d134252c Mon Sep 17 00:00:00 2001 From: Patricio Gonzalez Vivo Date: Tue, 13 Aug 2024 11:24:06 -0400 Subject: [PATCH] starting chapter 14 with a bit of text and basic examples --- 13/index.php | 1 + 14/README-pt.md | 27 ---------------- 14/README-ua.md | 16 ---------- 14/README.md | 41 +++++++++++++++++------- 14/index.php | 1 - 14/mandelbrot_00.frag | 39 +++++++++++++++++++++++ 14/tiling_00.frag | 38 ++++++++++++++++++++++ 14/tiling_01.frag | 73 +++++++++++++++++++++++++++++++++++++++++++ 14/tiling_02.frag | 72 ++++++++++++++++++++++++++++++++++++++++++ 14/tiling_03.frag | 70 +++++++++++++++++++++++++++++++++++++++++ 14/tiling_04.frag | 68 ++++++++++++++++++++++++++++++++++++++++ 14/tiling_05.frag | 64 +++++++++++++++++++++++++++++++++++++ 14/tiling_06.frag | 51 ++++++++++++++++++++++++++++++ 14/tiling_07.frag | 49 +++++++++++++++++++++++++++++ 14/tiling_08.frag | 54 ++++++++++++++++++++++++++++++++ README.md | 2 +- 16 files changed, 609 insertions(+), 57 deletions(-) delete mode 100644 14/README-pt.md delete mode 100644 14/README-ua.md create mode 100644 14/mandelbrot_00.frag create mode 100644 14/tiling_00.frag create mode 100644 14/tiling_01.frag create mode 100644 14/tiling_02.frag create mode 100644 14/tiling_03.frag create mode 100644 14/tiling_04.frag create mode 100644 14/tiling_05.frag create mode 100644 14/tiling_06.frag create mode 100644 14/tiling_07.frag create mode 100644 14/tiling_08.frag diff --git a/13/index.php b/13/index.php index 79d6056..0e2baa5 100644 --- a/13/index.php +++ b/13/index.php @@ -26,6 +26,7 @@ '; include($path."/footer.php"); diff --git a/14/README-pt.md b/14/README-pt.md deleted file mode 100644 index 2b27419..0000000 --- a/14/README-pt.md +++ /dev/null @@ -1,27 +0,0 @@ -## Fractais - -https://www.shadertoy.com/view/lsX3W4 - -https://www.shadertoy.com/view/Mss3Wf - -https://www.shadertoy.com/view/4df3Rn - -https://www.shadertoy.com/view/Mss3R8 - -https://www.shadertoy.com/view/4dfGRn - -https://www.shadertoy.com/view/lss3zs - -https://www.shadertoy.com/view/4dXGDX - -https://www.shadertoy.com/view/XsXGz2 - -https://www.shadertoy.com/view/lls3D7 - -https://www.shadertoy.com/view/XdB3DD - -https://www.shadertoy.com/view/XdBSWw - -https://www.shadertoy.com/view/llfGD2 - -https://www.shadertoy.com/view/Mlf3RX diff --git a/14/README-ua.md b/14/README-ua.md deleted file mode 100644 index 4773633..0000000 --- a/14/README-ua.md +++ /dev/null @@ -1,16 +0,0 @@ -## Фрактали - -Coming soon ... - -А поки що можете подивитися приклади з фракталами на платформі [shadertoy.com](https://www.shadertoy.com/results?query=fractals): - -[Basic Fractal](https://www.shadertoy.com/view/Mss3Wf) -[Mandelbrot - distance](https://www.shadertoy.com/view/lsX3W4) -[Mandelbrot - smooth](https://www.shadertoy.com/view/4df3Rn) -[Mandelbrot: Power Transitioning](https://www.shadertoy.com/view/lls3D7) -[IFS - brute force](https://www.shadertoy.com/view/lss3zs) -[Julia - Distance 1](https://www.shadertoy.com/view/Mss3R8) -[Julia - Distance 3](https://www.shadertoy.com/view/4dXGDX) -[Julia - Traps 2](https://www.shadertoy.com/view/4dfGRn) -[Fractal Wheel 2.0](https://www.shadertoy.com/view/llfGD2) -[Koch Snowflake again](https://www.shadertoy.com/view/Mlf3RX) diff --git a/14/README.md b/14/README.md index 37a1d5e..30c25a1 100644 --- a/14/README.md +++ b/14/README.md @@ -1,16 +1,33 @@ ## Fractals -Coming soon ... +In the prevous chapter we addeded incrising octaves of noise while we were decreasing it's amplitud, resulting in a more granular noise we called that fractal noise. It's name reside in the fact that the structure repeats it self at different scales. That property is known as **self similarity**. And is actually very useful in computer graphics, because it allows us to create complex structures from simple ones at any scale or resolution. For the same reason fractals can be spot on nature everywhere, from the shape of a tree, a shell, fern, etc. It's a smart way for life to grow and scale in a very efficient way with very little information. -In the meantime, you can check out some examples with fractals on the [shadertoy.com](https://www.shadertoy.com/results?query=fractals) platform: +Let's study self similarity in a simple way, no complicated math or formulas for now. We will go back and use [tile patterns](https://thebookofshaders.com/09/) and a [random functions](https://thebookofshaders.com/10/) from chapters 9 and 10 to get familiar with recursion and self similarity. -[Basic Fractal](https://www.shadertoy.com/view/Mss3Wf) -[Mandelbrot - distance](https://www.shadertoy.com/view/lsX3W4) -[Mandelbrot - smooth](https://www.shadertoy.com/view/4df3Rn) -[Mandelbrot: Power Transitioning](https://www.shadertoy.com/view/lls3D7) -[IFS - brute force](https://www.shadertoy.com/view/lss3zs) -[Julia - Distance 1](https://www.shadertoy.com/view/Mss3R8) -[Julia - Distance 3](https://www.shadertoy.com/view/4dXGDX) -[Julia - Traps 2](https://www.shadertoy.com/view/4dfGRn) -[Fractal Wheel 2.0](https://www.shadertoy.com/view/llfGD2) -[Koch Snowflake again](https://www.shadertoy.com/view/Mlf3RX) +Recursion + +
+ + +
+ +Self similarity + +
+ +
+ +
+ +
+ +
+ +
+ +
+ + +Mathematical model + +
diff --git a/14/index.php b/14/index.php index d17c39c..99d9261 100644 --- a/14/index.php +++ b/14/index.php @@ -26,7 +26,6 @@ '; include($path."/footer.php"); diff --git a/14/mandelbrot_00.frag b/14/mandelbrot_00.frag new file mode 100644 index 0000000..8aeb544 --- /dev/null +++ b/14/mandelbrot_00.frag @@ -0,0 +1,39 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + st = st * 2.0 - 1.0; + st.x -= 0.5; + + const float iterations_max = 15.0; + float iterations = mod(u_time, iterations_max); + vec2 uv = st; + + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + if (length(uv) > 2.0) + break; + + uv = vec2( uv.x*uv.x - uv.y*uv.y, + 2.0 * uv.x*uv.y) + st; + + // uv = mat2(uv.x, uv.y, -uv.y, uv.x) * uv + st; + + color++; + } + + color /= iterations_max; + + gl_FragColor = vec4(color, 1.0); +} diff --git a/14/tiling_00.frag b/14/tiling_00.frag new file mode 100644 index 0000000..c1e8b7f --- /dev/null +++ b/14/tiling_00.frag @@ -0,0 +1,38 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + +float random(in vec2 st) { + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +} + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + const float iterations_max = 8.0; + float iterations = mod(u_time, iterations_max); + + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + st *= 2.0; + vec2 st_i = floor(st); + st = fract(st); + + float v = random(st_i * 1.4); + + if (v > 0.5) { + color = vec3(v); + break; + } + } + + gl_FragColor = vec4(color, 1.0); +} diff --git a/14/tiling_01.frag b/14/tiling_01.frag new file mode 100644 index 0000000..f8480b7 --- /dev/null +++ b/14/tiling_01.frag @@ -0,0 +1,73 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + +#define PI 3.14159265358979323846 + +float random(in vec2 st) { + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +} + +vec2 rotate2D (vec2 _st, float _angle) { + _st -= 0.5; + _st = mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)) * _st; + _st += 0.5; + return _st; +} + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + const float iterations_max = 8.0; + float iterations = mod(u_time, iterations_max); + + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + st *= 2.0; + vec2 st_i = floor(st); + st = fract(st); + + // Give each cell an index number + // according to its position + float index = 0.0; + index += step(1., mod(st_i.x,2.0)); + index += step(1., mod(st_i.y,2.0))*2.0; + + // | + // 2 | 3 + // | + //-------------- + // | + // 0 | 1 + // | + + // Rotate each cell according to the index + if (index == 0.0) + st = rotate2D(st, PI*-0.5); + else if (index == 1.0) + st = st; + else if (index == 2.0) + st = st.yx; + else if (index == 3.0) + st = rotate2D(st, PI*0.5); + + + float v = random(st_i * 1.2); + + if (v > 0.5) { + color = vec3(step(st.x,st.y)); + break; + } + } + + gl_FragColor = vec4(color, 1.0); +} diff --git a/14/tiling_02.frag b/14/tiling_02.frag new file mode 100644 index 0000000..6af77d9 --- /dev/null +++ b/14/tiling_02.frag @@ -0,0 +1,72 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + +#define PI 3.14159265358979323846 + +float random(in vec2 st) { + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +} + +vec2 rotate2D (vec2 _st, float _angle) { + _st -= 0.5; + _st = mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)) * _st; + _st += 0.5; + return _st; +} + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + const float iterations_max = 8.0; + float iterations = mod(u_time, iterations_max); + + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + st *= 2.0; + vec2 st_i = floor(st); + st = fract(st); + + // Give each cell an index number + // according to its position + float index = 0.0; + index += step(1., mod(st_i.x,2.0)); + index += step(1., mod(st_i.y,2.0))*2.0; + + // | + // 2 | 3 + // | + //-------------- + // | + // 0 | 1 + // | + + // Rotate each cell according to the index + if (index == 0.0) + st = st; + else if (index == 1.0) + st = rotate2D(st, PI*0.5); + else if (index == 2.0) + st = rotate2D(st, PI*-0.5); + else if (index == 3.0) + st = st.yx; + + float v = random(st_i * 1.5); + + if (v > 0.5) { + color = vec3(step(st.x,st.y)); + break; + } + } + + gl_FragColor = vec4(color, 1.0); +} diff --git a/14/tiling_03.frag b/14/tiling_03.frag new file mode 100644 index 0000000..9e65c6f --- /dev/null +++ b/14/tiling_03.frag @@ -0,0 +1,70 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + +#define PI 3.14159265358979323846 + +float random(in vec2 st) { + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +} + +vec2 rotate2D (vec2 _st, float _angle) { + _st -= 0.5; + _st = mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)) * _st; + _st += 0.5; + return _st; +} + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + const float iterations_max = 8.0; + float iterations = mod(u_time, iterations_max); + + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + st *= 2.0; + vec2 st_i = floor(st); + st = fract(st); + + // Give each cell an index number + // according to its position + float index = 0.0; + index += step(1., mod(st_i.x,2.0)); + index += step(1., mod(st_i.y,2.0))*2.0; + + // | + // 2 | 3 + // | + //-------------- + // | + // 0 | 1 + // | + + // Rotate each cell according to the index + if (index == 0.0) + st = rotate2D(st, PI*-0.5); + else if (index == 1.0) + st = st.yx; + else if (index == 2.0) + st = st; + else if (index == 3.0) + st = rotate2D(st, PI*0.5); + + if (index < 2.0) { + color = vec3(step(st.x,st.y)); + break; + } + } + + gl_FragColor = vec4(color, 1.0); +} diff --git a/14/tiling_04.frag b/14/tiling_04.frag new file mode 100644 index 0000000..d1848c6 --- /dev/null +++ b/14/tiling_04.frag @@ -0,0 +1,68 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + +#define PI 3.14159265358979323846 + +float random(in vec2 st) { + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +} + +vec2 rotate2D (vec2 _st, float _angle) { + _st -= 0.5; + _st = mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)) * _st; + _st += 0.5; + return _st; +} + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + const float iterations_max = 8.0; + float iterations = mod(u_time, iterations_max); + + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + st *= 2.0; + vec2 st_i = floor(st); + st = fract(st); + + // Give each cell an index number + // according to its position + float index = 0.0; + index += step(1., mod(st_i.x,2.0)); + index += step(1., mod(st_i.y,2.0))*2.0; + + // | + // 2 | 3 + // | + //-------------- + // | + // 0 | 1 + // | + + // Rotate each cell according to the index + if (index == 0.0) + st = st; + else if (index == 1.0) + st = rotate2D(st, PI*0.5); + else if (index == 2.0) + st = rotate2D(st, PI*-0.5); + + if (index == 3.0) { + color = vec3(step(st.x,st.y)); + break; + } + } + + gl_FragColor = vec4(color, 1.0); +} diff --git a/14/tiling_05.frag b/14/tiling_05.frag new file mode 100644 index 0000000..140543c --- /dev/null +++ b/14/tiling_05.frag @@ -0,0 +1,64 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + +#define PI 3.14159265358979323846 + +float random(in vec2 st) { + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +} + +vec2 rotate2D (vec2 _st, float _angle) { + _st -= 0.5; + _st = mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)) * _st; + _st += 0.5; + return _st; +} + +float stroke(float x, float size, float w, float edge) { + float d = smoothstep(size - edge, size + edge, x + w * 0.5) - smoothstep(size - edge, size + edge, x - w * 0.5); + return clamp(d, 0.0, 1.0); +} + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + const float iterations_max = 8.0; + float iterations = mod(u_time, iterations_max); + + float width = 0.005; + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + vec2 st_i = floor(st); + st = fract(st); + + // Give each cell an index number + // according to its position + float index = 0.0; + index += step(1., mod(st_i.x,2.0)); + index += step(1., mod(st_i.y,2.0))*2.0; + + // Rotate each cell according to the index + vec2 uv = st; + + if (index == 3.0) { + color = vec3(stroke(length(uv), 1.0 - width, width, 0.01)); + break; + } + + st *= 2.0; + st = rotate2D(st, PI * -0.5); + width *= 2.0; + } + + gl_FragColor = vec4(color, 1.0); +} diff --git a/14/tiling_06.frag b/14/tiling_06.frag new file mode 100644 index 0000000..aac5649 --- /dev/null +++ b/14/tiling_06.frag @@ -0,0 +1,51 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + + +#define PI 3.14159265358979323846 + +vec2 rotate2D (vec2 _st, float _angle) { + _st -= 0.5; + _st = mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)) * _st; + _st += 0.5; + return _st; +} + + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + const float iterations_max = 9.0; + const float subdivide = 2.0; + float iterations = mod(u_time, iterations_max); + + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + st *= subdivide; + vec2 st_i = floor(st); + st = fract(st); + + float index = 0.0; + index += mod(st_i.x, subdivide); + index += mod(st_i.y, subdivide)*subdivide; + + if (index == subdivide-1.0) { + color = vec3(step(length(st), 1.) * i/iterations); + break; + } + + st = rotate2D(st, PI * 0.5); + } + + gl_FragColor = vec4(color, 1.0); +} diff --git a/14/tiling_07.frag b/14/tiling_07.frag new file mode 100644 index 0000000..111394f --- /dev/null +++ b/14/tiling_07.frag @@ -0,0 +1,49 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + + +#define PI 3.14159265358979323846 + +vec2 rotate2D (vec2 _st, float _angle) { + _st -= 0.5; + _st = mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)) * _st; + _st += 0.5; + return _st; +} + + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + const float iterations_max = 9.0; + const float subdivide = 3.0; + float iterations = mod(u_time, iterations_max); + + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + st *= subdivide; + vec2 st_i = floor(st); + st = fract(st); + + float index = 0.0; + index += mod(st_i.x, subdivide); + index += mod(st_i.y, subdivide)*subdivide; + + if (index == 4.) { + color = vec3(step(length(st-0.5), .5) * i/iterations); + break; + } + } + + gl_FragColor = vec4(color, 1.0); +} diff --git a/14/tiling_08.frag b/14/tiling_08.frag new file mode 100644 index 0000000..0967b34 --- /dev/null +++ b/14/tiling_08.frag @@ -0,0 +1,54 @@ + +#ifdef GL_ES +precision mediump float; +#endif + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_time; + + +#define PI 3.14159265358979323846 + +vec2 rotate2D (vec2 _st, float _angle) { + _st -= 0.5; + _st = mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)) * _st; + _st += 0.5; + return _st; +} + + +void main(void) { + vec3 color = vec3(0.0); + vec2 st = gl_FragCoord.xy / u_resolution; + + const float iterations_max = 9.0; + float iterations = mod(u_time, iterations_max); + + st -= 0.5; + st /= iterations * 0.25; + st += 0.5; + + for (float i = 0.0; i < iterations_max; i++) { + if (i >= iterations) + break; + + st = rotate2D(st, PI * 0.5); + st *= 2.0; + vec2 st_i = floor(st); + st = fract(st); + + float index = 0.0; + index += mod(st_i.x, 2.0); + index += mod(st_i.y, 2.0)*2.0; + + if (index == 2.) { + color = vec3(step(length(1.0-st), 1.0) * (1.0-i/iterations)); + break; + } + + } + + gl_FragColor = vec4(color, 1.0); +} diff --git a/README.md b/README.md index d82c896..d7d3318 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ This is a gentle step-by-step guide through the abstract and complex universe of * [Noise](11/) * [Cellular noise](12/) * [Fractional brownian motion](13/) - * Fractals + * [Fractals](14/) * Image processing * Textures