summaryrefslogtreecommitdiffhomepage
path: root/examples/shaders/resources
diff options
context:
space:
mode:
authorRay <[email protected]>2019-05-14 00:07:44 +0200
committerRay <[email protected]>2019-05-14 00:07:44 +0200
commit6f7b721d81c46718ae522e4a05e16c93711faefb (patch)
tree8644e950fbcd9908c5ce5d220026910b4e22ba51 /examples/shaders/resources
parent6804c2189e07a661ef975146c288619589c90731 (diff)
parent00431396b0b516b2296c17e5e5b5fd9e72bacfec (diff)
downloadraylib-6f7b721d81c46718ae522e4a05e16c93711faefb.tar.gz
raylib-6f7b721d81c46718ae522e4a05e16c93711faefb.zip
Merge branch 'master' of https://github.com/raysan5/raylib
Diffstat (limited to 'examples/shaders/resources')
-rw-r--r--examples/shaders/resources/shaders/glsl330/julia_shader.fs86
1 files changed, 86 insertions, 0 deletions
diff --git a/examples/shaders/resources/shaders/glsl330/julia_shader.fs b/examples/shaders/resources/shaders/glsl330/julia_shader.fs
new file mode 100644
index 00000000..b1331d84
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl330/julia_shader.fs
@@ -0,0 +1,86 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+
+uniform vec2 screenDims; // Dimensions of the screen
+uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
+uniform vec2 offset; // Offset of the scale.
+uniform float zoom; // Zoom of the scale.
+
+// Output fragment color
+out vec4 finalColor;
+
+const int MAX_ITERATIONS = 255; // Max iterations to do.
+
+// Square a complex number
+vec2 complexSquare(vec2 z)
+{
+ return vec2(
+ z.x * z.x - z.y * z.y,
+ z.x * z.y * 2.0
+ );
+}
+
+// Convert Hue Saturation Value color into RGB
+vec3 hsv2rgb(vec3 c)
+{
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+
+
+void main()
+{
+ // The pixel coordinates scaled so they are on the mandelbrot scale.
+ vec2 z = vec2(((gl_FragCoord.x + offset.x)/screenDims.x) * 2.5 * zoom,
+ ((screenDims.y - gl_FragCoord.y + offset.y)/screenDims.y) * 1.5 * zoom); // y also flipped due to opengl
+ int iterations = 0;
+
+ /*
+ Julia sets use a function z^2 + c, where c is a constant.
+ This function is iterated until the nature of the point is determined.
+
+ If the magnitude of the number becomes greater than 2, then from that point onward
+ the number will get bigger and bigger, and will never get smaller (tends towards infinity).
+ 2^2 = 4, 4^2 = 8 and so on.
+ So at 2 we stop iterating.
+
+ If the number is below 2, we keep iterating.
+ But when do we stop iterating if the number is always below 2 (it converges)?
+ That is what MAX_ITERATIONS is for.
+ Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can
+ then map to a color.
+
+ We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
+ And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power).
+ */
+ for (iterations = 0; iterations < MAX_ITERATIONS; iterations++)
+ {
+ z = complexSquare(z) + c; // Iterate function
+ if (dot(z, z) > 4.0)
+ {
+ break;
+ }
+ }
+
+ // Another few iterations decreases errors in the smoothing calculation.
+ // See http://linas.org/art-gallery/escape/escape.html for more information.
+ z = complexSquare(z) + c;
+ z = complexSquare(z) + c;
+
+ // This last part smooths the color (again see link above).
+ float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0));
+
+ // Normalize the value so it is between 0 and 1.
+ float norm = smoothVal/float(MAX_ITERATIONS);
+
+ // If in set, color black. 0.999 allows for some float accuracy error.
+ if (norm > 0.999)
+ {
+ finalColor = vec4(0.0, 0.0, 0.0, 1.0);
+ } else
+ {
+ finalColor = vec4(hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0);
+ }
+}