Skip to content

Commit

Permalink
refactor: simplify TextureTrait and MaterialTrait
Browse files Browse the repository at this point in the history
  • Loading branch information
Walther committed Dec 20, 2024
1 parent 80b09f9 commit fe0fd5d
Show file tree
Hide file tree
Showing 11 changed files with 25 additions and 57 deletions.
8 changes: 1 addition & 7 deletions clovers-cli/src/colorize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,7 @@ pub fn colorize(

// Get the emitted color from the surface that we just hit
// TODO: spectral light sources!
let emitted = hit_record.material.emit(
ray,
&hit_record,
hit_record.u,
hit_record.v,
hit_record.position,
);
let emitted = hit_record.material.emit(ray, &hit_record);
let tint: Xyz<E> = wavelength_into_xyz(ray.wavelength);
let emitted = emitted * tint;

Expand Down
11 changes: 2 additions & 9 deletions clovers/src/materials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use alloc::string::String;
use core::fmt::Debug;
use nalgebra::Unit;

use crate::{pdf::PDF, ray::Ray, Direction, Float, HitRecord, Position, Vec3};
use crate::{pdf::PDF, ray::Ray, Direction, Float, HitRecord, Vec3};
pub mod cone_light;
pub mod dielectric;
pub mod diffuse_light;
Expand Down Expand Up @@ -71,14 +71,7 @@ pub trait MaterialTrait: Debug {
}

/// Returns the emissivity of the material at the given position. Defaults to black as most materials don't emit - override when needed.
fn emit(
&self,
_ray: &Ray,
_hit_record: &HitRecord,
_u: Float,
_v: Float,
_position: Position,
) -> Xyz<E> {
fn emit(&self, _ray: &Ray, _hit_record: &HitRecord) -> Xyz<E> {
Xyz::new(0.0, 0.0, 0.0)
}
}
Expand Down
13 changes: 3 additions & 10 deletions clovers/src/materials/cone_light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::{MaterialTrait, ScatterRecord};
use crate::{
ray::Ray,
textures::{SolidColor, Texture, TextureTrait},
Float, HitRecord, Position,
Float, HitRecord,
};
use palette::{white_point::E, Xyz};
use rand::prelude::SmallRng;
Expand Down Expand Up @@ -41,14 +41,7 @@ impl MaterialTrait for ConeLight {

/// Emission function for [`ConeLight`]. If the given [`HitRecord`] has been hit on the `front_face`, emit a color based on the texture and surface coordinates. Otherwise, emit pure black.
#[must_use]
fn emit(
&self,
ray: &Ray,
hit_record: &HitRecord,
u: Float,
v: Float,
position: Position,
) -> Xyz<E> {
fn emit(&self, ray: &Ray, hit_record: &HitRecord) -> Xyz<E> {
// If we don't hit the front face, return black
if !hit_record.front_face {
return Xyz::new(0.0, 0.0, 0.0);
Expand All @@ -60,7 +53,7 @@ impl MaterialTrait for ConeLight {
/ (ray.direction.magnitude() * hit_record.normal.magnitude()))
.acos();

let emit = self.emit.color(u, v, position);
let emit = self.emit.color(hit_record);
if angle <= spread_radians {
emit
} else {
Expand Down
13 changes: 3 additions & 10 deletions clovers/src/materials/diffuse_light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::{MaterialTrait, ScatterRecord};
use crate::{
ray::Ray,
textures::{SolidColor, Texture, TextureTrait},
Float, HitRecord, Position,
HitRecord,
};
use palette::{white_point::E, Xyz};
use rand::prelude::SmallRng;
Expand Down Expand Up @@ -39,16 +39,9 @@ impl MaterialTrait for DiffuseLight {

/// Emission function for [`DiffuseLight`]. If the given [`HitRecord`] has been hit on the `front_face`, emit a color based on the texture and surface coordinates. Otherwise, emit pure black.
#[must_use]
fn emit(
&self,
_ray: &Ray,
hit_record: &HitRecord,
u: Float,
v: Float,
position: Position,
) -> Xyz<E> {
fn emit(&self, _ray: &Ray, hit_record: &HitRecord) -> Xyz<E> {
if hit_record.front_face {
self.emit.color(u, v, position)
self.emit.color(hit_record)
} else {
Xyz::new(0.0, 0.0, 0.0)
}
Expand Down
4 changes: 1 addition & 3 deletions clovers/src/materials/isotropic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ impl MaterialTrait for Isotropic {
hit_record: &HitRecord,
_rng: &mut SmallRng,
) -> Option<ScatterRecord> {
let albedo = self
.albedo
.color(hit_record.u, hit_record.v, hit_record.position);
let albedo = self.albedo.color(hit_record);

Some(ScatterRecord {
material_type: MaterialType::Diffuse,
Expand Down
4 changes: 1 addition & 3 deletions clovers/src/materials/lambertian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ impl MaterialTrait for Lambertian {
Some(ScatterRecord {
material_type: MaterialType::Diffuse,
specular_ray: None,
attenuation: self
.albedo
.color(hit_record.u, hit_record.v, hit_record.position),
attenuation: self.albedo.color(hit_record),
pdf_ptr: PDF::CosinePDF(CosinePDF::new(hit_record.normal)),
})
}
Expand Down
4 changes: 1 addition & 3 deletions clovers/src/materials/metal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ impl MaterialTrait for Metal {
time: ray.time,
wavelength: ray.wavelength,
}),
attenuation: self
.albedo
.color(hit_record.u, hit_record.v, hit_record.position),
attenuation: self.albedo.color(hit_record),
material_type: MaterialType::Specular,
pdf_ptr: PDF::ZeroPDF(ZeroPDF::new()),
})
Expand Down
4 changes: 2 additions & 2 deletions clovers/src/textures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub use solid_color::*;
pub use spatial_checker::*;
pub use surface_checker::*;

use crate::{Float, Position};
use crate::HitRecord;

#[enum_dispatch(TextureTrait)]
#[derive(Clone, Debug)]
Expand All @@ -30,7 +30,7 @@ pub enum Texture {
pub(crate) trait TextureTrait {
/// Evaluates the color of the texture at the given surface coordinates or spatial coordinate.
#[must_use]
fn color(&self, u: Float, v: Float, position: Position) -> Xyz<E>;
fn color(&self, hit_record: &HitRecord) -> Xyz<E>;
}

impl Default for Texture {
Expand Down
4 changes: 2 additions & 2 deletions clovers/src/textures/solid_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use palette::{convert::IntoColorUnclamped, white_point::E, Xyz};

use super::TextureTrait;
use crate::colorinit::ColorInit;
use crate::{Float, Position};
use crate::HitRecord;

/// Initialization structure for a solid color texture.
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -34,7 +34,7 @@ pub struct SolidColor {
impl TextureTrait for SolidColor {
/// Evaluates the color ignoring the given surface coordinates and spatial position - always returns the solid color.
#[must_use]
fn color(&self, _u: Float, _v: Float, _position: Position) -> Xyz<E> {
fn color(&self, _hit_record: &HitRecord) -> Xyz<E> {
self.color.into_color_unclamped()
}
}
Expand Down
7 changes: 4 additions & 3 deletions clovers/src/textures/spatial_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use palette::white_point::E;
use palette::Xyz;

use super::TextureTrait;
use crate::colorinit::ColorInit;
#[cfg(feature = "serde-derive")]
use crate::colorinit::TypedColorInit;
use crate::{Float, Position, PI};
use crate::{colorinit::ColorInit, HitRecord};
use crate::{Float, PI};

/// A standard checkered texture based on spatial 3D texturing.
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -82,7 +82,8 @@ impl SpatialChecker {
impl TextureTrait for SpatialChecker {
/// Evaluates the color at the given spatial position coordinate. Note that the `SpatialChecker` is spatial - surface coordinates are ignored.
#[must_use]
fn color(&self, _u: Float, _v: Float, position: Position) -> Xyz<E> {
fn color(&self, hit_record: &HitRecord) -> Xyz<E> {
let position = hit_record.position;
// TODO: convert ahead-of-time. NOTE: take into account serde-i-fication; not enough to do in `new` alone
let density = self.density * PI;
let sines = 1.0 // cosmetic 1 for readability of following lines :)
Expand Down
10 changes: 5 additions & 5 deletions clovers/src/textures/surface_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use palette::white_point::E;
use palette::Xyz;

use super::TextureTrait;
use crate::colorinit::ColorInit;
#[cfg(feature = "serde-derive")]
use crate::colorinit::TypedColorInit;
use crate::{Float, Position, PI};
use crate::{colorinit::ColorInit, HitRecord};
use crate::{Float, PI};

#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde-derive", derive(serde::Serialize, serde::Deserialize))]
Expand Down Expand Up @@ -80,12 +80,12 @@ impl SurfaceChecker {
impl TextureTrait for SurfaceChecker {
/// Evaluates the color at the given surface position coordinates. Note that `SurfaceChecker` is surface-based, and thus ignores the spatial position coordinate.
#[must_use]
fn color(&self, u: Float, v: Float, _position: Position) -> Xyz<E> {
fn color(&self, hit_record: &HitRecord) -> Xyz<E> {
// TODO: convert ahead-of-time. NOTE: take into account serde-i-fication; not enough to do in `new` alone
let density = self.density * PI;
let sines = 1.0 // cosmetic 1 for readability of following lines :)
* (density * u).sin()
* (density * v).sin();
* (density * hit_record.u).sin()
* (density * hit_record.v).sin();
if sines < 0.0 {
self.odd.into_color_unclamped()
} else {
Expand Down

0 comments on commit fe0fd5d

Please sign in to comment.