Start of surface normal support.
This commit is contained in:
parent
e8d05eeaee
commit
0c5c6381fc
@ -17,6 +17,9 @@ pub fn render(scene: &Scene) -> image::DynamicImage {
|
||||
let ray = rendering::Ray::create_prime(x, y, scene);
|
||||
|
||||
if let Some(intersection) = scene.trace(&ray) {
|
||||
let hit_point = ray.origin + (&ray.direction * intersection.distance);
|
||||
let surface_normal = intersection.object.surface_normal(&hit_point);
|
||||
let direction_to_light = -scene.light.direction;
|
||||
let c = &intersection.object.color();
|
||||
image.put_pixel(x, y, image::Rgba(c.to_rgba()))
|
||||
} else {
|
||||
@ -34,6 +37,7 @@ fn test_can_render_scene() {
|
||||
use rendering::Plane;
|
||||
use rendering::Sphere;
|
||||
use scene::Color;
|
||||
use scene::Light;
|
||||
use vector::Vector3;
|
||||
|
||||
let scene = Scene {
|
||||
@ -128,6 +132,19 @@ fn test_can_render_scene() {
|
||||
},
|
||||
}),
|
||||
],
|
||||
light: Light {
|
||||
direction: Vector3 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: -1.0,
|
||||
},
|
||||
color: Color {
|
||||
red: 1.0,
|
||||
green: 1.0,
|
||||
blue: 1.0,
|
||||
},
|
||||
intensity: 0.0,
|
||||
},
|
||||
};
|
||||
|
||||
let img: image::DynamicImage = render(&scene);
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
use std::ops::Add;
|
||||
use std::ops::Sub;
|
||||
|
||||
use vector::Vector3;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Point {
|
||||
pub x: f32,
|
||||
@ -17,6 +20,18 @@ impl Point {
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Vector3> for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn add(self, other: Vector3) -> Point {
|
||||
Point {
|
||||
x: self.x + other.x,
|
||||
y: self.y + other.y,
|
||||
z: self.z + other.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Point {
|
||||
type Output = Point;
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ use vector::Vector3;
|
||||
|
||||
pub trait Intersectable {
|
||||
fn intersect(&self, ray: &Ray) -> Option<f32>;
|
||||
fn surface_normal(&self, hit_point: &Point) -> Vector3;
|
||||
}
|
||||
|
||||
pub struct Sphere {
|
||||
@ -37,6 +38,10 @@ impl Intersectable for Sphere {
|
||||
let distance = if t0 < t1 { t0 } else { t1 };
|
||||
Some(distance)
|
||||
}
|
||||
|
||||
fn surface_normal(&self, hit_point: &Point) -> Vector3 {
|
||||
Vector3::from(*hit_point - self.center).normalize()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Plane {
|
||||
@ -58,6 +63,10 @@ impl Intersectable for Plane {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn surface_normal(&self, _: &Point) -> Vector3 {
|
||||
-self.normal
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Element {
|
||||
@ -72,6 +81,12 @@ impl Element {
|
||||
Element::Plane(ref p) => &p.color,
|
||||
}
|
||||
}
|
||||
pub fn surface_normal(&self, hit_point: &Point) -> Vector3 {
|
||||
match *self {
|
||||
Element::Sphere(ref s) => s.surface_normal(hit_point),
|
||||
Element::Plane(ref p) => p.surface_normal(hit_point),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Intersectable for Element {
|
||||
@ -81,6 +96,13 @@ impl Intersectable for Element {
|
||||
Element::Plane(ref p) => p.intersect(ray),
|
||||
}
|
||||
}
|
||||
|
||||
fn surface_normal(&self, hit_point: &Point) -> Vector3 {
|
||||
match *self {
|
||||
Element::Sphere(ref s) => s.surface_normal(hit_point),
|
||||
Element::Plane(ref p) => p.surface_normal(hit_point),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Ray {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use rendering::Element;
|
||||
use rendering::Intersectable;
|
||||
use rendering::Ray;
|
||||
use vector::Vector3;
|
||||
|
||||
pub struct Intersection<'a> {
|
||||
pub distance: f32,
|
||||
@ -31,11 +32,18 @@ impl Color {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Light {
|
||||
pub direction: Vector3,
|
||||
pub color: Color,
|
||||
pub intensity: f32,
|
||||
}
|
||||
|
||||
pub struct Scene {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub fov: f32,
|
||||
pub elements: Vec<Element>,
|
||||
pub light: Light,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
use point::Point;
|
||||
use std::ops::Add;
|
||||
use std::ops::Div;
|
||||
use std::ops::Mul;
|
||||
use std::ops::Neg;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Vector3 {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
@ -37,6 +41,42 @@ impl<'a> Div<f32> for &'a Vector3 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Mul<f32> for &'a Vector3 {
|
||||
type Output = Vector3;
|
||||
|
||||
fn mul(self, rhs: f32) -> Vector3 {
|
||||
Vector3 {
|
||||
x: self.x * rhs,
|
||||
y: self.y * rhs,
|
||||
z: self.z * rhs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Vector3 {
|
||||
type Output = Vector3;
|
||||
|
||||
fn add(self, rhs: Vector3) -> Vector3 {
|
||||
Vector3 {
|
||||
x: rhs.x + self.x,
|
||||
y: rhs.y + self.y,
|
||||
z: rhs.z + self.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for Vector3 {
|
||||
type Output = Vector3;
|
||||
|
||||
fn neg(self) -> Vector3 {
|
||||
Vector3 {
|
||||
x: -self.x,
|
||||
y: -self.y,
|
||||
z: -self.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Point> for Vector3 {
|
||||
fn from(p: Point) -> Self {
|
||||
Vector3 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user