feat(plane): add a special checkerboard plane
This commit is contained in:
parent
c3d6d80fd7
commit
61b5437561
@ -1,6 +1,6 @@
|
|||||||
use lispers::raytracer::{
|
use lispers::raytracer::{
|
||||||
camera::Camera,
|
camera::Camera,
|
||||||
plane::Plane,
|
plane::Checkerboard,
|
||||||
scene::Scene,
|
scene::Scene,
|
||||||
sphere::Sphere,
|
sphere::Sphere,
|
||||||
types::{Color, Light, Material, Point3, Vector3},
|
types::{Color, Light, Material, Point3, Vector3},
|
||||||
@ -12,10 +12,10 @@ use std::time::Instant;
|
|||||||
fn main() {
|
fn main() {
|
||||||
let mut scene = Scene::new();
|
let mut scene = Scene::new();
|
||||||
|
|
||||||
scene.set_ambient(Color::new(0.2, 0.2, 0.2));
|
scene.set_ambient(Color::new(0.1, 0.1, 0.1));
|
||||||
|
|
||||||
scene.add_light(Light {
|
scene.add_light(Light {
|
||||||
position: Point3::new(4.0, 7.0, 10.0),
|
position: Point3::new(5.0, 7.0, 10.0),
|
||||||
color: Color::new(1.0, 1.0, 1.0),
|
color: Color::new(1.0, 1.0, 1.0),
|
||||||
});
|
});
|
||||||
scene.add_light(Light {
|
scene.add_light(Light {
|
||||||
@ -23,16 +23,25 @@ fn main() {
|
|||||||
color: Color::new(1.0, 1.0, 1.0),
|
color: Color::new(1.0, 1.0, 1.0),
|
||||||
});
|
});
|
||||||
|
|
||||||
scene.add_object(Arc::new(Plane::new(
|
scene.add_object(Arc::new(Checkerboard::new(
|
||||||
Point3::new(0.0, -1.0, 0.0),
|
Point3::new(0.0, -1.0, 0.0),
|
||||||
Vector3::new(0.0, 1.0, 0.0),
|
Vector3::new(0.0, 1.0, 0.0),
|
||||||
Material::new(
|
Material::new(
|
||||||
Color::new(0.5, 0.5, 0.5),
|
Color::new(1.0, 1.0, 1.0),
|
||||||
Color::new(0.5, 0.5, 0.5),
|
Color::new(1.0, 1.0, 1.0),
|
||||||
Color::new(0.0, 0.0, 0.0),
|
Color::new(0.0, 0.0, 0.0),
|
||||||
0.0,
|
0.0,
|
||||||
0.6,
|
0.5,
|
||||||
),
|
),
|
||||||
|
Material::new(
|
||||||
|
Color::new(0.0, 0.0, 0.0),
|
||||||
|
Color::new(0.0, 0.0, 0.0),
|
||||||
|
Color::new(0.0, 0.0, 0.0),
|
||||||
|
0.0,
|
||||||
|
0.5,
|
||||||
|
),
|
||||||
|
0.3,
|
||||||
|
Vector3::new(0.0, 0.0, 1.0),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
scene.add_object(Arc::new(Sphere::new(
|
scene.add_object(Arc::new(Sphere::new(
|
||||||
@ -76,14 +85,14 @@ fn main() {
|
|||||||
Point3::new(-1.0, -0.5, 0.0),
|
Point3::new(-1.0, -0.5, 0.0),
|
||||||
Vector3::new(0.0, 1.0, 0.0),
|
Vector3::new(0.0, 1.0, 0.0),
|
||||||
60.0,
|
60.0,
|
||||||
4 * 256,
|
4 * 512,
|
||||||
3 * 256,
|
3 * 512,
|
||||||
);
|
);
|
||||||
|
|
||||||
let fname = "demo-scene.png";
|
let fname = "demo-scene.png";
|
||||||
print!("Rendering demo scene...");
|
print!("Rendering demo scene...");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
match camera.render(&scene, 5, 3).save(fname) {
|
match camera.render(&scene, 10, 4).save(fname) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!(" finished ({}s) ", start.elapsed().as_secs_f32());
|
println!(" finished ({}s) ", start.elapsed().as_secs_f32());
|
||||||
println!("Image saved to {}", fname)
|
println!("Image saved to {}", fname)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use super::types::{Intersect, Material, Point3, Vector3};
|
use super::types::{Intersect, Material, Point3, Scalar, Vector3};
|
||||||
|
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
@ -12,6 +12,18 @@ pub struct Plane {
|
|||||||
material: Material,
|
material: Material,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A infinite checkerboard plane in 3D space.
|
||||||
|
pub struct Checkerboard {
|
||||||
|
/// The base plane containing the "white" material
|
||||||
|
base: Plane,
|
||||||
|
/// An alternative "black" material
|
||||||
|
material_alt: Material,
|
||||||
|
/// The scale of the checkerboard (side-length of each square)
|
||||||
|
scale: f64,
|
||||||
|
/// A projection matrix to map 3D points to the 2D plane space.
|
||||||
|
projection_matrix: na::Matrix2x3<Scalar>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Plane {
|
impl Plane {
|
||||||
/// Create a new plane.
|
/// Create a new plane.
|
||||||
/// - `position` is the position of the plane.
|
/// - `position` is the position of the plane.
|
||||||
@ -26,6 +38,32 @@ impl Plane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Checkerboard {
|
||||||
|
/// Create a new Checkerboard Plane.
|
||||||
|
/// - `position` is the position of the plane.
|
||||||
|
/// - `normal` is the normal of the plane.
|
||||||
|
/// - `material1` is the material of the "white" squares.
|
||||||
|
/// - `material2` is the material of the "black" squares.
|
||||||
|
/// - `scale` is the side-length of each square.
|
||||||
|
/// - `up` is "y" direction on the plane in 3D-Space.
|
||||||
|
pub fn new(
|
||||||
|
position: Point3,
|
||||||
|
normal: Vector3,
|
||||||
|
material1: Material,
|
||||||
|
material2: Material,
|
||||||
|
scale: f64,
|
||||||
|
up: Vector3,
|
||||||
|
) -> Checkerboard {
|
||||||
|
let right = up.cross(&normal).normalize();
|
||||||
|
Checkerboard {
|
||||||
|
base: Plane::new(position, normal, material1),
|
||||||
|
material_alt: material2,
|
||||||
|
scale,
|
||||||
|
projection_matrix: na::Matrix3x2::from_columns(&[right, up]).transpose(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Intersect for Plane {
|
impl Intersect for Plane {
|
||||||
fn intersect<'a>(
|
fn intersect<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
@ -49,3 +87,30 @@ impl Intersect for Plane {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Intersect for Checkerboard {
|
||||||
|
fn intersect<'a>(
|
||||||
|
&'a self,
|
||||||
|
ray: &super::types::Ray,
|
||||||
|
) -> Option<(
|
||||||
|
Point3,
|
||||||
|
Vector3,
|
||||||
|
super::types::Scalar,
|
||||||
|
&'a super::types::Material,
|
||||||
|
)> {
|
||||||
|
if let Some((point, normal, t, material)) = self.base.intersect(ray) {
|
||||||
|
let v3 = point - self.base.position;
|
||||||
|
let v2 = self.projection_matrix * v3;
|
||||||
|
|
||||||
|
if ((v2.x / self.scale).round() % 2.0 == 0.0)
|
||||||
|
== ((v2.y / self.scale).round() % 2.0 == 0.0)
|
||||||
|
{
|
||||||
|
Some((point, normal, t, material))
|
||||||
|
} else {
|
||||||
|
Some((point, normal, t, &self.material_alt))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user