diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/kotlin/org/openrndr/Preload.kt | 8 | ||||
| -rw-r--r-- | src/main/kotlin/phenax/extensions/HeadlessScreenshot.kt | 2 | ||||
| -rw-r--r-- | src/main/kotlin/roll_credits/RollCreditsProgram.kt | 19 | ||||
| -rw-r--r-- | src/main/resources/shaders/modules/sdf.glsl | 7 | ||||
| -rw-r--r-- | src/main/resources/shaders/roll_credits.glsl | 157 |
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)); } |
