From e80e1d09fe142cb9508067a7c8f2b92485aa4a56 Mon Sep 17 00:00:00 2001 From: numzero Date: Thu, 20 Nov 2025 14:19:58 +0300 Subject: [PATCH] add interreflections --- src/lib.rs | 49 ++++++++++++++++++++++++------------------ src/main.rs | 1 + ui/src/api.hxx | 1 + ui/src/main_window.cxx | 1 + ui/src/main_window.ui | 33 ++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ba7dd7e..8b7384d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,7 @@ pub struct RedrawArgs { pub light_spread: f32, pub accum_sigma: f32, pub accum_scale: f32, + pub reflections: u32, pub show_axes: bool, pub show_shapes: bool, pub show_hit_emission: bool, @@ -261,29 +262,35 @@ impl Core { } } } - let mut hits2: Vec = Vec::with_capacity(hits.len()); - for hit in &hits { - let reflector = Lambertian; - let reflected = reflector.reflect(&mut prng, hit.normal, hit.incident.dir); - let ray = Ray::new(hit.incident.base, reflected); - let Some(hit2) = scene.trace_ray(ray) else { - continue; - }; - hits2.push(hit2); - if args.show_indirect_hit { - source_ray_display.extend([ - Vertex { - pos: hit2.incident.base - 0.02 * hit2.incident.dir, - color: vec3(1., 0., 1.), - }, - Vertex { - pos: hit2.incident.base, - color: vec3(1., 1., 1.), - }, - ]); + if args.reflections > 0 { + let mut hits1 = hits.clone(); + for _ in 0..args.reflections { + let mut hits2: Vec = Vec::with_capacity(hits1.len()); + for hit in &hits1 { + let reflector = Lambertian; + let reflected = reflector.reflect(&mut prng, hit.normal, hit.incident.dir); + let ray = Ray::new(hit.incident.base, reflected); + let Some(hit2) = scene.trace_ray(ray) else { + continue; + }; + hits2.push(hit2); + if args.show_indirect_hit { + source_ray_display.extend([ + Vertex { + pos: hit2.incident.base - 0.02 * hit2.incident.dir, + color: vec3(1., 0., 1.), + }, + Vertex { + pos: hit2.incident.base, + color: vec3(1., 1., 1.), + }, + ]); + } + } + hits.extend(&hits2); + hits1 = hits2; } } - hits.extend(hits2); let mut camera_ray_display: Vec = Vec::with_capacity(camera_rays.len()); if args.show_light { let sigma2 = args.accum_sigma.powi(2); diff --git a/src/main.rs b/src/main.rs index 7f8a128..f08bf16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,6 +52,7 @@ impl MainWindow { light_spread: 0.125, accum_sigma: 0.025, accum_scale: 0.01, + reflections: 2, show_axes: true, show_shapes: true, show_hit_emission: false, diff --git a/ui/src/api.hxx b/ui/src/api.hxx index ff7038e..caf32cd 100644 --- a/ui/src/api.hxx +++ b/ui/src/api.hxx @@ -20,6 +20,7 @@ struct RedrawArgs { float light_spread = 0.; float accum_sigma = 1.; float accum_scale = 1.; + std::uint32_t reflections = 0; bool show_axes = true; bool show_shapes = true; bool show_hit_emission = true; diff --git a/ui/src/main_window.cxx b/ui/src/main_window.cxx index 033645f..dff2f7d 100644 --- a/ui/src/main_window.cxx +++ b/ui/src/main_window.cxx @@ -31,6 +31,7 @@ void PhotonLight::updateView() { .light_spread = 0.125, .accum_sigma = exp10f(m_ui->accumSigma->value() / 25.0), .accum_scale = exp10f(m_ui->accumScale->value() / 25.0), + .reflections = std::uint32_t(m_ui->reflections->value()), .show_axes = m_ui->displayAxes->isChecked(), .show_shapes = m_ui->displayShapes->isChecked(), .show_hit_emission = m_ui->displayEmitted->isChecked(), diff --git a/ui/src/main_window.ui b/ui/src/main_window.ui index 44b57c5..23bf13b 100644 --- a/ui/src/main_window.ui +++ b/ui/src/main_window.ui @@ -254,6 +254,23 @@ + + + + Reflections + + + + + + + 20 + + + 2 + + + @@ -577,6 +594,22 @@ + + reflections + valueChanged(int) + MainWindow + updateView() + + + 1489 + 712 + + + 799 + 599 + + + updateView()