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