From d390df6564f3194699846d1399b75593b8b1c619 Mon Sep 17 00:00:00 2001 From: numzero Date: Mon, 23 Dec 2024 21:06:36 +0300 Subject: [PATCH] Make spheres a bit fuzzy --- src/trace.wgsl | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/trace.wgsl b/src/trace.wgsl index 1cabcb8..cba8e84 100644 --- a/src/trace.wgsl +++ b/src/trace.wgsl @@ -60,6 +60,8 @@ fn to_sphere(center: vec3f, radius: f32, t: ptr) -> bool { } fn trace_fragment(in: Varying) -> vec4f { + seed(in.screen); + var result = vec4(0.0, 0.0, 0.0, 0.0); var color = vec3(1.0, 1.0, 1.0); pos = in.eye; @@ -83,7 +85,9 @@ fn trace_fragment(in: Varying) -> vec4f { let normal = (pos - s.center) / s.radius; result += vec4(color * s.emit_color * -dot(normal, ray), 0.0); color *= s.reflect_color; - ray = reflect(ray, normal); + let diffuse = normal + rand_sphere(); + let specular = reflect(ray, normal); + ray = normalize(mix(diffuse, specular, 0.8)); if (length(color) < params.min_strength) { break; } @@ -91,3 +95,38 @@ fn trace_fragment(in: Varying) -> vec4f { return clamp(result, vec4(0.0), vec4(1.0)); } + +fn hash(key : u32) -> u32 { + var v = key; + v *= 0xb384af1bu; + v ^= v >> 15u; + return v; +} + +var rand_state: u32; + +fn seed(key: vec4f) { + let x = bitcast(key.x); + let y = bitcast(key.y); + rand_state = hash(hash(x) ^ y); +} + +fn rand_next() -> u32 { + rand_state = hash(rand_state); + return rand_state; +} + +fn rand_float() -> f32 { + return f32(rand_next()) / 0x1p32; +} + +fn rand_sphere() -> vec3f { + loop { + let v = vec3f(rand_float(), rand_float(), rand_float()); + let l = length(v); + if (length(v) <= 1.0) { + return v / l; + } + } + return vec3f(0.0); // unreachable +}