diff --git a/rtiow/src/bvh.rs b/rtiow/src/bvh.rs index 13f6931..7102152 100644 --- a/rtiow/src/bvh.rs +++ b/rtiow/src/bvh.rs @@ -234,6 +234,7 @@ mod tests { use material::Lambertian; use material::Metal; use sphere::Sphere; + use texture::ConstantTexture; use vec3::Vec3; use super::*; @@ -245,7 +246,9 @@ mod tests { Box::new(Sphere::new( Vec3::new(0., 0., 0.), 0.5, - Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.1, 0.2, 0.5, + ))))), )), Box::new(Sphere::new( Vec3::new(1., 0., 0.), @@ -271,7 +274,9 @@ mod tests { Box::new(Sphere::new( Vec3::new(0., 0., 0.), 0.5, - Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.1, 0.2, 0.5, + ))))), )), Box::new(Sphere::new( Vec3::new(1., 0., 0.), diff --git a/rtiow/src/lib.rs b/rtiow/src/lib.rs index d35501b..bf3ea5d 100644 --- a/rtiow/src/lib.rs +++ b/rtiow/src/lib.rs @@ -11,6 +11,7 @@ pub mod ray; pub mod renderer; pub mod scenes; pub mod sphere; +pub mod texture; pub mod vec3; extern crate crossbeam_channel; diff --git a/rtiow/src/material.rs b/rtiow/src/material.rs index abb4891..f127241 100644 --- a/rtiow/src/material.rs +++ b/rtiow/src/material.rs @@ -3,6 +3,7 @@ use self::rand::Rng; use hitable::HitRecord; use ray::Ray; +use texture::Texture; use vec3::dot; use vec3::Vec3; @@ -33,12 +34,13 @@ pub trait Material: Send + Sync { } pub struct Lambertian { - albedo: Vec3, + // TODO(wathiede): implement texture sharing via references + albedo: Box, } impl Lambertian { - pub fn new(albedo: Vec3) -> Lambertian { - Lambertian { albedo } + pub fn new(texture: Box) -> Lambertian { + Lambertian { albedo: texture } } } @@ -46,7 +48,7 @@ impl Material for Lambertian { fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse { let target = rec.p + rec.normal + random_in_unit_sphere(); ScatterResponse { - attenutation: self.albedo, + attenutation: self.albedo.value(0., 0., rec.p), scattered: Ray::new(rec.p, target - rec.p, r_in.time), reflected: true, } diff --git a/rtiow/src/scenes/bench.rs b/rtiow/src/scenes/bench.rs index c7774a2..f09e9ff 100644 --- a/rtiow/src/scenes/bench.rs +++ b/rtiow/src/scenes/bench.rs @@ -10,6 +10,7 @@ use material::Lambertian; use renderer::Opt; use renderer::Scene; use sphere::Sphere; +use texture::ConstantTexture; use vec3::Vec3; pub fn new(opt: &Opt) -> Scene { @@ -32,7 +33,7 @@ pub fn new(opt: &Opt) -> Scene { ); let mut rng = rand::thread_rng(); let mut grid: Vec> = Vec::new(); - let len = 100; + let len = 1000; for x in 0..len { for z in 0..len { let r = rng.gen_range::(0., 1.); @@ -45,7 +46,9 @@ pub fn new(opt: &Opt) -> Scene { grid.push(Box::new(Sphere::new( Vec3::new(x_pos, 0., z_pos), 0.5, - Box::new(Lambertian::new(Vec3::new(r, g, b))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + r, g, b, + ))))), ))); } } diff --git a/rtiow/src/scenes/book.rs b/rtiow/src/scenes/book.rs index f61058e..6b5824b 100644 --- a/rtiow/src/scenes/book.rs +++ b/rtiow/src/scenes/book.rs @@ -11,6 +11,7 @@ use material::Metal; use renderer::Opt; use renderer::Scene; use sphere::Sphere; +use texture::ConstantTexture; use vec3::Vec3; pub fn new(opt: &Opt) -> Scene { @@ -55,7 +56,9 @@ fn random_scene(background_color: Vec3) -> Vec> { let mut objects: Vec> = vec![Box::new(Sphere::new( Vec3::new(0., -1000., 0.), 1000., - Box::new(Lambertian::new(background_color)), + Box::new(Lambertian::new(Box::new(ConstantTexture::new( + background_color, + )))), ))]; let mut random = || rng.gen_range::(0., 1.); @@ -69,11 +72,11 @@ fn random_scene(background_color: Vec3) -> Vec> { Box::new(Sphere::new( center, 0.2, - Box::new(Lambertian::new(Vec3::new( + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( random() * random(), random() * random(), random() * random(), - ))), + ))))), )) } else if choose_mat < 0.95 { // metal @@ -107,7 +110,9 @@ fn random_scene(background_color: Vec3) -> Vec> { Box::new(Sphere::new( Vec3::new(-4., 1., 0.), 1.0, - Box::new(Lambertian::new(Vec3::new(0.4, 0.2, 0.1))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.4, 0.2, 0.1, + ))))), )), Box::new(Sphere::new( Vec3::new(4., 1., 0.), diff --git a/rtiow/src/scenes/bvh.rs b/rtiow/src/scenes/bvh.rs index dd86cc6..fe14d44 100644 --- a/rtiow/src/scenes/bvh.rs +++ b/rtiow/src/scenes/bvh.rs @@ -7,6 +7,7 @@ use moving_sphere::MovingSphere; use renderer::Opt; use renderer::Scene; use sphere::Sphere; +use texture::ConstantTexture; use vec3::Vec3; pub fn new(opt: &Opt) -> Scene { @@ -32,12 +33,16 @@ pub fn new(opt: &Opt) -> Scene { Box::new(Sphere::new( Vec3::new(0., 0., -1.), 0.5, - Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.1, 0.2, 0.5, + ))))), )), Box::new(Sphere::new( Vec3::new(0., -100.5, -1.), 100., - Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.8))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.8, 0.8, 0.8, + ))))), )), Box::new(Sphere::new( Vec3::new(1., 0., -1.), @@ -50,7 +55,9 @@ pub fn new(opt: &Opt) -> Scene { 0.5, time_min, time_max, - Box::new(Lambertian::new(Vec3::new(0.2, 0.8, 0.2))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.2, 0.8, 0.2, + ))))), )), ], time_min, diff --git a/rtiow/src/scenes/cube.rs b/rtiow/src/scenes/cube.rs index d9d25ff..261e516 100644 --- a/rtiow/src/scenes/cube.rs +++ b/rtiow/src/scenes/cube.rs @@ -6,6 +6,7 @@ use material::Lambertian; use renderer::Opt; use renderer::Scene; use sphere::Sphere; +use texture::ConstantTexture; use vec3::Vec3; pub fn new(opt: &Opt) -> Scene { @@ -30,17 +31,23 @@ pub fn new(opt: &Opt) -> Scene { Box::new(Sphere::new( Vec3::new(0., 0., -1.), 0.5, - Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.1, 0.2, 0.5, + ))))), )), Box::new(Cube::new( Vec3::new(0., 0., 0.), 0.5, - Box::new(Lambertian::new(Vec3::new(0.5, 0.2, 0.1))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.5, 0.2, 0.1, + ))))), )), Box::new(Sphere::new( Vec3::new(0., -100.5, -1.), 100., - Box::new(Lambertian::new(Vec3::new(0.8, 0.8, 0.8))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.8, 0.8, 0.8, + ))))), )), ])); Scene { diff --git a/rtiow/src/scenes/test.rs b/rtiow/src/scenes/test.rs index 09e7db0..5bc886c 100644 --- a/rtiow/src/scenes/test.rs +++ b/rtiow/src/scenes/test.rs @@ -9,6 +9,7 @@ use material::Metal; use renderer::Opt; use renderer::Scene; use sphere::Sphere; +use texture::ConstantTexture; use vec3::Vec3; pub fn new(opt: &Opt) -> Scene { @@ -43,19 +44,25 @@ pub fn new(opt: &Opt) -> Scene { objects.push(Box::new(Sphere::new( center, 0.5, - Box::new(Lambertian::new(Vec3::new(1., 0., 0.))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 1., 0., 0., + ))))), ))); let center = Vec3::new(c1, 0., c2); objects.push(Box::new(Sphere::new( center, 0.5, - Box::new(Lambertian::new(Vec3::new(0., 1., 0.))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0., 1., 0., + ))))), ))); let center = Vec3::new(c1, c2, 0.); objects.push(Box::new(Sphere::new( center, 0.5, - Box::new(Lambertian::new(Vec3::new(0., 0., 1.))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0., 0., 1., + ))))), ))); } let world: Box = if opt.use_accel { diff --git a/rtiow/src/scenes/tutorial.rs b/rtiow/src/scenes/tutorial.rs index 3cf7cf1..2d8548b 100644 --- a/rtiow/src/scenes/tutorial.rs +++ b/rtiow/src/scenes/tutorial.rs @@ -8,6 +8,7 @@ use moving_sphere::MovingSphere; use renderer::Opt; use renderer::Scene; use sphere::Sphere; +use texture::ConstantTexture; use vec3::Vec3; pub fn new(opt: &Opt) -> Scene { @@ -29,9 +30,9 @@ pub fn new(opt: &Opt) -> Scene { time_max, ); let ground_color = if opt.use_accel { - Vec3::new(1.0, 0.4, 0.4) + Box::new(ConstantTexture::new(Vec3::new(1.0, 0.4, 0.4))) } else { - Vec3::new(0.4, 1.0, 0.4) + Box::new(ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4))) }; let objects: Vec> = vec![ @@ -39,7 +40,9 @@ pub fn new(opt: &Opt) -> Scene { Box::new(Sphere::new( Vec3::new(0., 0., -1.), 0.5, - Box::new(Lambertian::new(Vec3::new(0.1, 0.2, 0.5))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.1, 0.2, 0.5, + ))))), )), Box::new(Sphere::new( Vec3::new(0., -100.5, -1.), @@ -57,7 +60,9 @@ pub fn new(opt: &Opt) -> Scene { 0.5, 0., 1., - Box::new(Lambertian::new(Vec3::new(0.2, 0.8, 0.2))), + Box::new(Lambertian::new(Box::new(ConstantTexture::new(Vec3::new( + 0.2, 0.8, 0.2, + ))))), )), ]; let world: Box = if opt.use_accel { diff --git a/rtiow/src/texture.rs b/rtiow/src/texture.rs new file mode 100644 index 0000000..bfab371 --- /dev/null +++ b/rtiow/src/texture.rs @@ -0,0 +1,21 @@ +use vec3::Vec3; + +pub trait Texture: Send + Sync { + fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3; +} + +pub struct ConstantTexture { + color: Vec3, +} + +impl ConstantTexture { + pub fn new(color: Vec3) -> ConstantTexture { + ConstantTexture { color } + } +} + +impl Texture for ConstantTexture { + fn value(&self, _u: f32, _v: f32, _p: Vec3) -> Vec3 { + self.color + } +}