diff --git a/src/bin/minitracer/trace.wgsl b/src/bin/minitracer/trace.wgsl index bd22c1c..6b6df27 100644 --- a/src/bin/minitracer/trace.wgsl +++ b/src/bin/minitracer/trace.wgsl @@ -69,8 +69,8 @@ fn to_sphere(center: vec3f, radius: f32, t: ptr) -> bool { fn trace_fragment(in: Varying) -> vec3f { seed(in.screen); - var result = vec3(0.0); - var color = vec3(1.0, 1.0, 1.0); + var result = vec3(0.); + var color = vec3(1.); pos = params.eye; let off_px = vec2(rand_float(), rand_float()) - .5; let off_w = mat2x3(dpdx(in.dir), dpdy(in.dir)); @@ -94,11 +94,18 @@ fn trace_fragment(in: Varying) -> vec3f { let s = spheres[sphere]; pos += t * ray; let normal = (pos - s.center) / s.radius; - result += color * s.emit_color; - color *= s.reflect_color; - let diffuse = normal + rand_sphere(); - let specular = reflect(ray, normal); - ray = normalize(mix(diffuse, specular, s.glossiness)); + if (all(s.emit_color == vec3(0.))) { + color *= s.reflect_color; + let diffuse = normal + rand_sphere(); + let specular = reflect(ray, normal); + ray = normalize(mix(diffuse, specular, s.glossiness)); + } else { + let d = dot(-ray, normal); + let strength = d * d; // it would be 1 for surface emission, but this models volume emission + result += color * s.emit_color * strength; + color *= (1. - strength); + pos += 1e-3 * ray; + } if (length(color) < params.min_strength) { break; }