ft: normal mapping

This commit is contained in:
2026-05-02 13:58:46 +02:00
parent ae73e626b9
commit bf980a28ec
6 changed files with 14 additions and 12 deletions

View File

@@ -4,7 +4,7 @@
"image_height": 1080, "image_height": 1080,
"anti_alias_rate": 1, "anti_alias_rate": 1,
"max_depth": 50, "max_depth": 50,
"fov": 10.0, "fov": 90.0,
"look_from": [0, 4, 15], "look_from": [0, 4, 15],
"look_at": [0.0, 0.0, 0.0], "look_at": [0.0, 0.0, 0.0],
"vup": [0.0, 1.0, 0.0], "vup": [0.0, 1.0, 0.0],

View File

@@ -235,7 +235,10 @@ impl Camera {
let closest = Hit::hit_list(hittables, r); let closest = Hit::hit_list(hittables, r);
if let Some(hit) = closest { if let Some(hit) = closest {
if let Some((scattered, att)) = hit.mat().scatter(&hit, r) { if let Some((scattered, att)) = hit.mat().scatter(&hit, r) {
return att * self.ray_colour(hittables, &scattered, depth - 1); if let Some(ray) = scattered {
return att * self.ray_colour(hittables, &ray, depth - 1);
}
return att;
} }
return Colour::default(); return Colour::default();
} }

View File

@@ -30,7 +30,7 @@ impl Dielectric {
} }
impl Material for Dielectric { impl Material for Dielectric {
fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Ray, Colour)> { fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Option<Ray>, Colour)> {
let ri = if hit.front_face() { let ri = if hit.front_face() {
1. / self.refraction_index 1. / self.refraction_index
} else { } else {
@@ -51,6 +51,6 @@ impl Material for Dielectric {
} else { } else {
unit.refract(hit.n(), ri) unit.refract(hit.n(), ri)
}; };
Some((Ray::new(*hit.p(), dir), Colour::new(1., 1., 1.))) Some((Some(Ray::new(*hit.p(), dir)), Colour::new(1., 1., 1.)))
} }
} }

View File

@@ -30,7 +30,7 @@ impl Lambertian {
} }
impl Material for Lambertian { impl Material for Lambertian {
fn scatter(&self, hit: &Hit, _ray: &Ray) -> Option<(Ray, Colour)> { fn scatter(&self, hit: &Hit, _ray: &Ray) -> Option<(Option<Ray>, Colour)> {
let mut rng = rand::rng(); let mut rng = rand::rng();
if self.prob >= rng.random::<f32>() { if self.prob >= rng.random::<f32>() {
let mut dir = *hit.n() + Vec3::random_unit(); let mut dir = *hit.n() + Vec3::random_unit();
@@ -38,7 +38,7 @@ impl Material for Lambertian {
dir = *hit.n(); dir = *hit.n();
} }
let scattered = Ray::new(*hit.p(), dir); let scattered = Ray::new(*hit.p(), dir);
return Some((scattered, self.albedo)); return Some((Some(scattered), self.albedo));
} }
None None
} }
@@ -70,12 +70,12 @@ impl Metal {
} }
impl Material for Metal { impl Material for Metal {
fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Ray, Colour)> { fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Option<Ray>, Colour)> {
let mut rng = rand::rng(); let mut rng = rand::rng();
if self.prob >= rng.random::<f32>() { if self.prob >= rng.random::<f32>() {
let mut refl = ray.dir().reflect(hit.n()); let mut refl = ray.dir().reflect(hit.n());
refl = refl.get_unit() + self.fuzz * Vec3::random_unit(); refl = refl.get_unit() + self.fuzz * Vec3::random_unit();
return Some((Ray::new(*hit.p(), refl), self.albedo)); return Some((Some(Ray::new(*hit.p(), refl)), self.albedo));
} }
None None
} }

View File

@@ -10,8 +10,7 @@ use crate::{
pub struct Normal {} pub struct Normal {}
impl Material for Normal { impl Material for Normal {
fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Ray, Vec3)> { fn scatter(&self, hit: &Hit, _ray: &Ray) -> Option<(Option<Ray>, Vec3)> {
let refl = ray.dir().reflect(hit.n()).get_unit(); Some((None, (hit.n() + 1.) / 2.))
Some((Ray::new(*hit.p(), refl), (hit.n() + 1.) / 2.))
} }
} }

View File

@@ -2,5 +2,5 @@ use crate::{objects::hit::Hit, ray::Ray, vec3::Colour};
use std::fmt::Debug; use std::fmt::Debug;
pub trait Material: Debug + Send + Sync{ pub trait Material: Debug + Send + Sync{
fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Ray, Colour)>; fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Option<Ray>, Colour)>;
} }