64 lines
2.0 KiB
Rust
64 lines
2.0 KiB
Rust
use crate::types_defined::{Ray, Vec3};
|
|
|
|
pub fn clamp(value: f32, low: f32, high: f32) -> f32 {
|
|
if value < low {
|
|
return low;
|
|
}
|
|
if value > high {
|
|
return high;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
pub fn near_zero(v: Vec3) -> bool {
|
|
const EPSILON: f32 = 1e-4;
|
|
|
|
v.x.abs() < EPSILON && v.y.abs() < EPSILON && v.z.abs() < EPSILON
|
|
}
|
|
|
|
pub fn reflect(v: Vec3, n: Vec3) -> Vec3 {
|
|
v - ((2.0 * v.dot(n)) * n)
|
|
}
|
|
|
|
// v, normal, 折射率
|
|
pub fn refract(uv: Vec3, n: Vec3, etai_over_etat: f32) -> Vec3 {
|
|
// auto cos_theta = std::fmin(dot(-uv, n), 1.0);
|
|
// vec3 r_out_perp = etai_over_etat * (uv + cos_theta*n);
|
|
// vec3 r_out_parallel = -std::sqrt(std::fabs(1.0 - r_out_perp.length_squared())) * n;
|
|
// return r_out_perp + r_out_parallel;
|
|
let cos_theta = (-uv.dot(n)).min(1.0);
|
|
let r_out_perp = etai_over_etat * (uv + cos_theta * n);
|
|
let r_out_parallel = -(f32::sqrt(f32::abs(1.0 - r_out_perp.length()))) * n;
|
|
r_out_perp + r_out_parallel
|
|
|
|
// let v_normalized = v;
|
|
// let n_normalized = n.normalize();
|
|
|
|
// let cos_theta = f32::min(-v_normalized.dot(n_normalized), 1.0);
|
|
// let sin_theta = (1.0 - cos_theta * cos_theta).sqrt();
|
|
// // 检查是否全内反射(无法折射)
|
|
// if etai_over_etat * sin_theta > 1.0 {
|
|
// return reflect(v_normalized, n)
|
|
// }
|
|
|
|
// let r_out_perp = etai_over_etat * (v_normalized + cos_theta * n_normalized);
|
|
// let discriminant = 1.0 - r_out_perp.length_squared();
|
|
// // if discriminant < 0.0 {
|
|
// // return -1.0 * v; // 全内反射,返回零向量(或改为反射)
|
|
// // }
|
|
// let r_out_parallel = -discriminant * n_normalized;
|
|
|
|
// r_out_perp + r_out_parallel
|
|
}
|
|
|
|
pub fn is_front_face(r: &Ray, outward_normal: Vec3) -> bool {
|
|
r.direction.dot(outward_normal) < 0.0
|
|
}
|
|
|
|
pub fn front_face_normal(r: &Ray, outward_normal: Vec3) -> Vec3 {
|
|
if is_front_face(r, outward_normal) {
|
|
outward_normal
|
|
} else {
|
|
-1. * outward_normal
|
|
}
|
|
} |