Added more detailed render stats.
This commit is contained in:
parent
7884cff604
commit
8b14e46bc1
15
src/main.rs
15
src/main.rs
|
@ -179,8 +179,19 @@ fn main() {
|
||||||
println!("\tBuilt scene in {:.3}s", t.tick());
|
println!("\tBuilt scene in {:.3}s", t.tick());
|
||||||
|
|
||||||
println!("Rendering scene with {} threads...", thread_count);
|
println!("Rendering scene with {} threads...", thread_count);
|
||||||
let mut image = r.render(max_samples_per_bucket, thread_count);
|
let (mut image, rstats) = r.render(max_samples_per_bucket, thread_count);
|
||||||
println!("\tRendered scene in {:.3}s", t.tick());
|
// Print render stats
|
||||||
|
{
|
||||||
|
let rtime = t.tick();
|
||||||
|
let ntime = rtime as f64 / rstats.total_time;
|
||||||
|
println!("\tRendered scene in {:.3}s", rtime);
|
||||||
|
println!("\t\tTrace: {:.3}s", ntime * rstats.trace_time);
|
||||||
|
println!("\t\tRay generation: {:.3}s",
|
||||||
|
ntime * rstats.ray_generation_time);
|
||||||
|
println!("\t\tSample writing: {:.3}s",
|
||||||
|
ntime * rstats.sample_writing_time);
|
||||||
|
println!("\t\tTotal: {:.3}s", ntime * rstats.total_time);
|
||||||
|
}
|
||||||
|
|
||||||
println!("Writing image to disk...");
|
println!("Writing image to disk...");
|
||||||
if r.output_file.ends_with(".png") {
|
if r.output_file.ends_with(".png") {
|
||||||
|
|
|
@ -18,6 +18,7 @@ use ray::Ray;
|
||||||
use sampling::halton;
|
use sampling::halton;
|
||||||
use scene::Scene;
|
use scene::Scene;
|
||||||
use surface;
|
use surface;
|
||||||
|
use timer::Timer;
|
||||||
use tracer::Tracer;
|
use tracer::Tracer;
|
||||||
use transform_stack::TransformStack;
|
use transform_stack::TransformStack;
|
||||||
|
|
||||||
|
@ -31,8 +32,34 @@ pub struct Renderer<'a> {
|
||||||
pub scene: Scene<'a>,
|
pub scene: Scene<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct RenderStats {
|
||||||
|
pub trace_time: f64,
|
||||||
|
pub ray_generation_time: f64,
|
||||||
|
pub sample_writing_time: f64,
|
||||||
|
pub total_time: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderStats {
|
||||||
|
fn new() -> RenderStats {
|
||||||
|
RenderStats {
|
||||||
|
trace_time: 0.0,
|
||||||
|
ray_generation_time: 0.0,
|
||||||
|
sample_writing_time: 0.0,
|
||||||
|
total_time: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collect(&mut self, other: RenderStats) {
|
||||||
|
self.trace_time += other.trace_time;
|
||||||
|
self.ray_generation_time += other.ray_generation_time;
|
||||||
|
self.sample_writing_time += other.sample_writing_time;
|
||||||
|
self.total_time += other.total_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Renderer<'a> {
|
impl<'a> Renderer<'a> {
|
||||||
pub fn render(&self, max_samples_per_bucket: u32, thread_count: u32) -> Image {
|
pub fn render(&self, max_samples_per_bucket: u32, thread_count: u32) -> (Image, RenderStats) {
|
||||||
let mut tpool = Pool::new(thread_count);
|
let mut tpool = Pool::new(thread_count);
|
||||||
|
|
||||||
let image = Image::new(self.resolution.0, self.resolution.1);
|
let image = Image::new(self.resolution.0, self.resolution.1);
|
||||||
|
@ -40,6 +67,8 @@ impl<'a> Renderer<'a> {
|
||||||
|
|
||||||
let all_jobs_queued = RwLock::new(false);
|
let all_jobs_queued = RwLock::new(false);
|
||||||
|
|
||||||
|
let collective_stats = RwLock::new(RenderStats::new());
|
||||||
|
|
||||||
// Pre-calculate some useful values related to the image plane
|
// Pre-calculate some useful values related to the image plane
|
||||||
let cmpx = 1.0 / self.resolution.0 as f32;
|
let cmpx = 1.0 / self.resolution.0 as f32;
|
||||||
let cmpy = 1.0 / self.resolution.1 as f32;
|
let cmpy = 1.0 / self.resolution.1 as f32;
|
||||||
|
@ -65,13 +94,18 @@ impl<'a> Renderer<'a> {
|
||||||
let jq = &job_queue;
|
let jq = &job_queue;
|
||||||
let ajq = &all_jobs_queued;
|
let ajq = &all_jobs_queued;
|
||||||
let img = ℑ
|
let img = ℑ
|
||||||
|
let cstats = &collective_stats;
|
||||||
scope.execute(move || {
|
scope.execute(move || {
|
||||||
|
let mut stats = RenderStats::new();
|
||||||
|
let mut timer = Timer::new();
|
||||||
|
let mut total_timer = Timer::new();
|
||||||
|
|
||||||
let mut paths = Vec::new();
|
let mut paths = Vec::new();
|
||||||
let mut rays = Vec::new();
|
let mut rays = Vec::new();
|
||||||
let mut tracer = Tracer::from_assembly(&self.scene.root);
|
let mut tracer = Tracer::from_assembly(&self.scene.root);
|
||||||
let mut xform_stack = TransformStack::new();
|
let mut xform_stack = TransformStack::new();
|
||||||
|
|
||||||
loop {
|
'render_loop: loop {
|
||||||
paths.clear();
|
paths.clear();
|
||||||
rays.clear();
|
rays.clear();
|
||||||
|
|
||||||
|
@ -83,11 +117,12 @@ impl<'a> Renderer<'a> {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if *ajq.read().unwrap() == true {
|
if *ajq.read().unwrap() == true {
|
||||||
return;
|
break 'render_loop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timer.tick();
|
||||||
// Generate light paths and initial rays
|
// Generate light paths and initial rays
|
||||||
for y in bucket.y..(bucket.y + bucket.h) {
|
for y in bucket.y..(bucket.y + bucket.h) {
|
||||||
for x in bucket.x..(bucket.x + bucket.w) {
|
for x in bucket.x..(bucket.x + bucket.w) {
|
||||||
|
@ -124,18 +159,21 @@ impl<'a> Renderer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stats.ray_generation_time += timer.tick() as f64;
|
||||||
|
|
||||||
// Trace the paths!
|
// Trace the paths!
|
||||||
let mut pi = paths.len();
|
let mut pi = paths.len();
|
||||||
while pi > 0 {
|
while pi > 0 {
|
||||||
// Test rays against scene
|
// Test rays against scene
|
||||||
let isects = tracer.trace(&rays);
|
let isects = tracer.trace(&rays);
|
||||||
|
stats.trace_time += timer.tick() as f64;
|
||||||
|
|
||||||
// Determine next rays to shoot based on result
|
// Determine next rays to shoot based on result
|
||||||
pi =
|
pi =
|
||||||
partition_pair(&mut paths[..pi], &mut rays[..pi], |i, path, ray| {
|
partition_pair(&mut paths[..pi], &mut rays[..pi], |i, path, ray| {
|
||||||
path.next(&mut xform_stack, &self.scene, &isects[i], &mut *ray)
|
path.next(&mut xform_stack, &self.scene, &isects[i], &mut *ray)
|
||||||
});
|
});
|
||||||
|
stats.ray_generation_time += timer.tick() as f64;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate color based on ray hits and save to image
|
// Calculate color based on ray hits and save to image
|
||||||
|
@ -148,6 +186,7 @@ impl<'a> Renderer<'a> {
|
||||||
col += XYZ::from_spectral_sample(&path.color) / self.spp as f32;
|
col += XYZ::from_spectral_sample(&path.color) / self.spp as f32;
|
||||||
img_bucket.set(path.pixel_co.0, path.pixel_co.1, col);
|
img_bucket.set(path.pixel_co.0, path.pixel_co.1, col);
|
||||||
}
|
}
|
||||||
|
stats.sample_writing_time += timer.tick() as f64;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print render progress
|
// Print render progress
|
||||||
|
@ -169,6 +208,11 @@ impl<'a> Renderer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stats.total_time += total_timer.tick() as f64;
|
||||||
|
|
||||||
|
// Collect stats
|
||||||
|
cstats.write().unwrap().collect(stats);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,8 +273,8 @@ impl<'a> Renderer<'a> {
|
||||||
// Clear percentage progress print
|
// Clear percentage progress print
|
||||||
print!("\r \r");
|
print!("\r \r");
|
||||||
|
|
||||||
// Return the rendered image
|
// Return the rendered image and stats
|
||||||
return image;
|
return (image, *collective_stats.read().unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user