Some misc small optimizations.
This commit is contained in:
parent
dcf25b92af
commit
a3a19e53ef
|
@ -63,6 +63,14 @@ impl SpectralSample {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_parts(e: Float4, wavelength: f32) -> SpectralSample {
|
||||
debug_assert!(wavelength >= WL_MIN && wavelength <= WL_MAX);
|
||||
SpectralSample {
|
||||
e: e,
|
||||
hero_wavelength: wavelength,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the nth wavelength
|
||||
fn wl_n(&self, n: usize) -> f32 {
|
||||
let wl = self.hero_wavelength + (WL_RANGE_Q * n as f32);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::cmp::PartialEq;
|
||||
use std::ops::{Add, Sub, Mul, Div, BitAnd};
|
||||
use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, BitAnd};
|
||||
|
||||
#[cfg(feature = "simd_perf")]
|
||||
use simd::{f32x4, bool32fx4};
|
||||
|
@ -347,6 +347,13 @@ impl Add for Float4 {
|
|||
}
|
||||
|
||||
|
||||
impl AddAssign for Float4 {
|
||||
fn add_assign(&mut self, rhs: Float4) {
|
||||
*self = *self + rhs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Sub for Float4 {
|
||||
type Output = Float4;
|
||||
|
||||
|
@ -366,6 +373,13 @@ impl Sub for Float4 {
|
|||
}
|
||||
|
||||
|
||||
impl SubAssign for Float4 {
|
||||
fn sub_assign(&mut self, rhs: Float4) {
|
||||
*self = *self - rhs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Mul for Float4 {
|
||||
type Output = Float4;
|
||||
|
||||
|
@ -403,6 +417,19 @@ impl Mul<f32> for Float4 {
|
|||
}
|
||||
|
||||
|
||||
impl MulAssign for Float4 {
|
||||
fn mul_assign(&mut self, rhs: Float4) {
|
||||
*self = *self * rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl MulAssign<f32> for Float4 {
|
||||
fn mul_assign(&mut self, rhs: f32) {
|
||||
*self = *self * rhs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Div for Float4 {
|
||||
type Output = Float4;
|
||||
|
||||
|
@ -439,6 +466,20 @@ impl Div<f32> for Float4 {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl DivAssign for Float4 {
|
||||
fn div_assign(&mut self, rhs: Float4) {
|
||||
*self = *self / rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl DivAssign<f32> for Float4 {
|
||||
fn div_assign(&mut self, rhs: f32) {
|
||||
*self = *self / rhs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Lerp for Float4 {
|
||||
fn lerp(self, other: Float4, alpha: f32) -> Float4 {
|
||||
(self * (1.0 - alpha)) + (other * alpha)
|
||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -57,6 +57,7 @@ use mem_arena::MemArena;
|
|||
|
||||
use parse::{parse_scene, DataTree};
|
||||
use ray::{Ray, AccelRay};
|
||||
use surface::SurfaceIntersection;
|
||||
use renderer::LightPath;
|
||||
use bbox::BBox;
|
||||
use bbox4::BBox4;
|
||||
|
@ -124,6 +125,8 @@ fn main() {
|
|||
if args.is_present("dev") {
|
||||
println!("Ray size: {} bytes", mem::size_of::<Ray>());
|
||||
println!("AccelRay size: {} bytes", mem::size_of::<AccelRay>());
|
||||
println!("SurfaceIntersection size: {} bytes",
|
||||
mem::size_of::<SurfaceIntersection>());
|
||||
println!("LightPath size: {} bytes", mem::size_of::<LightPath>());
|
||||
println!("BBox size: {} bytes", mem::size_of::<BBox>());
|
||||
println!("BBox4 size: {} bytes", mem::size_of::<BBox4>());
|
||||
|
@ -185,12 +188,15 @@ fn main() {
|
|||
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\t\tTraversal: {:.3}s",
|
||||
println!("\t\tTrace: {:.3}s",
|
||||
ntime * rstats.trace_time);
|
||||
println!("\t\t\tTraversal: {:.3}s",
|
||||
ntime * rstats.accel_traversal_time);
|
||||
println!("\t\tRay generation: {:.3}s",
|
||||
println!("\t\tInitial ray generation: {:.3}s",
|
||||
ntime * rstats.initial_ray_generation_time);
|
||||
println!("\t\tRay generation: {:.3}s",
|
||||
ntime * rstats.ray_generation_time);
|
||||
println!("\t\tSample writing: {:.3}s",
|
||||
println!("\t\tSample writing: {:.3}s",
|
||||
ntime * rstats.sample_writing_time);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use scoped_threadpool::Pool;
|
|||
use algorithm::partition_pair;
|
||||
use accel::ACCEL_TRAV_TIME;
|
||||
use color::{Color, XYZ, SpectralSample, map_0_1_to_wavelength};
|
||||
use float4::Float4;
|
||||
use hash::hash_u32;
|
||||
use hilbert;
|
||||
use image::Image;
|
||||
|
@ -37,6 +38,7 @@ pub struct Renderer<'a> {
|
|||
pub struct RenderStats {
|
||||
pub trace_time: f64,
|
||||
pub accel_traversal_time: f64,
|
||||
pub initial_ray_generation_time: f64,
|
||||
pub ray_generation_time: f64,
|
||||
pub sample_writing_time: f64,
|
||||
pub total_time: f64,
|
||||
|
@ -47,6 +49,7 @@ impl RenderStats {
|
|||
RenderStats {
|
||||
trace_time: 0.0,
|
||||
accel_traversal_time: 0.0,
|
||||
initial_ray_generation_time: 0.0,
|
||||
ray_generation_time: 0.0,
|
||||
sample_writing_time: 0.0,
|
||||
total_time: 0.0,
|
||||
|
@ -56,6 +59,7 @@ impl RenderStats {
|
|||
fn collect(&mut self, other: RenderStats) {
|
||||
self.trace_time += other.trace_time;
|
||||
self.accel_traversal_time += other.accel_traversal_time;
|
||||
self.initial_ray_generation_time += other.initial_ray_generation_time;
|
||||
self.ray_generation_time += other.ray_generation_time;
|
||||
self.sample_writing_time += other.sample_writing_time;
|
||||
self.total_time += other.total_time;
|
||||
|
@ -163,7 +167,7 @@ impl<'a> Renderer<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
stats.ray_generation_time += timer.tick() as f64;
|
||||
stats.initial_ray_generation_time += timer.tick() as f64;
|
||||
|
||||
// Trace the paths!
|
||||
let mut pi = paths.len();
|
||||
|
@ -186,8 +190,10 @@ impl<'a> Renderer<'a> {
|
|||
let max = (bucket.x + bucket.w, bucket.y + bucket.h);
|
||||
let mut img_bucket = img.get_bucket(min, max);
|
||||
for path in paths.iter() {
|
||||
let path_col = SpectralSample::from_parts(path.color,
|
||||
path.wavelength);
|
||||
let mut col = img_bucket.get(path.pixel_co.0, path.pixel_co.1);
|
||||
col += XYZ::from_spectral_sample(&path.color) / self.spp as f32;
|
||||
col += XYZ::from_spectral_sample(&path_col) / self.spp as f32;
|
||||
img_bucket.set(path.pixel_co.0, path.pixel_co.1, col);
|
||||
}
|
||||
stats.sample_writing_time += timer.tick() as f64;
|
||||
|
@ -291,14 +297,14 @@ impl<'a> Renderer<'a> {
|
|||
pub struct LightPath {
|
||||
pixel_co: (u32, u32),
|
||||
lds_offset: u32,
|
||||
dim_offset: u32,
|
||||
dim_offset: Cell<u32>,
|
||||
round: u32,
|
||||
time: f32,
|
||||
wavelength: f32,
|
||||
interaction: surface::SurfaceIntersection,
|
||||
light_attenuation: SpectralSample,
|
||||
pending_color_addition: SpectralSample,
|
||||
color: SpectralSample,
|
||||
light_attenuation: Float4,
|
||||
pending_color_addition: Float4,
|
||||
color: Float4,
|
||||
}
|
||||
|
||||
impl LightPath {
|
||||
|
@ -313,14 +319,14 @@ impl LightPath {
|
|||
(LightPath {
|
||||
pixel_co: pixel_co,
|
||||
lds_offset: lds_offset,
|
||||
dim_offset: 6,
|
||||
dim_offset: Cell::new(6),
|
||||
round: 0,
|
||||
time: time,
|
||||
wavelength: wavelength,
|
||||
interaction: surface::SurfaceIntersection::Miss,
|
||||
light_attenuation: SpectralSample::from_value(1.0, wavelength),
|
||||
pending_color_addition: SpectralSample::new(wavelength),
|
||||
color: SpectralSample::new(wavelength),
|
||||
light_attenuation: Float4::splat(1.0),
|
||||
pending_color_addition: Float4::splat(0.0),
|
||||
color: Float4::splat(0.0),
|
||||
},
|
||||
|
||||
scene.camera.generate_ray(image_plane_co.0,
|
||||
|
@ -330,9 +336,10 @@ impl LightPath {
|
|||
lens_uv.1))
|
||||
}
|
||||
|
||||
fn next_lds_samp(&mut self) -> f32 {
|
||||
let s = halton::sample(self.dim_offset, self.lds_offset);
|
||||
self.dim_offset += 1;
|
||||
fn next_lds_samp(&self) -> f32 {
|
||||
let s = halton::sample(self.dim_offset.get(), self.lds_offset);
|
||||
let inc = self.dim_offset.get() + 1;
|
||||
self.dim_offset.set(inc);
|
||||
s
|
||||
}
|
||||
|
||||
|
@ -346,8 +353,8 @@ impl LightPath {
|
|||
|
||||
// Result of shading ray, prepare light ray
|
||||
if self.round % 2 == 1 {
|
||||
if let &surface::SurfaceIntersection::Hit { intersection_data: idata, closure } =
|
||||
isect {
|
||||
if let &surface::SurfaceIntersection::Hit { intersection_data: ref idata,
|
||||
ref closure } = isect {
|
||||
// Hit something! Do the stuff
|
||||
self.interaction = *isect; // Store interaction for use in next phase
|
||||
|
||||
|
@ -367,7 +374,7 @@ impl LightPath {
|
|||
self.pending_color_addition = {
|
||||
let material = closure.as_surface_closure();
|
||||
let la = material.evaluate(ray.dir, shadow_vec, idata.nor, self.wavelength);
|
||||
light_color * la * self.light_attenuation / (light_pdf * light_sel_pdf)
|
||||
light_color.e * la.e * self.light_attenuation / (light_pdf * light_sel_pdf)
|
||||
};
|
||||
|
||||
// Calculate the shadow ray for testing if the light is
|
||||
|
@ -390,7 +397,7 @@ impl LightPath {
|
|||
}
|
||||
} else {
|
||||
// Didn't hit anything, so background color
|
||||
self.color += scene.world.background_color.to_spectral_sample(self.wavelength) *
|
||||
self.color += scene.world.background_color.to_spectral_sample(self.wavelength).e *
|
||||
self.light_attenuation;
|
||||
return false;
|
||||
}
|
||||
|
@ -405,8 +412,8 @@ impl LightPath {
|
|||
|
||||
// Calculate bounced lighting!
|
||||
if self.round < 6 {
|
||||
if let surface::SurfaceIntersection::Hit { intersection_data: idata, closure } =
|
||||
self.interaction {
|
||||
if let surface::SurfaceIntersection::Hit { intersection_data: ref idata,
|
||||
ref closure } = self.interaction {
|
||||
// Sample material
|
||||
let (dir, filter, pdf) = {
|
||||
let material = closure.as_surface_closure();
|
||||
|
@ -417,7 +424,7 @@ impl LightPath {
|
|||
|
||||
// Account for the additional light attenuation from
|
||||
// this bounce
|
||||
self.light_attenuation *= filter / pdf;
|
||||
self.light_attenuation *= filter.e / pdf;
|
||||
|
||||
// Calculate the ray for this bounce
|
||||
*ray = Ray::new(idata.pos + dir.normalized() * 0.0001, dir, self.time, false);
|
||||
|
|
Loading…
Reference in New Issue
Block a user