Implement diffuse lighting, and gamma correction.
This commit is contained in:
parent
4584eeb08f
commit
73ca5c8454
@ -10,9 +10,26 @@ use rtiow::ray::Ray;
|
||||
use rtiow::sphere::Sphere;
|
||||
use rtiow::vec3::Vec3;
|
||||
|
||||
fn random_in_unit_sphere() -> Vec3 {
|
||||
let mut rng = rand::thread_rng();
|
||||
let v = Vec3::new(1., 1., 1.);
|
||||
loop {
|
||||
let p = 2. * Vec3::new(
|
||||
rng.gen_range::<f32>(0., 1.),
|
||||
rng.gen_range::<f32>(0., 1.),
|
||||
rng.gen_range::<f32>(0., 1.),
|
||||
) - v;
|
||||
if p.squared_length() < 1. {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn color(r: Ray, world: &Hit) -> Vec3 {
|
||||
if let Some(rec) = world.hit(r, 0., std::f32::MAX) {
|
||||
return (rec.normal + 1.) * 0.5;
|
||||
if let Some(rec) = world.hit(r, 0.001, std::f32::MAX) {
|
||||
let target = rec.p + rec.normal + random_in_unit_sphere();
|
||||
// 50% grey material
|
||||
return 0.5 * color(Ray::new(rec.p, target - rec.p), world);
|
||||
}
|
||||
|
||||
// No hit, choose color from background.
|
||||
@ -43,6 +60,9 @@ fn main() -> Result<(), std::io::Error> {
|
||||
col = col + color(r, &world);
|
||||
}
|
||||
col = col / ns as f32;
|
||||
// Gamma correct, use gamma 2 correction, which is 1/gamma where gamma=2 which is 1/2
|
||||
// or sqrt.
|
||||
col = Vec3::new(col[0].sqrt(), col[1].sqrt(), col[2].sqrt());
|
||||
let ir = (255.99 * col[0]) as u32;
|
||||
let ig = (255.99 * col[1]) as u32;
|
||||
let ib = (255.99 * col[2]) as u32;
|
||||
|
||||
73
rtiow/src/bin/tracer_diffuse.rs
Normal file
73
rtiow/src/bin/tracer_diffuse.rs
Normal file
@ -0,0 +1,73 @@
|
||||
extern crate rand;
|
||||
extern crate rtiow;
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
use rtiow::camera::Camera;
|
||||
use rtiow::hitable::Hit;
|
||||
use rtiow::hitable_list::HitableList;
|
||||
use rtiow::ray::Ray;
|
||||
use rtiow::sphere::Sphere;
|
||||
use rtiow::vec3::Vec3;
|
||||
|
||||
fn random_in_unit_sphere() -> Vec3 {
|
||||
let mut rng = rand::thread_rng();
|
||||
let v = Vec3::new(1., 1., 1.);
|
||||
loop {
|
||||
let p = 2. * Vec3::new(
|
||||
rng.gen_range::<f32>(0., 1.),
|
||||
rng.gen_range::<f32>(0., 1.),
|
||||
rng.gen_range::<f32>(0., 1.),
|
||||
) - v;
|
||||
if p.squared_length() < 1. {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn color(r: Ray, world: &Hit) -> Vec3 {
|
||||
if let Some(rec) = world.hit(r, 0.001, std::f32::MAX) {
|
||||
let target = rec.p + rec.normal + random_in_unit_sphere();
|
||||
// 50% grey material
|
||||
return 0.5 * color(Ray::new(rec.p, target - rec.p), world);
|
||||
}
|
||||
|
||||
// No hit, choose color from background.
|
||||
let unit_direction = r.direction().unit_vector();
|
||||
let t = 0.5 * (unit_direction.y + 1.);
|
||||
Vec3::new(1., 1., 1.) * (1. - t) + Vec3::new(0.5, 0.7, 1.) * t
|
||||
}
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let nx = 200;
|
||||
let ny = 100;
|
||||
let ns = 100;
|
||||
println!("P3\n{} {}\n255", nx, ny);
|
||||
let objects = vec![
|
||||
Sphere::new(Vec3::new(0., 0., -1.), 0.5),
|
||||
Sphere::new(Vec3::new(0., -100.5, -1.), 100.),
|
||||
];
|
||||
let cam = Camera::new2x1();
|
||||
let world = HitableList::new(objects.iter().map(|o| o).collect());
|
||||
for j in (0..ny).rev() {
|
||||
for i in 0..nx {
|
||||
let mut col: Vec3 = Default::default();
|
||||
for _ in 0..ns {
|
||||
let u = (rng.gen_range::<f32>(0., 1.) + i as f32) / nx as f32;
|
||||
let v = (rng.gen_range::<f32>(0., 1.) + j as f32) / ny as f32;
|
||||
let r = cam.get_ray(u, v);
|
||||
col = col + color(r, &world);
|
||||
}
|
||||
col = col / ns as f32;
|
||||
// Gamma correct, use gamma 2 correction, which is 1/gamma where gamma=2 which is 1/2
|
||||
// or sqrt.
|
||||
col = Vec3::new(col[0].sqrt(), col[1].sqrt(), col[2].sqrt());
|
||||
let ir = (255.99 * col[0]) as u32;
|
||||
let ig = (255.99 * col[1]) as u32;
|
||||
let ib = (255.99 * col[2]) as u32;
|
||||
println!("{} {} {}", ir, ig, ib);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -131,6 +131,18 @@ impl Mul for Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Vec3> for f32 {
|
||||
type Output = Vec3;
|
||||
|
||||
fn mul(self, v: Vec3) -> Vec3 {
|
||||
Vec3 {
|
||||
x: v.x * self,
|
||||
y: v.y * self,
|
||||
z: v.z * self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<f32> for Vec3 {
|
||||
type Output = Vec3;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user