diff options
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/kotlin/placenta/PlacentaProgram.kt | 41 | ||||
| -rw-r--r-- | src/main/resources/shaders/placenta.glsl | 97 |
2 files changed, 138 insertions, 0 deletions
diff --git a/src/main/kotlin/placenta/PlacentaProgram.kt b/src/main/kotlin/placenta/PlacentaProgram.kt new file mode 100644 index 0000000..2971110 --- /dev/null +++ b/src/main/kotlin/placenta/PlacentaProgram.kt @@ -0,0 +1,41 @@ +package placenta + +import org.openrndr.application +import org.openrndr.color.* +import org.openrndr.draw.* +import org.openrndr.extra.noise.filters.SimplexNoise3D +import org.openrndr.math.Vector3 +import phenax.utils.* + +fun main() = application { + recordDuration(5.seconds()) + + if (captureEnabled) { + configure { + width = 1920 + height = 1440 + windowResizable = false + } + } else { + configure { + width = 640 + height = 480 + windowResizable = false + } + } + + oliveProgram { + val enableAntialiasing = captureEnabled + val cs by liveComputeShader("placenta") + + val outputBuffer = colorBuffer(width, height, type = ColorType.UINT8) + + extend { + cs.uniform("enable_antialiasing", enableAntialiasing) + cs.uniform("seconds", seconds) + cs.image("output_image", 0, outputBuffer.imageBinding(0, ImageAccess.WRITE)) + cs.execute(outputBuffer.width, outputBuffer.height, 1) + drawer.image(outputBuffer) + } + } +} diff --git a/src/main/resources/shaders/placenta.glsl b/src/main/resources/shaders/placenta.glsl new file mode 100644 index 0000000..6871f52 --- /dev/null +++ b/src/main/resources/shaders/placenta.glsl @@ -0,0 +1,97 @@ +#version 430 +layout(local_size_x = 1, local_size_y = 1) in; + +#include <sdf> +#include <noise> +#include <utils> + +uniform float seconds = 0; +layout(rgba8) uniform writeonly image2D output_image; + +uniform float antialiasing = 0.28; +uniform bool enable_antialiasing = false; + +vec3 col_bg = srgb(0); +vec3 col_hair = srgb(1); +vec3 col_mface = srgb(1); +vec3 col_daisy = srgb(1, 1, 0.86); +vec3 col_daisy_pistil = srgb(0.96, 0.86, 0); + +vec3 image(vec2 uv) { + vec3 color = col_bg; + + vec2 p = uv; + + vec2 hmp = (p - vec2(0.05, 0.1)) * 1.5; + float tilt = -0.5; + hmp *= mat2x2(cos(tilt), -sin(tilt), sin(tilt), cos(tilt)); + + float head = sdf_circle(hmp * vec2(1, 0.77), 0.038); + color = mix(color, col_mface, 1 - smoothstep(-0, 0.02, head)); + + vec2 hp = (hmp - vec2(-0.03, 0.03)) * vec2(1, 0.8); + vec2 hp2 = hp - vec2(0.05, -0.06); + float theta = atan(hp.y, hp.x); + + const int HAIR_COUNT = 68; + for (int i = 0; i < HAIR_COUNT; i++) { + float d = (i * 1. / HAIR_COUNT + 0.2); + float th = atan(hp2.y, hp2.x); + th = mix(th, 2 * PI + th, step(th, 0)); + float tt = (th * d) * (10 - 0.15 * i) - 0.2; + float r = 21 * hp2.y / sin(th) + 0.8 * sin(tt) - 0.8 * fbm(vec2(i) * 1000); + float hair = abs(r - th + 1.0) - 0.011; + color = mix(color, col_hair, step(hair, 0) * (smoothstep(-0.16, 0.2, -r / 16))); + } + for (int i = 0; i < HAIR_COUNT; i++) { + float d = (i * 1. / HAIR_COUNT + 0.6); + float tt = (theta * d) * (10 - 0.15 * i) + 0.2; + float r = -10 * hp.y / sin(theta); + float r1 = r + (0.3 + r / 18) * sin(tt + 0.8) - 0.8 * fbm(vec2(i) * 1000); + float hair = abs(r1 - theta + 1.0) - 0.007; // 0.007 + color = mix(color, col_hair, step(hair, 0) * (smoothstep(-0.26, 0.2, r / 13))); + } + + { + vec2 babip = hmp - vec2(-0.22, -0.16); + + float scale = 28.; + vec2 p1 = babip; + vec2 p2 = p1 * mat2x2(cos(PI / 4), -sin(PI / 4), sin(PI / 4), cos(PI / 4)); + float theta1 = atan(p1.y, p1.x); + float petals = scale * p1.y / sin(theta1) - sin(4. * theta1); + petals = min(petals, scale * p1.y / sin(theta1) - cos(4. * theta1)); + float theta2 = atan(p2.y, p2.x); + petals = min(petals, scale * p2.y / sin(theta2) - sin(4. * theta2)); + petals = min(petals, scale * p2.y / sin(theta2) - cos(4. * theta2)); + color = mix(color, col_daisy, 1 - smoothstep(-0.4, 0.2, petals)); + color = mix(color, mix(col_daisy, vec3(0), 0.2), 1 - smoothstep(-0.9, -0.2, petals)); + color = mix(color, mix(color, col_daisy, 0.2), 1 - smoothstep(-1.5, 0.30, petals / 4)); + + float pistil = sdf_circle(babip, 0.01); + color = mix(color, col_daisy_pistil, step(pistil, 0)); + } + + 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); + 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)); +} |
