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);
|
let ray = rendering::Ray::create_prime(x, y, scene);
|
||||||
|
|
||||||
if let Some(intersection) = scene.trace(&ray) {
|
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();
|
let c = &intersection.object.color();
|
||||||
image.put_pixel(x, y, image::Rgba(c.to_rgba()))
|
image.put_pixel(x, y, image::Rgba(c.to_rgba()))
|
||||||
} else {
|
} else {
|
||||||
@ -34,6 +37,7 @@ fn test_can_render_scene() {
|
|||||||
use rendering::Plane;
|
use rendering::Plane;
|
||||||
use rendering::Sphere;
|
use rendering::Sphere;
|
||||||
use scene::Color;
|
use scene::Color;
|
||||||
|
use scene::Light;
|
||||||
use vector::Vector3;
|
use vector::Vector3;
|
||||||
|
|
||||||
let scene = Scene {
|
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);
|
let img: image::DynamicImage = render(&scene);
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
|
use std::ops::Add;
|
||||||
use std::ops::Sub;
|
use std::ops::Sub;
|
||||||
|
|
||||||
|
use vector::Vector3;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Point {
|
pub struct Point {
|
||||||
pub x: f32,
|
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 {
|
impl Sub for Point {
|
||||||
type Output = Point;
|
type Output = Point;
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use vector::Vector3;
|
|||||||
|
|
||||||
pub trait Intersectable {
|
pub trait Intersectable {
|
||||||
fn intersect(&self, ray: &Ray) -> Option<f32>;
|
fn intersect(&self, ray: &Ray) -> Option<f32>;
|
||||||
|
fn surface_normal(&self, hit_point: &Point) -> Vector3;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Sphere {
|
pub struct Sphere {
|
||||||
@ -37,6 +38,10 @@ impl Intersectable for Sphere {
|
|||||||
let distance = if t0 < t1 { t0 } else { t1 };
|
let distance = if t0 < t1 { t0 } else { t1 };
|
||||||
Some(distance)
|
Some(distance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn surface_normal(&self, hit_point: &Point) -> Vector3 {
|
||||||
|
Vector3::from(*hit_point - self.center).normalize()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Plane {
|
pub struct Plane {
|
||||||
@ -58,6 +63,10 @@ impl Intersectable for Plane {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn surface_normal(&self, _: &Point) -> Vector3 {
|
||||||
|
-self.normal
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Element {
|
pub enum Element {
|
||||||
@ -72,6 +81,12 @@ impl Element {
|
|||||||
Element::Plane(ref p) => &p.color,
|
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 {
|
impl Intersectable for Element {
|
||||||
@ -81,6 +96,13 @@ impl Intersectable for Element {
|
|||||||
Element::Plane(ref p) => p.intersect(ray),
|
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 {
|
pub struct Ray {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use rendering::Element;
|
use rendering::Element;
|
||||||
use rendering::Intersectable;
|
use rendering::Intersectable;
|
||||||
use rendering::Ray;
|
use rendering::Ray;
|
||||||
|
use vector::Vector3;
|
||||||
|
|
||||||
pub struct Intersection<'a> {
|
pub struct Intersection<'a> {
|
||||||
pub distance: f32,
|
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 struct Scene {
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
pub fov: f32,
|
pub fov: f32,
|
||||||
pub elements: Vec<Element>,
|
pub elements: Vec<Element>,
|
||||||
|
pub light: Light,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
use point::Point;
|
use point::Point;
|
||||||
|
use std::ops::Add;
|
||||||
use std::ops::Div;
|
use std::ops::Div;
|
||||||
|
use std::ops::Mul;
|
||||||
|
use std::ops::Neg;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Vector3 {
|
pub struct Vector3 {
|
||||||
pub x: f32,
|
pub x: f32,
|
||||||
pub y: 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 {
|
impl From<Point> for Vector3 {
|
||||||
fn from(p: Point) -> Self {
|
fn from(p: Point) -> Self {
|
||||||
Vector3 {
|
Vector3 {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user