use crate::vec3::Vec3;
pub fn linear_to_gamma(linear: f64) -> f64 {
if linear > 0. {
return linear.sqrt();
}
return 0.;
}
pub fn gamma_to_linear(gamma: f64) -> f64 {
return gamma * gamma;
}
pub fn linear_color_to_gamma(color: Vec3) -> Vec3 {
Vec3 {
x: linear_to_gamma(color.x),
y: linear_to_gamma(color.y),
z: linear_to_gamma(color.z),
}
}
pub fn gamma_color_to_linear(color: Vec3) -> Vec3 {
Vec3 {
x: gamma_to_linear(color.x),
y: gamma_to_linear(color.y),
z: gamma_to_linear(color.z),
}
}
impl Color {
pub fn to_rgb_bytes(mut self) -> [u8; 3] {
self = gamma_color_to_linear(self);
let intensity = (0.0, 0.999);
let rbyte = (self.x.clamp(intensity.0, intensity.1) * 255.0) as u8;
let gbyte = (self.y.clamp(intensity.0, intensity.1) * 255.) as u8;
let bbyte = (self.z.clamp(intensity.0, intensity.1) * 255.) as u8;
[rbyte, gbyte, bbyte]
}
pub fn to_hex(&self) -> String {
let bytes = self.to_rgb_bytes();
format!("#{:02x}{:02x}{:02x}", bytes[0], bytes[1], bytes[2])
}
pub fn from_hex(hex: &str) -> Result<Vec3, std::num::ParseIntError> {
let hex = hex.trim_start_matches('#');
let r = u8::from_str_radix(&hex[0..2], 16)?;
let g = u8::from_str_radix(&hex[2..4], 16)?;
let b = u8::from_str_radix(&hex[4..6], 16)?;
let r = r as f64 / 255.0;
let g = g as f64 / 255.0;
let b = b as f64 / 255.0;
Ok(Vec3::new(r, g, b))
}
}
pub type Color = Vec3;