aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/kotlin/org/openrndr/Preload.kt8
-rw-r--r--src/main/kotlin/phenax/extensions/HeadlessScreenshot.kt2
-rw-r--r--src/main/kotlin/roll_credits/RollCreditsProgram.kt19
-rw-r--r--src/main/resources/shaders/modules/sdf.glsl7
-rw-r--r--src/main/resources/shaders/roll_credits.glsl157
5 files changed, 124 insertions, 69 deletions
diff --git a/src/main/kotlin/org/openrndr/Preload.kt b/src/main/kotlin/org/openrndr/Preload.kt
index e6a9688..42bab94 100644
--- a/src/main/kotlin/org/openrndr/Preload.kt
+++ b/src/main/kotlin/org/openrndr/Preload.kt
@@ -1,9 +1,9 @@
package org.openrndr
import org.openrndr.draw.*
+import org.openrndr.extensions.SingleScreenshot
import org.openrndr.extra.olive.*
import org.openrndr.ffmpeg.ScreenRecorder
-import phenax.extensions.HeadlessScreenshot
import phenax.utils.*
class Preload : ApplicationPreload() {
@@ -19,7 +19,11 @@ class Preload : ApplicationPreload() {
multisample = BufferMultisample.SampleCount(16)
}
} else if (screenshotEnabled) {
- program.extend(HeadlessScreenshot())
+ program.extend(SingleScreenshot()) {
+ outputFile = "screenshot/${program.name}.png"
+ async = false
+ quitAfterScreenshot = true
+ }
}
}
}
diff --git a/src/main/kotlin/phenax/extensions/HeadlessScreenshot.kt b/src/main/kotlin/phenax/extensions/HeadlessScreenshot.kt
index 35de05d..7bd9967 100644
--- a/src/main/kotlin/phenax/extensions/HeadlessScreenshot.kt
+++ b/src/main/kotlin/phenax/extensions/HeadlessScreenshot.kt
@@ -24,7 +24,5 @@ class HeadlessScreenshot : Extension {
override fun afterDraw(drawer: Drawer, program: Program) {
screenshots?.trigger()
-
- // program.application.exit()
}
}
diff --git a/src/main/kotlin/roll_credits/RollCreditsProgram.kt b/src/main/kotlin/roll_credits/RollCreditsProgram.kt
index b07d6fc..472ce85 100644
--- a/src/main/kotlin/roll_credits/RollCreditsProgram.kt
+++ b/src/main/kotlin/roll_credits/RollCreditsProgram.kt
@@ -3,8 +3,6 @@ package roll_credits
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 {
@@ -25,31 +23,22 @@ fun main() = application {
}
oliveProgram {
+ val enableAntialiasing = captureEnabled
val cs by liveComputeShader("roll_credits")
- val outputBuffer = colorBuffer(width, height, type = ColorType.UINT8)
-
- val size = Math.max(width, height) * 2
- val noiseBuffer = colorBuffer(size, size, type = ColorType.UINT8)
- val noiseFilter = SimplexNoise3D()
- noiseFilter.scale = Vector3.ONE * 2.4
- noiseFilter.octaves = 8
- noiseFilter.premultipliedAlpha = true
+ val scale = if (enableAntialiasing) 2 else 1
+ val outputBuffer = colorBuffer(scale * width, scale * height, type = ColorType.UINT8)
// val camera_manager = CameraManager()
// extend(camera_manager)
extend {
- noiseFilter.seed = Vector3(0.01, 0.01, 0.001)
- noiseFilter.apply(emptyArray(), noiseBuffer)
- cs.image("noise_texture", 1, noiseBuffer.imageBinding(0, ImageAccess.READ))
-
// camera_manager.setUniforms(cs)
cs.uniform("seconds", seconds)
cs.image("output_image", 0, outputBuffer.imageBinding(0, ImageAccess.WRITE))
cs.execute(outputBuffer.width, outputBuffer.height, 1)
- drawer.image(outputBuffer)
+ drawer.image(outputBuffer, 0.0, 0.0, width.toDouble(), height.toDouble())
}
}
}
diff --git a/src/main/resources/shaders/modules/sdf.glsl b/src/main/resources/shaders/modules/sdf.glsl
index e7222b4..4c2f60c 100644
--- a/src/main/resources/shaders/modules/sdf.glsl
+++ b/src/main/resources/shaders/modules/sdf.glsl
@@ -26,8 +26,13 @@ float sd_ellipsoid(vec3 p, vec3 r) {
return k0 * (k0 - 1.0) / k1;
}
-float sd_cone(vec3 p, vec2 c) {
+float sdf_cone(vec3 p, vec2 c) {
vec2 q = vec2(length(p.xz), -p.y);
float d = length(q - c * max(dot(q, c), 0.0));
return d * ((q.x * c.y - q.y * c.x < 0.0) ? -1.0 : 1.0);
}
+
+float sdf_capsule(vec3 p, float h, float r) {
+ p.y -= clamp(p.y, 0.0, h);
+ return length(p) - r;
+}
diff --git a/src/main/resources/shaders/roll_credits.glsl b/src/main/resources/shaders/roll_credits.glsl
index ae3fdd5..416a5e6 100644
--- a/src/main/resources/shaders/roll_credits.glsl
+++ b/src/main/resources/shaders/roll_credits.glsl
@@ -5,8 +5,15 @@ layout(local_size_x = 1, local_size_y = 1) in;
#include <utils>
#include <noise>
-const float MAX_DISTANCE = 1000.;
-const int MAX_ITERATIONS = 500;
+// TODO: fix terrain lighting
+// TODO: add burn in front of asteroid
+// TODO: change leg texture
+// TODO: fog
+// TODO: post processing
+// TODO: structure on mountain
+
+const float MAX_DISTANCE = 1000.; // 1000.
+const int MAX_ITERATIONS = 800; // 600+
const float MIN_GAP = 0.001;
uniform float seconds = 0;
@@ -15,14 +22,13 @@ layout(rgba8) uniform readonly image2D noise_texture;
layout(rgba8) uniform writeonly image2D output_image;
uniform float antialiasing = 0.28;
-uniform bool enable_antialiasing = false;
+// uniform bool enable_antialiasing = false;
-// uniform vec3 camera_position = vec3(0, 1, -2);
-// uniform vec3 camera_position = vec3(-9.5, 2.0, 30.0); // character focus
-uniform vec3 camera_position = vec3(12., 16, 60); // death focus
+uniform vec3 camera_position = vec3(0, 1, -2);
const vec3 character_offset = vec3(-9.5, 2.6, 36.0);
-const vec3 death_offset = vec3(12., 16, 80);
+const vec3 death_offset = vec3(42., 70, 300);
+const vec3 plant1_offset = vec3(186.0, -68.0, 450.0);
vec3 pink = srgb(0.82, 0.33, 0.51);
vec3 teal = srgb(0.28, 0.74, 0.75);
@@ -41,9 +47,12 @@ float sample_noise(in vec2 p) {
const int O_DUNE1 = 1;
const int O_CAPE = 2;
-const int O_LEGS = 3;
-const int O_DEATH = 4;
-const int O_DEATHCONE = 5;
+const int O_WALKSTICK = 3;
+const int O_LEGS = 4;
+const int O_DEATH = 5;
+const int O_DEATHCONE = 6;
+const int O_PLANT1 = 7;
+const int O_PLANT1_BASE = 8;
float scene(in vec3 p, out int obj_id) {
float dune;
@@ -56,14 +65,21 @@ float scene(in vec3 p, out int obj_id) {
dune = sdf_plane(p, vec3(0, 1, 0), dune_elevation);
}
- float cape, legs;
+ float cape, legs, stick;
{
float ctheta = PI / 9;
vec3 charp = p - character_offset;
- cape = sd_cone(charp, vec2(sin(ctheta), cos(ctheta)));
- cape = smin(cape, sdf_circle(charp + vec3(0, 0.12, 0), 0.21), 0.26);
+ cape = sdf_cone(charp, vec2(sin(ctheta), cos(ctheta)));
cape = max(cape, -sdf_plane(charp, vec3(0, 1, 0), 1.20 + 0.04 * sin(16 * charp.x) + 0.6 * (0.76 - fbm(charp.xz / 1.5))));
cape = max(cape, -sdf_circle(charp + vec3(0, 1.42, -0.12), 0.51));
+ cape = smin(cape, sdf_circle(charp + vec3(0, 0.12, 0), 0.21), 0.26);
+ cape = smin(cape, sdf_box(charp + vec3(0.22, 0.64, 0), vec3(0.1, 0.22, 0.1), 0.1), 0.1);
+ cape = smin(cape, sdf_box(charp + vec3(-0.22, 0.64, 0), vec3(0.1, 0.22, 0.1), 0.1), 0.1);
+ float tilt = -PI / 3;
+ vec3 handp = charp + vec3(-0.42, 0.82, 0);
+ handp.xz *= mat2x2(cos(tilt), -sin(tilt), sin(tilt), cos(tilt));
+ cape = smin(cape, sdf_box(handp, vec3(0.22, 0.08, 0.08), 0.08), 0.06);
+ stick = sdf_box(charp + vec3(-0.48, 0.86, -0.1), vec3(0.02, 0.9, 0.02), 0.04);
legs = sdf_box(charp + vec3(0.1, 1.6, 0.1), vec3(0.08, 0.3, 0.08), 0.1);
legs = min(legs, sdf_box(charp + vec3(-0.2, 1.6, 0.1), vec3(0.08, 0.3, 0.08), 0.1));
}
@@ -71,40 +87,60 @@ float scene(in vec3 p, out int obj_id) {
float death, deathcone;
{
vec3 dp = p - death_offset;
- death = sdf_circle(dp, 2.0 - 1.4 * fbm(p, 2));
- float ctheta = PI / 21;
+ death = sdf_circle(dp, 4.2 - 1.8 * fbm(p / 2, 2));
+ float ctheta = PI / 17;
vec3 conep = dp;
float deaththeta = PI / 3;
conep.xy *= mat2x2(cos(deaththeta), -sin(deaththeta), sin(deaththeta), cos(deaththeta));
- conep -= vec3(0, 11.0, 0);
- conep -= vec3(0, sin(conep.y * 10), 0);
- deathcone = sd_cone(conep, vec2(sin(ctheta), cos(ctheta)));
- deathcone = max(deathcone, -sdf_plane(conep, vec3(0, 1, 0), 10));
+ conep -= vec3(0.0, 20.0, 1);
+ conep -= vec3(0, sin(conep.y * 2.8) * (0.2 + fbm(conep.xy * 2)) * 2.2, 0);
+ deathcone = sdf_cone(conep, vec2(sin(ctheta), cos(ctheta)));
+ deathcone = max(deathcone, -sdf_plane(conep, vec3(0, 1, 0), 20.0));
+ }
+
+ float plant1, plant1_base;
+ {
+ vec3 pos = p - plant1_offset;
+ vec3 pp = pos;
+ float spread = 0.7;
+ pp += vec3(fbm(pp.yy / 1.5) * spread, 0, fbm((pp.yy + 2) / 1.5) * spread) - vec3(pp.y * spread / 3, 0, pp.y * spread / 3);
+ pp.x = abs(pp.x) - 0.6 * pp.y + 0.06;
+ pp.x = abs(pp.x) - 0.2 * pp.y + 0.06;
+ pp.z = abs(pp.z) - 0.6 * pp.y + 0.06;
+ pp.z = abs(pp.z) - 0.2 * pp.y + 0.06;
+ plant1 = sdf_capsule(pp, 15, 1.2 * (sin(pp.y / 2 + 0.9) + 1.5) / 2);
+ plant1_base = sdf_circle(pos - vec3(-0.05, 0.1, -0.36), 2.8);
}
float dist = dune;
dist = min(dist, cape);
+ dist = min(dist, stick);
dist = min(dist, legs);
dist = min(dist, death);
dist = min(dist, deathcone);
+ dist = min(dist, smin(plant1, plant1_base, 0.1));
if (dist == dune) obj_id = O_DUNE1;
else if (dist == cape) obj_id = O_CAPE;
+ else if (dist == stick) obj_id = O_WALKSTICK;
else if (dist == legs) obj_id = O_LEGS;
else if (dist == death) obj_id = O_DEATH;
else if (dist == deathcone) obj_id = O_DEATHCONE;
+ else if (dist == plant1) obj_id = O_PLANT1;
+ else if (dist == plant1_base) obj_id = O_PLANT1_BASE;
return dist;
}
-vec3 get_material_properties(in int object_id, in vec3 surface_point, in vec2 screen_point, out float ambient) {
+vec3 get_material_properties(in int obj_id, in vec3 surface_point, in vec2 screen_point, in float dist, out float ambient) {
vec3 color = skyblue;
color = mix(color, skygreen, 1 - smoothstep(-0.2, 0.5, screen_point.y));
+ float fog = 0.3 * (1 - smoothstep(-0.5, 0.5, exp(-0.000001 * dist * dist * dist)));
ambient = 0.06;
- if (object_id == O_DUNE1) {
+ if (obj_id == O_DUNE1) {
color = sandred;
- color = mix(color, sandyellow, 1 - smoothstep(-0.2, 0.2, fbm(surface_point.xz * 2)));
- color = mix(color, red1, 1 - smoothstep(-0.2, 0.2, fbm((surface_point.xz + 2) * 4)));
- } else if (object_id == O_CAPE) {
+ color = mix(color, sandyellow, 1 - smoothstep(-0.2, 0.2, fbm(surface_point.xz / 2)));
+ color = mix(color, red1, 1 - smoothstep(-0.3, 0.3, fbm((surface_point.xz * 5) * 4)));
+ } else if (obj_id == O_CAPE) {
color = srgb(0.3, 0.3, 0.5);
float x = surface_point.x * 10;
float y = surface_point.y * 32;
@@ -114,17 +150,34 @@ vec3 get_material_properties(in int object_id, in vec3 surface_point, in vec2 sc
* step(surface_point.y, character_offset.y - 0.35)
* step(sin(surface_point.y * 50), 0.38));
ambient = 0.2;
- } else if (object_id == O_LEGS) {
+ } else if (obj_id == O_WALKSTICK) {
+ color = vec3(0);
+ } else if (obj_id == O_LEGS) {
color = vec3(0.04);
color = mix(color, srgb(0.3, 0.3, 0.5), step(sin(surface_point.y * 90), 0));
ambient = 0.01;
- } else if (object_id == O_DEATH) {
+ } else if (obj_id == O_DEATH) {
color = srgb(0.6, 0.5, 0.6);
ambient = 0.2;
- } else if (object_id == O_DEATHCONE) {
- color = srgb(1.0, 0.5, 0.6);
+ } else if (obj_id == O_DEATHCONE) {
+ float tail = sdf_circle(surface_point.xy - death_offset.xy - vec2(2.6, 1.3), 1.5);
+ color = mix(color, srgb(1.0, 0.6, 0.0), (1 - smoothstep(-0, 10, tail)) * 0.6);
+ color = mix(color, srgb(1.0, 0.3, 0.0), (1 - smoothstep(-0.5, 1, tail)) * 0.76);
ambient = 1;
+ fog = 0;
+ } else if (obj_id == O_PLANT1) {
+ color = srgb(0.48, 0.31, 0.61);
+ color = mix(color, srgb(0.78, 0.31, 0.61), 1 - step(sin((surface_point.x) * 20) * cos((surface_point.y) * 20) - 0.5, 0));
+ ambient = 0.2;
+ } else if (obj_id == O_PLANT1_BASE) {
+ color = srgb(0.78, 0.31, 0.61);
+ ambient = 0.2;
+ } else {
+ fog = 0;
}
+
+ color += fog;
+
return color;
}
@@ -137,8 +190,8 @@ float raymarch_scene(vec3 ray_origin, vec3 ray_direction, out int obj_id) {
if (gap <= MIN_GAP)
return dist;
}
- obj_id = 0;
- return -1;
+ obj_id = -1;
+ return dist;
}
vec3 surface_normal_scene(in vec3 p) {
@@ -151,24 +204,29 @@ vec3 surface_normal_scene(in vec3 p) {
}
vec3 image(vec2 uv) {
- int object_id = 0;
+ int obj_id = 0;
+
+ vec3 campos = camera_position;
+ // campos = character_offset - vec3(0, 0.5, 8); // character focus
+ // campos = death_offset - vec3(0, 0, 38); // death focus
+ // campos = plant1_offset - vec3(0, -12, 100); // plant focus
vec3 uv_direction = normalize(vec3(uv, 1));
- float dist = raymarch_scene(camera_position, uv_direction, object_id);
+ float dist = raymarch_scene(campos, uv_direction, obj_id);
- vec3 p = camera_position + uv_direction * dist;
+ vec3 p = campos + uv_direction * dist;
vec3 norm = surface_normal_scene(p);
- vec3 light = vec3(8, 300, -4);
+ vec3 light = vec3(8, 500, -4);
light = mix(light, vec3(0, light.y, -100), smoothstep(-20, 50, p.z));
- light = mix(light, vec3(0, light.y, 480), smoothstep(200, 400, p.z));
- light = mix(light, vec3(-8, 280, 1000), smoothstep(800, 1000, p.z));
+ light = mix(light, vec3(0, 280, 480), smoothstep(200, 400, p.z));
+ light = mix(light, vec3(-8, 500, 1000), smoothstep(760, 1000, p.z));
vec3 light_dir = normalize(light - p);
float ambient;
- vec3 color = get_material_properties(object_id, p, uv, ambient);
+ vec3 color = get_material_properties(obj_id, p, uv, dist, ambient);
- if (object_id > 0) {
+ if (obj_id > 0) {
float contrast = clamp(dot(norm, light_dir), 0, 1);
color *= clamp((1 - ambient) * contrast + ambient, 0, 1);
}
@@ -176,23 +234,24 @@ vec3 image(vec2 uv) {
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;
-}
+// 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);
+ // vec3 color = enable_antialiasing ? antialiased_image(uv) : image(uv);
+ vec3 color = image(uv);
imageStore(output_image, ivec2(gl_GlobalInvocationID.xy), vec4(color, 1));
}