Add some faster AABB hit implementations.
Switch e?println to info/trace logging.
This commit is contained in:
parent
4a9754dfdb
commit
aa26c79f6d
72
rtiow/Cargo.lock
generated
72
rtiow/Cargo.lock
generated
@ -44,6 +44,16 @@ name = "cfg-if"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.32.0"
|
||||
@ -225,6 +235,14 @@ dependencies = [
|
||||
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzw"
|
||||
version = "0.10.0"
|
||||
@ -403,9 +421,11 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossbeam-channel 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stderrlog 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"structopt 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -453,6 +473,17 @@ name = "stable_deref_trait"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "stderrlog"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.7.0"
|
||||
@ -487,6 +518,14 @@ dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.1"
|
||||
@ -505,6 +544,24 @@ dependencies = [
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.5"
|
||||
@ -557,6 +614,14 @@ name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wincolor"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
@ -565,6 +630,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||
"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781"
|
||||
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
|
||||
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
|
||||
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
|
||||
@ -585,6 +651,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
|
||||
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
|
||||
"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
|
||||
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
|
||||
"checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
|
||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||
@ -613,12 +680,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
|
||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||
"checksum stderrlog 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "61dc66b7ae72b65636dbf36326f9638fb3ba27871bb737a62e2c309b87d91b70"
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum structopt 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8e9ad6a11096cbecdcca0cc6aa403fdfdbaeda2fb3323a39c98e6a166a1e45a"
|
||||
"checksum structopt-derive 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4cbce8ccdc62166bd594c14396a3242bf94c337a51dbfa9be1076dd74b3db2af"
|
||||
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
|
||||
"checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
|
||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
@ -628,3 +699,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
|
||||
|
||||
@ -10,3 +10,5 @@ crossbeam-channel = "0.2.4"
|
||||
num_cpus = "1.8.0"
|
||||
rayon = "1.0.2"
|
||||
structopt = "0.2.10"
|
||||
stderrlog = "0.4.1"
|
||||
log = "0.4.5"
|
||||
|
||||
@ -5,29 +5,104 @@ use vec3::Vec3;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct AABB {
|
||||
pub min: Vec3,
|
||||
pub max: Vec3,
|
||||
bounds: [Vec3; 2],
|
||||
}
|
||||
|
||||
impl fmt::Display for AABB {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "({})-({})", self.min, self.max)
|
||||
write!(f, "({})-({})", self.bounds[0], self.bounds[1])
|
||||
}
|
||||
}
|
||||
|
||||
fn min(x: f32, y: f32) -> f32 {
|
||||
if x < y {
|
||||
x
|
||||
} else {
|
||||
y
|
||||
}
|
||||
}
|
||||
|
||||
fn max(x: f32, y: f32) -> f32 {
|
||||
if x > y {
|
||||
x
|
||||
} else {
|
||||
y
|
||||
}
|
||||
}
|
||||
|
||||
impl AABB {
|
||||
pub fn new(min: Vec3, max: Vec3) -> AABB {
|
||||
AABB { min, max }
|
||||
AABB { bounds: [min, max] }
|
||||
}
|
||||
|
||||
pub fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> bool {
|
||||
pub fn min(&self) -> Vec3 {
|
||||
self.bounds[0]
|
||||
}
|
||||
pub fn max(&self) -> Vec3 {
|
||||
self.bounds[1]
|
||||
}
|
||||
|
||||
pub fn hit2(&self, r: Ray, t_min: f32, t_max: f32) -> bool {
|
||||
let mut t_min = t_min;
|
||||
let mut t_max = t_max;
|
||||
for axis in 0..3 {
|
||||
let t0 = ((self.min[axis] - r.origin[axis]) / r.direction[axis])
|
||||
.min((self.max[axis] - r.origin[axis]) / r.direction[axis]);
|
||||
let t1 = ((self.min[axis] - r.origin[axis]) / r.direction[axis])
|
||||
.max((self.max[axis] - r.origin[axis]) / r.direction[axis]);
|
||||
let d_inv = 1.0 / r.direction[axis];
|
||||
let t0 = min(
|
||||
(self.min()[axis] - r.origin[axis]) * d_inv,
|
||||
(self.max()[axis] - r.origin[axis]) * d_inv,
|
||||
);
|
||||
let t1 = max(
|
||||
(self.min()[axis] - r.origin[axis]) * d_inv,
|
||||
(self.max()[axis] - r.origin[axis]) * d_inv,
|
||||
);
|
||||
t_min = max(t0, t_min);
|
||||
t_max = min(t1, t_max);
|
||||
if t_max <= t_min {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn hit(&self, r: Ray, t0: f32, t1: f32) -> bool {
|
||||
let mut t_min = (self.bounds[r.sign[0]].x - r.origin.x) * r.inv_direction.x;
|
||||
let mut t_max = (self.bounds[1 - r.sign[0]].x - r.origin.x) * r.inv_direction.x;
|
||||
let t_y_min = (self.bounds[r.sign[0]].y - r.origin.y) * r.inv_direction.y;
|
||||
let t_y_max = (self.bounds[1 - r.sign[0]].y - r.origin.y) * r.inv_direction.y;
|
||||
|
||||
if t_min > t_y_max || t_y_min > t_max {
|
||||
return false;
|
||||
}
|
||||
|
||||
if t_y_min > t_min {
|
||||
t_min = t_y_min;
|
||||
}
|
||||
if t_y_max < t_max {
|
||||
t_max = t_y_max;
|
||||
}
|
||||
|
||||
let t_z_min = (self.bounds[r.sign[2]].z - r.origin.z) * r.inv_direction.z;
|
||||
let t_z_max = (self.bounds[1 - r.sign[2]].z - r.origin.z) * r.inv_direction.z;
|
||||
if t_min > t_z_max || t_z_min > t_max {
|
||||
return false;
|
||||
}
|
||||
if t_z_min > t_min {
|
||||
t_min = t_z_min;
|
||||
}
|
||||
if t_z_max < t_max {
|
||||
t_max = t_z_max;
|
||||
}
|
||||
t_min < t1 && t_max > t0
|
||||
}
|
||||
|
||||
pub fn hit_original(&self, r: Ray, t_min: f32, t_max: f32) -> bool {
|
||||
let mut t_min = t_min;
|
||||
let mut t_max = t_max;
|
||||
for axis in 0..3 {
|
||||
let t0 = ((self.min()[axis] - r.origin[axis]) * r.inv_direction[axis])
|
||||
.min((self.max()[axis] - r.origin[axis]) * r.inv_direction[axis]);
|
||||
let t1 = ((self.min()[axis] - r.origin[axis]) * r.inv_direction[axis])
|
||||
.max((self.max()[axis] - r.origin[axis]) * r.inv_direction[axis]);
|
||||
t_min = t0.max(t_min);
|
||||
t_max = t1.min(t_max);
|
||||
if t_max <= t_min {
|
||||
@ -36,18 +111,37 @@ impl AABB {
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn hit_fast(&self, r: Ray, _t_min: f32, _t_max: f32) -> bool {
|
||||
let b = self;
|
||||
let mut t1 = (b.min()[0] - r.origin[0]) * 1. / r.direction[0];
|
||||
let mut t2 = (b.max()[0] - r.origin[0]) * 1. / r.direction[0];
|
||||
|
||||
let mut tmin = t1.min(t2);
|
||||
let mut tmax = t1.max(t2);
|
||||
|
||||
for i in 1..3 {
|
||||
t1 = (b.min()[i] - r.origin[i]) * 1. / r.direction[i];
|
||||
t2 = (b.max()[i] - r.origin[i]) * 1. / r.direction[i];
|
||||
|
||||
tmin = tmin.max(t1.min(t2));
|
||||
tmax = tmax.min(t1.max(t2));
|
||||
}
|
||||
|
||||
return tmax > tmin.max(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn surrounding_box(box0: &AABB, box1: &AABB) -> AABB {
|
||||
let min = Vec3::new(
|
||||
box0.min.x.min(box1.min.x),
|
||||
box0.min.y.min(box1.min.y),
|
||||
box0.min.z.min(box1.min.z),
|
||||
box0.min().x.min(box1.min().x),
|
||||
box0.min().y.min(box1.min().y),
|
||||
box0.min().z.min(box1.min().z),
|
||||
);
|
||||
let max = Vec3::new(
|
||||
box0.max.x.max(box1.max.x),
|
||||
box0.max.y.max(box1.max.y),
|
||||
box0.max.z.max(box1.max.z),
|
||||
box0.max().x.max(box1.max().x),
|
||||
box0.max().y.max(box1.max().y),
|
||||
box0.max().z.max(box1.max().z),
|
||||
);
|
||||
AABB::new(min, max)
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate rand;
|
||||
extern crate rtiow;
|
||||
extern crate stderrlog;
|
||||
#[macro_use]
|
||||
extern crate structopt;
|
||||
|
||||
@ -114,7 +117,9 @@ fn build_scene_book(bvh: bool, opt: &Opt) -> Scene {
|
||||
);
|
||||
let world: Box<Hit>;
|
||||
if bvh {
|
||||
world = Box::new(BVH::new(random_scene(), time_min, time_max));
|
||||
let b = BVH::new(random_scene(), time_min, time_max);
|
||||
trace!(target: "bvh", "World {}", b);
|
||||
world = Box::new(b);
|
||||
} else {
|
||||
world = Box::new(HitableList::new(random_scene()));
|
||||
}
|
||||
@ -145,7 +150,7 @@ fn build_scene_bvh(opt: &Opt) -> Scene {
|
||||
time_min,
|
||||
time_max,
|
||||
);
|
||||
let world: Box<Hit> = Box::new(BVH::new(
|
||||
let b = BVH::new(
|
||||
vec![
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(0., 0., -1.),
|
||||
@ -173,7 +178,9 @@ fn build_scene_bvh(opt: &Opt) -> Scene {
|
||||
],
|
||||
time_min,
|
||||
time_max,
|
||||
));
|
||||
);
|
||||
trace!(target: "bvh", "World {}", b);
|
||||
let world: Box<Hit> = Box::new(b);
|
||||
Scene {
|
||||
camera,
|
||||
world,
|
||||
@ -332,6 +339,11 @@ pub struct Opt {
|
||||
}
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
stderrlog::new()
|
||||
.verbosity(3)
|
||||
.timestamp(stderrlog::Timestamp::Millisecond)
|
||||
.init()
|
||||
.unwrap();
|
||||
let start = Instant::now();
|
||||
let opt = Opt::from_args();
|
||||
let scene = match opt.model {
|
||||
@ -343,7 +355,7 @@ fn main() -> Result<(), std::io::Error> {
|
||||
};
|
||||
let res = render(scene, &opt.output);
|
||||
let runtime = start.elapsed();
|
||||
eprintln!(
|
||||
info!(
|
||||
"Render time {}.{} seconds",
|
||||
runtime.as_secs(),
|
||||
runtime.subsec_millis()
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use std;
|
||||
use std::fmt;
|
||||
use std::time::Instant;
|
||||
|
||||
use rand;
|
||||
use rand::Rng;
|
||||
@ -43,7 +44,7 @@ impl fmt::Display for BVHNode {
|
||||
fn box_x_compare(ah: &Box<Hit>, bh: &Box<Hit>) -> std::cmp::Ordering {
|
||||
match (ah.bounding_box(0., 0.), bh.bounding_box(0., 0.)) {
|
||||
(Some(box_left), Some(box_right)) => {
|
||||
return box_left.min.x.partial_cmp(&box_right.min.x).unwrap();
|
||||
return box_left.min().x.partial_cmp(&box_right.min().x).unwrap();
|
||||
}
|
||||
_ => panic!("hit missing bounding box"),
|
||||
}
|
||||
@ -52,7 +53,7 @@ fn box_x_compare(ah: &Box<Hit>, bh: &Box<Hit>) -> std::cmp::Ordering {
|
||||
fn box_y_compare(ah: &Box<Hit>, bh: &Box<Hit>) -> std::cmp::Ordering {
|
||||
match (ah.bounding_box(0., 0.), bh.bounding_box(0., 0.)) {
|
||||
(Some(box_left), Some(box_right)) => {
|
||||
return box_left.min.y.partial_cmp(&box_right.min.y).unwrap();
|
||||
return box_left.min().y.partial_cmp(&box_right.min().y).unwrap();
|
||||
}
|
||||
_ => panic!("hit missing bounding box"),
|
||||
}
|
||||
@ -61,7 +62,7 @@ fn box_y_compare(ah: &Box<Hit>, bh: &Box<Hit>) -> std::cmp::Ordering {
|
||||
fn box_z_compare(ah: &Box<Hit>, bh: &Box<Hit>) -> std::cmp::Ordering {
|
||||
match (ah.bounding_box(0., 0.), bh.bounding_box(0., 0.)) {
|
||||
(Some(box_left), Some(box_right)) => {
|
||||
return box_left.min.z.partial_cmp(&box_right.min.z).unwrap();
|
||||
return box_left.min().z.partial_cmp(&box_right.min().z).unwrap();
|
||||
}
|
||||
_ => panic!("hit missing bounding box"),
|
||||
}
|
||||
@ -115,6 +116,13 @@ impl BVHNode {
|
||||
(None, None) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn volume(&self) -> f32 {
|
||||
let bbox = self.bounding_box(0., 0.).unwrap();
|
||||
(bbox.min().x - bbox.max().x).abs()
|
||||
* (bbox.min().y - bbox.max().y).abs()
|
||||
* (bbox.min().z - bbox.max().z).abs()
|
||||
}
|
||||
}
|
||||
|
||||
impl Hit for BVHNode {
|
||||
@ -152,15 +160,25 @@ pub struct BVH {
|
||||
|
||||
impl BVH {
|
||||
pub fn new(l: Vec<Box<Hit>>, t_min: f32, t_max: f32) -> BVH {
|
||||
BVH {
|
||||
let count = l.len();
|
||||
let start = Instant::now();
|
||||
let bvh = BVH {
|
||||
root: BVHNode::new(l, t_min, t_max),
|
||||
}
|
||||
};
|
||||
let runtime = start.elapsed();
|
||||
info!(
|
||||
"BVH build time {}.{} seconds for {} hitables",
|
||||
runtime.as_secs(),
|
||||
runtime.subsec_millis(),
|
||||
count
|
||||
);
|
||||
bvh
|
||||
}
|
||||
}
|
||||
|
||||
fn print_tree(f: &mut fmt::Formatter, depth: usize, bvhn: &BVHNode) -> fmt::Result {
|
||||
// TODO(wathiede): recurse and indent
|
||||
write!(f, "{}{}\n", " ".repeat(depth * 2), bvhn)?;
|
||||
let vol = bvhn.volume();
|
||||
write!(f, "{:.*}{}{}\n", 2, vol, " ".repeat(depth * 2), bvhn)?;
|
||||
if let BVHNode::Branch { left, right, .. } = bvhn {
|
||||
print_tree(f, depth + 1, left)?;
|
||||
print_tree(f, depth + 1, right)?;
|
||||
|
||||
@ -13,6 +13,8 @@ pub mod vec3;
|
||||
|
||||
extern crate crossbeam_channel;
|
||||
extern crate image;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate num_cpus;
|
||||
extern crate rand;
|
||||
extern crate rayon;
|
||||
|
||||
@ -5,14 +5,23 @@ pub struct Ray {
|
||||
pub origin: Vec3,
|
||||
pub direction: Vec3,
|
||||
pub time: f32,
|
||||
pub inv_direction: Vec3,
|
||||
pub sign: [usize; 3],
|
||||
}
|
||||
|
||||
impl Ray {
|
||||
pub fn new(origin: Vec3, direction: Vec3, time: f32) -> Ray {
|
||||
let inv = 1. / direction;
|
||||
Ray {
|
||||
origin,
|
||||
direction,
|
||||
time,
|
||||
inv_direction: inv,
|
||||
sign: [
|
||||
(inv.x < 0.) as usize,
|
||||
(inv.y < 0.) as usize,
|
||||
(inv.z < 0.) as usize,
|
||||
],
|
||||
}
|
||||
}
|
||||
pub fn point_at_parameter(self, t: f32) -> Vec3 {
|
||||
|
||||
@ -47,6 +47,7 @@ fn trace_pixel(x: usize, y: usize, scene: &Scene) -> Vec3 {
|
||||
}
|
||||
|
||||
fn render_worker(
|
||||
tid: usize,
|
||||
scene: &Scene,
|
||||
input_chan: channel::Receiver<usize>,
|
||||
output_chan: channel::Sender<(usize, Vec<Vec3>)>,
|
||||
@ -61,7 +62,7 @@ fn render_worker(
|
||||
}
|
||||
output_chan.send((subsample, pixel_data));
|
||||
}
|
||||
eprintln!("Shutting down worker");
|
||||
info!("Shutting down worker {}", tid);
|
||||
}
|
||||
|
||||
pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::io::Error> {
|
||||
@ -69,12 +70,12 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
|
||||
let (pixel_data_tx, pixel_data_rx) = channel::unbounded();
|
||||
|
||||
let scene = sync::Arc::new(scene);
|
||||
for _ in 0..num_cpus::get() {
|
||||
for i in 0..num_cpus::get() {
|
||||
let s = sync::Arc::clone(&scene);
|
||||
let seq_rx = seq_rx.clone();
|
||||
let pixel_data_tx = pixel_data_tx.clone();
|
||||
thread::spawn(move || {
|
||||
render_worker(&s, seq_rx, pixel_data_tx);
|
||||
render_worker(i, &s, seq_rx, pixel_data_tx);
|
||||
});
|
||||
}
|
||||
drop(seq_rx);
|
||||
@ -113,12 +114,12 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
|
||||
);
|
||||
});
|
||||
let path = output_dir.join(format!("iteration{:05}.png", acc_count));
|
||||
eprintln!("saving {}", path.to_string_lossy());
|
||||
trace!(target: "renderer", "Saving {}", path.to_string_lossy());
|
||||
img.save(&path)
|
||||
.unwrap_or_else(|_| panic!("Failed save {}", path.to_string_lossy()));
|
||||
}
|
||||
let path = output_dir.join("final.png");
|
||||
// Write the contents of this image to the Writer in PNG format.
|
||||
eprintln!("Saving {}", path.to_string_lossy());
|
||||
trace!(target: "renderer", "Saving {}", path.to_string_lossy());
|
||||
img.save(path)
|
||||
}
|
||||
|
||||
@ -91,6 +91,18 @@ impl Add for Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<Vec3> for f32 {
|
||||
type Output = Vec3;
|
||||
|
||||
fn div(self, r: Vec3) -> Vec3 {
|
||||
Vec3 {
|
||||
x: self / r.x,
|
||||
y: self / r.y,
|
||||
z: self / r.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<f32> for Vec3 {
|
||||
type Output = Vec3;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user