From 6f0b6ccedb47710da5a4b1cd2697547333ecae28 Mon Sep 17 00:00:00 2001 From: altunenes Date: Thu, 14 Nov 2024 18:51:29 +0300 Subject: [PATCH] update adelson --- shaders/adelson.wgsl | 84 ++++++++++++++++++++++++++------------------ src/adelson.rs | 2 +- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/shaders/adelson.wgsl b/shaders/adelson.wgsl index 69d42fc..997d8f5 100644 --- a/shaders/adelson.wgsl +++ b/shaders/adelson.wgsl @@ -34,6 +34,22 @@ fn sdCylinder(p: vec3) -> f32 { let d = abs(vec2(length(p_adj.xz), p_adj.y)) - vec2(CYLINDER_RADIUS, CYLINDER_HEIGHT); return min(max(d.x, d.y), 0.0) + length(max(d, vec2(0.0))); } +fn refsqpos(time: f32) -> vec2 { + let startPos = vec2(-0.25, 0.15); + let endPos = vec2(0.05, -0.25); + + var t = (sin(time * 0.5) + 1.0) * 0.5; + t = smoothstep(0.0, 1.0, t); + + return mix(startPos, endPos, t); +} + +fn refsq(p: vec2, time: f32) -> f32 { + let squarePos = refsqpos(time); + let d = abs(p - squarePos) - vec2(0.05, 0.05); + + return step(max(d.x, d.y), 0.0); +} fn sdPlane(p: vec3) -> f32 { let q = abs(p.xz); @@ -59,28 +75,28 @@ fn checkerboard(p: vec2) -> f32 { let grid = floor(p / CHECKER_SCALE); return fract((grid.x + grid.y) * 0.5) * 2.0; } -fn getSceneDistance(p: vec3) -> vec2 { +fn scene(p: vec3) -> vec2 { let cylinder = sdCylinder(p); let plane = sdPlane(p); let id = select(0.0, 1.0, cylinder < plane); return vec2(min(cylinder, plane), id); } -fn getNormal(p: vec3) -> vec3 { +fn norm(p: vec3) -> vec3 { let e = vec2(0.01, 0.0); let n = vec3( - getSceneDistance(p + e.xyy).x - getSceneDistance(p - e.xyy).x, - getSceneDistance(p + e.yxy).x - getSceneDistance(p - e.yxy).x, - getSceneDistance(p + e.yyx).x - getSceneDistance(p - e.yyx).x + scene(p + e.xyy).x - scene(p - e.xyy).x, + scene(p + e.yxy).x - scene(p - e.yxy).x, + scene(p + e.yyx).x - scene(p - e.yyx).x ); return normalize(n); } -fn getShadow(p: vec3, lightDir: vec3) -> f32 { +fn shad(p: vec3, lightDir: vec3) -> f32 { var res = 1.0; var t = 0.1; let k = 16.0; for(var i = 0; i < 32; i++) { - let h = getSceneDistance(p + lightDir * t).x; + let h = scene(p + lightDir * t).x; res = min(res, k * h / t); t += h; if (res < 0.001 || t > 20.0) { @@ -90,52 +106,52 @@ fn getShadow(p: vec3, lightDir: vec3) -> f32 { return clamp(res, 0.1, 1.0); } -fn render(ro: vec3, rd: vec3) -> vec3 { - var col = vec3(0.1); +fn render(ro: vec3, rd: vec3, time: f32) -> vec3 { + var col = vec3(0.1, 0.1, 0.1); var t = 0.0; - var res = vec2(0.0); + var res = vec2(0.0, 0.0); - for(var i = 0; i < MAX_STEPS; i++) { + for (var i = 0; i < 100; i = i + 1) { let p = ro + rd * t; - res = getSceneDistance(p); - if (res.x < SURF_DIST || t > MAX_DIST) { + res = scene(p); + if (res.x < 0.001 || t > 100.0) { break; } - t += res.x; + t = t + res.x; } - if (t < MAX_DIST) { + + if (t < 100.0) { let p = ro + rd * t; - let n = getNormal(p); - let shadow = getShadow(p + n * 0.02, LIGHT_DIR); - + let n = norm(p); + let shadow = shad(p + n * 0.02, normalize(vec3(-1.0, 1.2, -0.5))); if (res.y > 0.5) { col = vec3(0.2, 0.8, 0.2); } else { let check = checkerboard(p.xz); if (check < 0.0) { - col = vec3(0.1); + col = vec3(0.1, 0.1, 0.1); } else { - col = mix(vec3(0.15), vec3(0.85), check); - let isDot = dotss(p.xz); - if (isDot > 0.5) { + col = mix(vec3(0.15, 0.15, 0.15), vec3(0.85, 0.85, 0.85), check); + if (refsq(p.xz, time) > 0.5) { + col = vec3(29.0 / 255.0, 29.0 / 255.0, 29.0 / 255.0); + return col; + } + if (dotss(p.xz) > 0.5) { col = vec3(0.8, 0.0, 0.0); + return col; } } } - - let diff = max(dot(n, LIGHT_DIR), 0.0); - let amb = params.blue; - - let isDot = dotss(p.xz); - if (isDot < 0.5 || res.y > 0.5) { - col *= amb + (1.0 - amb) * diff * shadow; - let ao = 1.0 - 0.2 * (1.0 - shadow); - col *= ao; - } + let diff = max(dot(n, normalize(vec3(-1.0, 1.2, -0.5))), 0.0); + let amb = params.blue; // "illusion constant" value + col = col * (amb + (1.0 - amb) * diff * shadow); + let ao = 1.0 - 0.2 * (1.0 - shadow); + col = col * ao; } - + return col; } + @fragment fn main(@builtin(position) FragCoord: vec4) -> @location(0) vec4 { let resolution = vec2(1920.0, 1080.0); @@ -154,7 +170,7 @@ fn main(@builtin(position) FragCoord: vec4) -> @location(0) vec4 { let uu = normalize(cross(ww, vec3(0.0, 1.0, 0.0))); let vv = normalize(cross(uu, ww)); let rd = normalize(uv.x * uu + uv.y * vv + params.lambda * ww); - var col = render(ro, rd); + var col = render(ro, rd,u_time.time); col = pow(col, vec3(params.gamma)); return vec4(col, 1.0); diff --git a/src/adelson.rs b/src/adelson.rs index 00dc26a..6506726 100644 --- a/src/adelson.rs +++ b/src/adelson.rs @@ -44,7 +44,7 @@ fn update(app: &App, model: &mut Model, update: Update) { model.settings.show_ui = !model.settings.show_ui; } egui::Window::new("Shader Settings").show(&ctx, |ui| { - ui.add(egui::Slider::new(&mut model.settings.lambda, 0.001..=5.0).text("l")); + ui.add(egui::Slider::new(&mut model.settings.lambda, 0.1..=10.0).text("l")); ui.add(egui::Slider::new(&mut model.settings.theta, 0.0..=5.0).text("CYLINDER_HEIGHT")); ui.add(egui::Slider::new(&mut model.settings.sigma, 0.0..=2.0).text("CYLINDER_RADIUS")); ui.add(egui::Slider::new(&mut model.settings.gamma, 0.0..=2.0).text("gamma"));