Add ConstantTexture and use it for Lambertian material.

This commit is contained in:
Bill Thiede 2018-09-22 19:53:27 -07:00
parent e1c430b9b2
commit a1d3cce4e4
10 changed files with 88 additions and 25 deletions

View File

@ -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.),

View File

@ -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;

View File

@ -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<Texture>,
}
impl Lambertian {
pub fn new(albedo: Vec3) -> Lambertian {
Lambertian { albedo }
pub fn new(texture: Box<Texture>) -> 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,
}

View File

@ -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<Box<Hit>> = Vec::new();
let len = 100;
let len = 1000;
for x in 0..len {
for z in 0..len {
let r = rng.gen_range::<f32>(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,
))))),
)));
}
}

View File

@ -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<Box<Hit>> {
let mut objects: Vec<Box<Hit>> = 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::<f32>(0., 1.);
@ -69,11 +72,11 @@ fn random_scene(background_color: Vec3) -> Vec<Box<Hit>> {
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<Hit>> {
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.),

View File

@ -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,

View File

@ -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 {

View File

@ -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<Hit> = if opt.use_accel {

View File

@ -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<Box<Hit>> = 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<Hit> = if opt.use_accel {

21
rtiow/src/texture.rs Normal file
View File

@ -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
}
}