Add Mandelbrot texture and test scene.
This commit is contained in:
parent
c8f5bf9e19
commit
27c1534273
@ -33,6 +33,7 @@ pub enum Model {
|
||||
CornellSmoke,
|
||||
PerlinDebug,
|
||||
Final,
|
||||
Mandelbrot,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
@ -47,6 +48,7 @@ impl Model {
|
||||
Model::CornellSmoke => scenes::cornell_smoke::new(&opt),
|
||||
Model::PerlinDebug => scenes::perlin_debug::new(&opt),
|
||||
Model::Final => scenes::final_scene::new(&opt),
|
||||
Model::Mandelbrot => scenes::mandelbrot::new(&opt),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -73,6 +75,7 @@ impl str::FromStr for Model {
|
||||
"cornell_smoke" => Ok(Model::CornellSmoke),
|
||||
"perlin_debug" => Ok(Model::PerlinDebug),
|
||||
"final" => Ok(Model::Final),
|
||||
"mandelbrot" => Ok(Model::Mandelbrot),
|
||||
_ => Err(ModelParseError(s.to_owned())),
|
||||
}
|
||||
}
|
||||
|
||||
156
rtiow/src/scenes/mandelbrot.rs
Normal file
156
rtiow/src/scenes/mandelbrot.rs
Normal file
@ -0,0 +1,156 @@
|
||||
use image;
|
||||
use rand;
|
||||
|
||||
use crate::camera::Camera;
|
||||
use crate::hitable::Hit;
|
||||
use crate::hitable_list::HitableList;
|
||||
use crate::kdtree::KDTree;
|
||||
use crate::material::DiffuseLight;
|
||||
use crate::material::Lambertian;
|
||||
use crate::noise::perlin::Perlin;
|
||||
use crate::noise::NoiseType;
|
||||
use crate::rect::XYRect;
|
||||
use crate::rect::XZRect;
|
||||
use crate::rect::YZRect;
|
||||
use crate::renderer::Opt;
|
||||
use crate::renderer::Scene;
|
||||
use crate::sphere::Sphere;
|
||||
use crate::texture::ConstantTexture;
|
||||
use crate::texture::ImageTexture;
|
||||
use crate::texture::Mandelbrot;
|
||||
use crate::texture::NoiseTexture;
|
||||
use crate::vec3::Vec3;
|
||||
|
||||
pub fn new(opt: &Opt) -> Scene {
|
||||
let lookfrom = Vec3::new(20., 20., 20.);
|
||||
let lookat = Vec3::new(0., 1., 0.);
|
||||
let dist_to_focus = 10.0;
|
||||
let aperture = 0.0;
|
||||
let time_min = 0.;
|
||||
let time_max = 1.;
|
||||
let camera = Camera::new(
|
||||
lookfrom,
|
||||
lookat,
|
||||
Vec3::new(0., 1., 0.),
|
||||
20.,
|
||||
opt.width as f32 / opt.height as f32,
|
||||
aperture,
|
||||
dist_to_focus,
|
||||
time_min,
|
||||
time_max,
|
||||
);
|
||||
let rng = &mut rand::thread_rng();
|
||||
let _ground_color = if opt.use_accel {
|
||||
Box::new(ConstantTexture::new(Vec3::new(1.0, 0.4, 0.4)))
|
||||
} else {
|
||||
Box::new(ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4)))
|
||||
};
|
||||
|
||||
let world_image_bytes = include_bytes!("../../images/world.jpg");
|
||||
let it = ImageTexture::new(image::load_from_memory(world_image_bytes).unwrap().to_rgb());
|
||||
let noise_source = Perlin::new(rng);
|
||||
let noise_type = NoiseType::Scale(10.);
|
||||
let objects: Vec<Box<Hit>> = vec![
|
||||
// Textured globe
|
||||
// Box::new(Sphere::new(Vec3::new(0., 2., 0.), 2.0, Lambertian::new(it))),
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(0., 2., 0.),
|
||||
2.0,
|
||||
DiffuseLight::new(Mandelbrot::new()),
|
||||
)),
|
||||
// Earth sized sphere
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(0., -1000., 0.),
|
||||
1000.,
|
||||
// Box::new(Lambertian::new(ground_color)),
|
||||
Lambertian::new(NoiseTexture::new(noise_source, noise_type)),
|
||||
)),
|
||||
Box::new(XZRect::new(
|
||||
-100.,
|
||||
100.,
|
||||
-100.,
|
||||
1000.,
|
||||
60.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(1., 1., 1.))),
|
||||
)),
|
||||
Box::new(YZRect::new(
|
||||
1.,
|
||||
3.,
|
||||
-1.,
|
||||
1.,
|
||||
4.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(4., 0., 4.))),
|
||||
)),
|
||||
Box::new(YZRect::new(
|
||||
1.,
|
||||
3.,
|
||||
-1.,
|
||||
1.,
|
||||
-4.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(0., 4., 0.))),
|
||||
)),
|
||||
Box::new(XZRect::new(
|
||||
-1.,
|
||||
1.,
|
||||
-1.,
|
||||
1.,
|
||||
6.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(4., 4., 0.))),
|
||||
)),
|
||||
Box::new(XYRect::new(
|
||||
-1.,
|
||||
1.,
|
||||
1.,
|
||||
3.,
|
||||
-4.,
|
||||
DiffuseLight::new(ConstantTexture::new(Vec3::new(0., 0., 4.))),
|
||||
)),
|
||||
Box::new(XYRect::new(
|
||||
-1.75,
|
||||
1.75,
|
||||
1.,
|
||||
3.,
|
||||
4.,
|
||||
DiffuseLight::new(Mandelbrot::new()),
|
||||
)),
|
||||
/*
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(0., 0., 0.),
|
||||
0.5,
|
||||
Box::new(Lambertian::new(ConstantTexture::new(Vec3::new(
|
||||
0.1, 0.2, 0.5,
|
||||
)))),
|
||||
)),
|
||||
// Shiny sphere
|
||||
Box::new(Sphere::new(
|
||||
Vec3::new(1., 0., 0.),
|
||||
0.5,
|
||||
Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
|
||||
)),
|
||||
Box::new(MovingSphere::new(
|
||||
Vec3::new(-1., 0., -0.25),
|
||||
Vec3::new(-1., 0., 0.25),
|
||||
0.5,
|
||||
0.,
|
||||
1.,
|
||||
Lambertian::new(ConstantTexture::new(Vec3::new(
|
||||
0.2, 0.8, 0.2,
|
||||
))),
|
||||
)),
|
||||
*/
|
||||
];
|
||||
let world: Box<Hit> = if opt.use_accel {
|
||||
Box::new(KDTree::new(objects, time_min, time_max))
|
||||
} else {
|
||||
Box::new(HitableList::new(objects))
|
||||
};
|
||||
Scene {
|
||||
camera,
|
||||
world,
|
||||
subsamples: opt.subsamples,
|
||||
width: opt.width,
|
||||
height: opt.height,
|
||||
global_illumination: false,
|
||||
env_map: None,
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ pub mod bvh;
|
||||
pub mod cornell_box;
|
||||
pub mod cornell_smoke;
|
||||
pub mod final_scene;
|
||||
pub mod mandelbrot;
|
||||
pub mod perlin_debug;
|
||||
pub mod test;
|
||||
pub mod tutorial;
|
||||
|
||||
78
rtiow/src/texture/mandelbrot.rs
Normal file
78
rtiow/src/texture/mandelbrot.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use rand;
|
||||
use rand::Rng;
|
||||
|
||||
use crate::texture::Texture;
|
||||
use crate::vec3::Vec3;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Mandelbrot {
|
||||
scale: f32,
|
||||
palette: Vec<Vec3>,
|
||||
}
|
||||
|
||||
// HSV values in [0..1]
|
||||
// returns [r, g, b] values from 0 to 255
|
||||
//From https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
|
||||
fn hsv_to_rgb(h: f32, s: f32, v: f32) -> Vec3 {
|
||||
let h_i = (h * 6.) as i32;
|
||||
let f = h * 6. - h_i as f32;
|
||||
let p = v * (1. - s);
|
||||
let q = v * (1. - f * s);
|
||||
let t = v * (1. - (1. - f) * s);
|
||||
match h_i {
|
||||
0 => Vec3::new(v, t, p),
|
||||
1 => Vec3::new(q, v, p),
|
||||
2 => Vec3::new(p, v, t),
|
||||
3 => Vec3::new(p, q, v),
|
||||
4 => Vec3::new(t, p, v),
|
||||
5 => Vec3::new(v, p, q),
|
||||
_ => panic!(format!("Unknown H value {}", h_i)),
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_palette(num: usize) -> Vec<Vec3> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut random = || rng.gen_range::<f32>(0.0, 0.1);
|
||||
// use golden ratio
|
||||
let golden_ratio_conjugate = 0.618033988749895;
|
||||
let mut h = random();
|
||||
(0..num)
|
||||
.map(|_| {
|
||||
h += golden_ratio_conjugate;
|
||||
h %= 1.0;
|
||||
hsv_to_rgb(h, 0.99, 0.99)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
impl Mandelbrot {
|
||||
pub fn new() -> Mandelbrot {
|
||||
Mandelbrot {
|
||||
scale: 2.0,
|
||||
palette: generate_palette(10),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Texture for Mandelbrot {
|
||||
fn value(&self, u: f32, v: f32, _p: Vec3) -> Vec3 {
|
||||
// scaled x coordinate of pixel (scaled to lie in the Mandelbrot X scale (-2.5, 1))
|
||||
let x0 = u * 3.5 - 2.5;
|
||||
// scaled y coordinate of pixel (scaled to lie in the Mandelbrot Y scale (-1, 1))
|
||||
let y0 = v * 2.0 - 1.0;
|
||||
let mut x = 0.0;
|
||||
let mut y = 0.0;
|
||||
let mut iteration = 0;
|
||||
let max_iteration = 1000;
|
||||
while (x * x + y * y) <= 2. * 2. && iteration < max_iteration {
|
||||
let xtemp = x * x - y * y + x0;
|
||||
y = 2. * x * y + y0;
|
||||
x = xtemp;
|
||||
iteration = iteration + 1;
|
||||
}
|
||||
if iteration == max_iteration {
|
||||
return Vec3::default();
|
||||
}
|
||||
self.palette[iteration % self.palette.len()]
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,14 @@
|
||||
mod checker;
|
||||
mod constant;
|
||||
mod image;
|
||||
mod noise;
|
||||
mod envmap;
|
||||
mod image;
|
||||
mod mandelbrot;
|
||||
mod noise;
|
||||
pub use crate::texture::checker::CheckerTexture;
|
||||
pub use crate::texture::constant::ConstantTexture;
|
||||
pub use crate::texture::envmap::EnvMap;
|
||||
pub use crate::texture::image::ImageTexture;
|
||||
pub use crate::texture::mandelbrot::Mandelbrot;
|
||||
pub use crate::texture::noise::NoiseTexture;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user