wip: normal material

This commit is contained in:
2026-05-02 13:48:27 +02:00
parent c3d37f4758
commit ae73e626b9
10 changed files with 36 additions and 12 deletions

View File

@@ -4,9 +4,9 @@
"image_height": 1080,
"anti_alias_rate": 1,
"max_depth": 50,
"fov": 50.0,
"look_from": [15, 4, 10],
"look_at": [10.0, 2.0, 0.0],
"fov": 10.0,
"look_from": [0, 4, 15],
"look_at": [0.0, 0.0, 0.0],
"vup": [0.0, 1.0, 0.0],
"defocus_angle": 0,
"focus_dist": 15.68
@@ -14,20 +14,21 @@
"materials": [
{ "type": "lambertian", "albedo": [0.2, 0.2, 0.2], "prob": 0.8 },
{ "type": "lambertian", "albedo": [0.9, 0.9, 0.0], "prob": 1.0, "fuzz": 0.1 },
{ "type": "dielectric", "refraction_index": 1.5}
{ "type": "dielectric", "refraction_index": 1.5},
{ "type": "normal"}
],
"objects": [
{ "type": "sphere", "center": [0.0, 0.0, -1.2], "radius": 0.5, "material": { "type": "metal", "albedo": [0.7, 0.4, 0.2], "prob": 1.0, "fuzz": 0.1 }},
{ "type": "sphere", "center": [-1, 0, -1], "radius": 0.4, "material": 2},
{ "type": "sphere", "center": [-1, 0, -1], "radius": 0.4, "material": 3},
{ "type": "sphere", "center": [1, 0, -1], "radius": 0.5, "material": { "type": "metal", "albedo": [0.8, 0.6, 0.2], "prob": 1.0, "fuzz": 1.0 }},
{ "type": "triangle", "p1": [-4, 0, -4], "p2": [0, 0, -4], "p3": [-2, 2, -4], "material": 1},
{ "type": "triangle", "p1": [0, 0, -4], "p2": [4, 0, -4], "p3": [2, 2, -4], "material": 1},
{ "type": "triangle", "p1": [-2, 2, -4], "p2": [2, 2, -4], "p3": [0, 4, -4], "material": 1},
{ "type": "triangle", "p1": [-2, 2, -4], "p2": [2, 2, -4], "p3": [0, 4, -4], "material": 3},
{ "type": "quad", "p1": [-20, -1, -20], "p2": [20, -1, -20], "p3": [20, 20, -20], "p4": [-20, 20, -20], "material": 0},
{ "type": "quad", "p1": [-20, -1, 20], "p2": [-20, -1, -20], "p3": [-20, 20, -20], "p4": [-20, 20, 20], "material": 0},
{ "type": "quad", "p1": [-20, -1, 20], "p2": [20, -1, 20], "p3": [20, -1, -20], "p4": [-20, -1, -20], "material": 0},
{ "type": "quad", "p1": [20, -1, 20], "p2": [20, -1, -20], "p3": [20, 20, -20], "p4": [20, 20, 20], "material": 0},
{ "type": "cube", "p1": [8, 0, 2], "p2": [12, 0, 2], "p3": [12, 4, 2], "p4": [8, 4, 2], "p5": [8, 0, -2], "p6": [12, 0, -2], "p7": [12, 4, -2], "p8": [8, 4, -2], "material": 1}
{ "type": "cube", "p1": [8, 0, 2], "p2": [12, 0, 2], "p3": [12, 4, 2], "p4": [8, 4, 2], "p5": [8, 0, -2], "p6": [12, 0, -2], "p7": [12, 4, -2], "p8": [8, 4, -2], "material": 3}
]
}

View File

@@ -1,6 +1,6 @@
use std::{f32::consts::PI, sync::Arc};
use log::info;
use log::{info, warn};
use crate::{
objects::{hit::Hit, traits::Hittable},

View File

@@ -44,6 +44,7 @@ impl Hittable for Cube {
}
fn normal_at(&self, p: &Vec3) -> Vec3 {
// TODO: normal calc for cube
todo!()
}
}

View File

@@ -45,6 +45,7 @@ impl Hit {
self.front_face
}
// TODO: use front_face to discard back-hits for culling
pub fn hit_list(hittables: &Vec<Arc<dyn Hittable>>, r: &Ray) -> Option<Hit> {
let mut closest: Option<Hit> = None;
for hittable in hittables {

View File

@@ -1,3 +1,4 @@
pub mod dielectric;
pub mod lambertian;
pub mod normal;
pub mod traits;

View File

@@ -0,0 +1,17 @@
use serde::Deserialize;
use crate::{
objects::{hit::Hit, materials::traits::Material},
ray::Ray,
vec3::Vec3,
};
#[derive(Debug, Deserialize)]
pub struct Normal {}
impl Material for Normal {
fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Ray, Vec3)> {
let refl = ray.dir().reflect(hit.n()).get_unit();
Some((Ray::new(*hit.p(), refl), (hit.n() + 1.) / 2.))
}
}

View File

@@ -4,7 +4,7 @@ use crate::objects::traits::Hittable;
use crate::objects::triangle::Triangle;
use crate::ray::Ray;
use crate::{objects::materials::traits::Material, vec3::Vec3};
use log::info;
use log::{info, warn};
use std::fmt::Debug;
use std::sync::Arc;
@@ -19,6 +19,7 @@ pub struct Quad {
impl Quad {
pub fn new(p1: Vec3, p2: Vec3, p3: Vec3, p4: Vec3, material: Arc<dyn Material>) -> Self {
warn!("quad normal {}", (p2 - p1).cross(&(p4 - p1)).get_unit());
Self {
p1,
p2,

View File

@@ -1,5 +1,3 @@
use log::{info, warn};
use crate::objects::hit::Hit;
use crate::objects::traits::Hittable;
use crate::ray::Ray;
@@ -56,7 +54,7 @@ impl Triangle {
let diff = (a4 - a1 - a2 - a3).abs();
if diff < 0.001 {
return Some(Hit::new(t, p, normal, material, normal.dot(&-r.dir()) < 0.));
return Some(Hit::new(t, p, normal, material, normal.dot(&-r.dir()) > 0.));
} else {
return None;
}

View File

@@ -11,6 +11,7 @@ use crate::{
materials::{
dielectric::Dielectric,
lambertian::{Lambertian, Metal},
normal::Normal,
traits::Material,
},
quad::Quad,
@@ -207,6 +208,7 @@ enum MaterialDef {
Lambertian(Lambertian),
Metal(Metal),
Dielectric(Dielectric),
Normal(Normal),
}
impl MaterialDef {
@@ -215,6 +217,7 @@ impl MaterialDef {
MaterialDef::Lambertian(l) => Arc::new(l),
MaterialDef::Metal(m) => Arc::new(m),
MaterialDef::Dielectric(d) => Arc::new(d),
MaterialDef::Normal(n) => Arc::new(n),
}
}
}

View File

@@ -1,5 +1,6 @@
use core::f32::math::sqrt;
use is_close::default;
use log::warn;
use rand::RngExt;
use serde::{Deserialize, Serialize, Serializer};
use std::{