diff --git a/rtiow/src/renderer.rs b/rtiow/src/renderer.rs index 7823448..5355e9d 100644 --- a/rtiow/src/renderer.rs +++ b/rtiow/src/renderer.rs @@ -146,9 +146,12 @@ pub struct Opt { /// Sub-samples per pixel #[structopt(short = "s", long = "subsample", default_value = "8")] pub subsamples: usize, + /// Use adaptive subsampling + #[structopt(long = "adaptive")] + pub adaptive_subsampling: bool, /// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box", /// "cornell_smoke", "perlin_debug", "final" - #[structopt(long = "model", default_value = "perlin_debug")] + #[structopt(long = "model", default_value = "book")] pub model: Model, /// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof #[structopt(long = "pprof", parse(from_os_str))] @@ -180,6 +183,8 @@ pub struct Scene { pub world: Box, pub camera: Camera, pub subsamples: usize, + /// overrides subsamples setting. + pub adaptive_subsampling: bool, pub num_threads: Option, pub width: usize, pub height: usize, @@ -214,6 +219,7 @@ impl Default for Scene { )), camera, subsamples: 0, + adaptive_subsampling: false, num_threads: None, width: 0, height: 0, @@ -304,10 +310,14 @@ static PIXEL_COUNT: AtomicUsize = AtomicUsize::new(0); fn render_pixel(scene: &Scene, x: usize, y: usize) -> Vec3 { let mut pixel: Vec3 = Default::default(); - for _ in 0..scene.subsamples { - pixel = pixel + trace_pixel(x, y, scene); - } - pixel = pixel / scene.subsamples as f32; + let pixel = if scene.adaptive_subsampling { + Default::default() + } else { + for _ in 0..scene.subsamples { + pixel = pixel + trace_pixel(x, y, scene); + } + pixel / scene.subsamples as f32 + }; // Gamma correct, use gamma 2 correction, which is 1/gamma where gamma=2 which is 1/2 or // sqrt. PIXEL_COUNT.fetch_add(1, Ordering::SeqCst); @@ -351,6 +361,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i let scene = Arc::new(scene); let pixel_req_rx = Arc::new(Mutex::new(pixel_req_rx)); info!("Creating {} render threads", num_threads); + info!("Adaptive subsampling: {}", scene.adaptive_subsampling); for i in 0..num_threads { let s = sync::Arc::clone(&scene); let pixel_req_rx = pixel_req_rx.clone(); diff --git a/rtiow/src/scenes/book.rs b/rtiow/src/scenes/book.rs index fd2cea0..649bcad 100644 --- a/rtiow/src/scenes/book.rs +++ b/rtiow/src/scenes/book.rs @@ -51,6 +51,7 @@ pub fn new(opt: &Opt) -> Scene { camera, world, subsamples: opt.subsamples, + adaptive_subsampling: opt.adaptive_subsampling, num_threads: opt.num_threads, width: opt.width, height: opt.height,