ft: 9: diffuse materials
This commit is contained in:
52
src/vec3.rs
52
src/vec3.rs
@@ -4,6 +4,8 @@ use std::{
|
||||
ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
|
||||
};
|
||||
|
||||
use rand::RngExt;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Vec3 {
|
||||
r: f32,
|
||||
@@ -26,6 +28,33 @@ impl Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random() -> Vec3 {
|
||||
let mut rng = rand::rng();
|
||||
Vec3 {
|
||||
r: rng.random_range(-1.0..1.),
|
||||
g: rng.random_range(-1.0..1.),
|
||||
b: rng.random_range(-1.0..1.),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random_unit() -> Vec3 {
|
||||
loop {
|
||||
let v = Vec3::random();
|
||||
if v.length_squared() <= 1. {
|
||||
return v / v.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random_unit_hemisphere(n: &Vec3) -> Vec3 {
|
||||
let v = Vec3::random_unit();
|
||||
if n.dot(&v) > 0.0 {
|
||||
v
|
||||
} else {
|
||||
-v
|
||||
}
|
||||
}
|
||||
|
||||
pub fn x(&self) -> &f32 {
|
||||
&self.r
|
||||
}
|
||||
@@ -67,9 +96,26 @@ impl Vec3 {
|
||||
}
|
||||
|
||||
pub fn output(self) -> image::Rgb<u8> {
|
||||
let ir = (255.599 * self.r.clamp(0., 1.)) as u8;
|
||||
let ig = (255.599 * self.g.clamp(0., 1.)) as u8;
|
||||
let ib = (255.599 * self.b.clamp(0., 1.)) as u8;
|
||||
// gamma correction
|
||||
let r = if self.r > 0. {
|
||||
sqrt(self.r).clamp(0., 1.)
|
||||
} else {
|
||||
0.
|
||||
};
|
||||
let g = if self.g > 0. {
|
||||
sqrt(self.g).clamp(0., 1.)
|
||||
} else {
|
||||
0.
|
||||
};
|
||||
let b = if self.b > 0. {
|
||||
sqrt(self.b).clamp(0.1, 1.)
|
||||
} else {
|
||||
0.
|
||||
};
|
||||
|
||||
let ir = (255.599 * r) as u8;
|
||||
let ig = (255.599 * g) as u8;
|
||||
let ib = (255.599 * b) as u8;
|
||||
|
||||
image::Rgb([ir, ig, ib])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user