use std::sync::Arc;
use nanorand::tls::TlsWyRand;
pub use pbr_material::PbrMaterial;
use crate::color::{Color, Texture};
use crate::math::{Hit, Point2, Ray, Vec3};
mod pbr_material;
pub trait Material: Send + Sync {
fn next_ray(&self, ray: Ray, hit: Hit, rng: &mut TlsWyRand) -> Option<Ray>;
fn get_color(&self, uv: Point2) -> (Color, Color);
}
pub fn compute_color(
color: Color,
texture: &Option<Arc<dyn Texture>>,
strength: f64,
uv: Point2,
) -> Color {
strength as f32
* color
* match texture {
None => Color::WHITE,
Some(t) => t.get_pixel(uv.x, uv.y),
}
}
pub fn compute_normal(
normal: Vec3,
tangent: Vec3,
bitangent: Vec3,
normal_texture: &Option<Arc<dyn Texture>>,
uv: Point2,
) -> Vec3 {
match normal_texture {
None => normal,
Some(texture) => {
let texture_normal = Vec3::from(texture.get_pixel(uv.x, uv.y)) * 2.0 - Vec3::splat(1.0);
(texture_normal.x * tangent + texture_normal.y * bitangent + texture_normal.z * normal)
.normalize()
}
}
}