aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2026-10-14 02:06:42 +0530
committerAkshay Nair <phenax5@gmail.com>2026-10-14 02:27:24 +0530
commit686b2954a7cf0aae0493b4a974400aed64bbb96f (patch)
tree8ec556b14c4d6eb41634e25bf9a0bac40dd4d4ae /src/main
parent49b6b0c9d7de093fc63af376afe5d03f1690995a (diff)
downloadart-playground-openrndr-686b2954a7cf0aae0493b4a974400aed64bbb96f.tar.gz
art-playground-openrndr-686b2954a7cf0aae0493b4a974400aed64bbb96f.zip
Add moth trtrfr
Diffstat (limited to 'src/main')
-rw-r--r--src/main/kotlin/trtrfr/TrtrfrProgram.kt89
-rw-r--r--src/main/resources/shaders/modules/complex.glsl46
-rw-r--r--src/main/resources/shaders/newton.glsl42
-rw-r--r--src/main/resources/shaders/trtrfr.glsl93
4 files changed, 230 insertions, 40 deletions
diff --git a/src/main/kotlin/trtrfr/TrtrfrProgram.kt b/src/main/kotlin/trtrfr/TrtrfrProgram.kt
new file mode 100644
index 0000000..7d2f959
--- /dev/null
+++ b/src/main/kotlin/trtrfr/TrtrfrProgram.kt
@@ -0,0 +1,89 @@
+package trtrfr
+
+import org.openrndr.application
+import org.openrndr.color.*
+import org.openrndr.draw.*
+import org.openrndr.math.IntVector2
+import org.openrndr.math.Vector2
+import phenax.utils.*
+
+fun main() = application {
+ if (captureEnabled) {
+ val hiRes = System.getenv("PHENAX_HIRES")?.isNotEmpty() ?: false
+ configure {
+ width = if (hiRes) 3840 else 1920
+ height = if (hiRes) 2160 else 1080
+ windowResizable = false
+ }
+ } else {
+ configure {
+ width = 640
+ height = 360
+ windowResizable = false
+ }
+ }
+
+ oliveProgram {
+ val cs by liveComputeShader("trtrfr")
+ val enableAntialiasing = captureEnabled
+ val shaderLocalSize = IntVector2(8, 8)
+
+ val outputSize = IntVector2(width, height)
+ val outputBuffer = colorBuffer(outputSize.x, outputSize.y, type = ColorType.UINT8)
+
+ var scale: Double = 1.0
+ var offset: Vector2 = Vector2.ZERO
+ var moving = false
+
+ program.keyboard.keyDown.listen {
+ if (it.name == "r") {
+ scale = 1.0
+ offset = Vector2.ZERO
+ }
+ }
+ program.mouse.buttonDown.listen { moving = true }
+ program.mouse.buttonUp.listen { moving = false }
+ var lastPos = Vector2.ZERO
+ program.mouse.moved.listen {
+ val dimens = Vector2(program.width.toDouble(), program.height.toDouble())
+ var pos = (Vector2(it.position.x, -it.position.y) - dimens / 2.0).div(dimens)
+ val del = lastPos - pos
+ lastPos = pos
+ if (moving) offset = offset + del * 5.0 / scale
+ }
+
+ program.mouse.scrolled.listen { scale = scale * (1 + it.rotation.y / 3) }
+
+ extend {
+ cs.uniform("enable_antialiasing", enableAntialiasing)
+ cs.uniform("offset", offset)
+ cs.uniform("scale", scale)
+ cs.uniform("seconds", seconds)
+ cs.image("output_image", 0, outputBuffer.imageBinding(0, ImageAccess.WRITE))
+ cs.execute(
+ (outputBuffer.width + shaderLocalSize.x - 1) / shaderLocalSize.x,
+ (outputBuffer.height + shaderLocalSize.y - 1) / shaderLocalSize.y,
+ 1
+ )
+ drawer.image(outputBuffer, 0.0, 0.0, width.toDouble(), height.toDouble())
+
+ // val shadow = outputBuffer.shadow
+ // shadow.download()
+ // for (y in 0 until outputBuffer.height) {
+ // for (x in 0 until outputBuffer.width) {
+ // val c = shadow[x, y]
+ // shadow[x, y] =
+ // ColorRGBa(
+ // Math.pow(c.r, (1.0 / 2.2)),
+ // Math.pow(c.g, (1.0 / 2.2)),
+ // Math.pow(c.b, (1.0 / 2.2)),
+ // c.alpha
+ // )
+ // }
+ // }
+ // shadow.upload()
+ // outputBuffer.saveToFile(java.io.File("screenshot/${program.name}.png"), async = false)
+ // program.application.exit()
+ }
+ }
+}
diff --git a/src/main/resources/shaders/modules/complex.glsl b/src/main/resources/shaders/modules/complex.glsl
new file mode 100644
index 0000000..87114ac
--- /dev/null
+++ b/src/main/resources/shaders/modules/complex.glsl
@@ -0,0 +1,46 @@
+float cosh(float val) {
+ float tmp = exp(val);
+ float cosH = (tmp + 1.0 / tmp) / 2.0;
+ return cosH;
+}
+
+float sinh(float val) {
+ float tmp = exp(val);
+ float sinH = (tmp - 1.0 / tmp) / 2.0;
+ return sinH;
+}
+
+vec2 cmul(vec2 a, vec2 b) {
+ return vec2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
+}
+
+vec2 cdiv(vec2 a, vec2 b) {
+ float denominator = b.x * b.x + b.y * b.y;
+ if (denominator == 0.) return a;
+ return cmul(a, vec2(b.x, -b.y)) / denominator;
+}
+
+vec2 csin(vec2 a) {
+ return vec2(sin(a.x) * cosh(a.y), cos(a.x) * sinh(a.y));
+}
+
+vec2 ccos(vec2 a) {
+ return vec2(cos(a.x) * cosh(a.y), -sin(a.x) * sinh(a.y));
+}
+
+vec2 ctan(vec2 a) {
+ return cdiv(csin(a), ccos(a));
+}
+
+vec2 cpow(vec2 z, int n) {
+ vec2 res = z;
+ for (int i = 0; i < 20; i++) {
+ if (i >= n - 1) break;
+ res = cmul(z, res);
+ }
+ return res;
+}
+
+vec2 cexp(vec2 z) {
+ return exp(z.x) * vec2(cos(z.y), sin(z.y));
+}
diff --git a/src/main/resources/shaders/newton.glsl b/src/main/resources/shaders/newton.glsl
index e53b153..a0bcc10 100644
--- a/src/main/resources/shaders/newton.glsl
+++ b/src/main/resources/shaders/newton.glsl
@@ -2,6 +2,7 @@
layout(local_size_x = 1, local_size_y = 1) in;
#include <utils>
+#include <complex>
#define MAX_ITERATIONS 200
@@ -9,45 +10,6 @@ const float antialiasing = 0.28;
uniform float seconds = 0;
layout(rgba8) uniform writeonly image2D output_image;
-float fabs(float a) {
- return a > 0. ? a : -a;
-}
-
-float cosh(float val) {
- float tmp = exp(val);
- float cosH = (tmp + 1.0 / tmp) / 2.0;
- return cosH;
-}
-
-float sinh(float val) {
- float tmp = exp(val);
- float sinH = (tmp - 1.0 / tmp) / 2.0;
- return sinH;
-}
-
-vec2 cmul(vec2 a, vec2 b) {
- return vec2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
-}
-
-vec2 cdiv(vec2 a, vec2 b) {
- float denominator = b.x * b.x + b.y * b.y;
- if (denominator == 0.) return a;
- return cmul(a, vec2(b.x, -b.y)) / denominator;
-}
-
-vec2 cpow(vec2 z, int n) {
- vec2 res = z;
- for (int i = 0; i < 20; i++) {
- if (i >= n - 1) break;
- res = cmul(z, res);
- }
- return res;
-}
-
-vec2 cexp(vec2 z) {
- return exp(z.x) * vec2(cos(z.y), sin(z.y));
-}
-
vec2 get_step(vec2 z) {
vec2 value = cpow(z, 5) + 2.0 * cpow(z, 3) - vec2(1., 0.);
vec2 derivative = 5.0 * cpow(z, 4) + 3.0 * cpow(z, 2);
@@ -67,7 +29,7 @@ vec3 image(vec2 uv) {
z = prevZ - cmul(factor, get_step(prevZ));
iterations++;
- if (fabs(z.x - prevZ.x) < 0.001) break;
+ if (abs(z.x - prevZ.x) < 0.001) break;
}
float val = float(iterations) * 10.0 / float(MAX_ITERATIONS);
diff --git a/src/main/resources/shaders/trtrfr.glsl b/src/main/resources/shaders/trtrfr.glsl
new file mode 100644
index 0000000..080aae0
--- /dev/null
+++ b/src/main/resources/shaders/trtrfr.glsl
@@ -0,0 +1,93 @@
+#version 430
+layout(local_size_x = 8, local_size_y = 8) in;
+precision highp float;
+
+#include <complex>
+#include <sdf>
+#include <utils>
+
+uniform float seconds = 0;
+layout(rgba8) uniform writeonly image2D output_image;
+
+uniform float antialiasing = 0.28;
+uniform bool enable_antialiasing = false;
+
+uniform vec2 offset;
+uniform float scale;
+
+const int MAX_ITERATIONS = 1000;
+const float INF_GAP = 10000.0;
+
+vec3 col_blue1 = srgb(0.33, 0.48, 0.60);
+vec3 col_pink1 = srgb(0.98, 0.27, 0.47);
+vec3 col_pink2 = srgb(0.84, 0.24, 0.33);
+vec3 col_yellow1 = srgb(0.90, 0.69, 0.18);
+vec3 col_violet1 = srgb(0.26, 0.11, 0.52);
+vec3 col_green1 = srgb(0.24, 0.40, 0.33);
+vec3 col_wingpat = srgb(0.12, 0.06, 0.03);
+vec3 col_mothbody = srgb(0.12, 0.06, 0.03);
+vec3 col_bg = vec3(0);
+
+vec3 image(vec2 uv) {
+ vec3 color = col_bg;
+
+ vec2 c = (uv - vec2(0, 0.20)) * 6 / scale + offset;
+ c = vec2(c.y, c.x);
+ vec2 z = vec2(0);
+ vec2 last_z;
+ int iter;
+ float last_dist;
+ for (iter = 0; iter <= MAX_ITERATIONS; iter++) {
+ last_z = z;
+ z = csin(ccos(z)) - ctan(z) + c;
+ last_dist = length(z - last_z);
+ if (last_dist >= INF_GAP) break;
+ }
+ float f = float(iter) / float(MAX_ITERATIONS);
+
+ // Pat
+ vec2 p = (uv - vec2(0, -0.012)) * vec2(23, 72);
+ float buttpat = sin(-abs(p.x) - 5) * sin(abs(p.y)) - sin((abs(p.x) - 6) * p.y);
+ color = mix(color, col_wingpat, (smoothstep(-0.5, 1.0, buttpat)) * step(last_dist, 0.0000003));
+ color = mix(color, col_mothbody, (1 - step(last_dist, 0.0000016)) * step(last_dist, 0.05));
+
+ float gap = 0.504;
+ vec2 eyesp = uv - vec2(gap / 2., 0.093);
+ eyesp.x -= round(eyesp.x / gap) * gap;
+
+ float eyes = sdf_circle(eyesp, 0.007);
+ color = mix(color, mix(col_wingpat, col_bg, 0.22), step(abs(eyes) - 0.003, 0));
+
+ // Floral
+ color = mix(color, srgb(0.0, 0.13, 0.08), (1 - step(last_dist, 0.1)) * (1 - step(last_dist, INF_GAP)));
+ color = mix(color, mix(col_pink1, col_violet1, smoothstep(-0.2, 0.5, f)), step(f, 0.9999));
+ color = mix(color, col_yellow1, step(f, 0.016));
+ color = mix(color, col_violet1, step(f, 0.008));
+ color = mix(color, col_pink2, step(f, 0.005));
+ color = mix(color, col_green1, step(f, 0.003));
+
+ return color;
+}
+
+vec3 antialiased_image(vec2 uv) {
+ vec2 resolution = vec2(imageSize(output_image).xy);
+ float s = antialiasing / max(resolution.x, resolution.y);
+ vec3 sum = vec3(0);
+ int count = 0;
+ for (int i = -2; i < 2; i++)
+ for (int j = -2; j < 2; j++, count++)
+ sum += image(uv + vec2(i, j) * s);
+ return sum / count;
+}
+
+void main() {
+ vec2 resolution = vec2(imageSize(output_image).xy);
+ if (gl_GlobalInvocationID.x >= resolution.x || gl_GlobalInvocationID.y >= resolution.y) return;
+
+ float aspect_ratio = resolution.y / resolution.x;
+ vec2 uv = (gl_GlobalInvocationID.xy - resolution / 2) * vec2(1.0, aspect_ratio) / resolution;
+
+ vec3 color = enable_antialiasing ? antialiased_image(uv) : image(uv);
+
+ imageStore(output_image, ivec2(gl_GlobalInvocationID.xy), vec4(color, 1));
+}