我在一个周末(生锈版)内完成射线追踪:https://misterdanb.github.io/raytracinginrust/
但是在加入电介质(玻璃)之后,我在玻璃球体上的折射是远远不够的。我已经做过故障排除,但是对于Rust版本和它所基于的C++版本,数学看起来都是正确的。预期的图像如下:

但是我的代码产生了这样的结果:

我的github链接是:https://github.com/jsjutzi/rust-ray-tracer
我为折射和玻璃材料分别添加的唯一代码是:
pub fn refract(self, n: Vec3, etai_over_etat: f64) -> Vec3 {
let cos_theta = (-1.0 * self).dot(n).min(1.0);
let r_out_perp = etai_over_etat * (self + cos_theta * n);
let r_out_parallel = -(1.0 - r_out_perp.length().powi(2)).abs().sqrt() * n;
r_out_perp + r_out_parallel
}和:
pub struct Dielectric {
ir: f64,
}
impl Dielectric {
pub fn new(index_of_refraction: f64) -> Dielectric {
Dielectric {
ir: index_of_refraction,
}
}
impl Scatter for Dielectric {
fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> Option<(Color, Ray)> {
let refraction_ratio = if rec.front_face {
1.0 / self.ir
} else {
self.ir
};
let unit_direction = r_in.direction();
let refracted = unit_direction.refract(rec.normal, refraction_ratio);
let scattered = Ray::new(rec.p, refracted);
Some((Color::new(1.0, 1.0, 1.0), scattered))
}我甚至不确定这个问题是否是折射本身,或者我是否在我的构建早期搞砸了其他的东西,它现在因为折射/玻璃表面被添加而浮出水面。我已经回溯了几个章节,没有发现任何明显的,我错过了早些时候,我也读了一些斯内尔定律,也没有看到一个明显的数学错误。
有人知道我哪里出了问题吗?
发布于 2022-10-06 00:13:29
因此,我很久以前就没有添加规范化的方法,错误地认为它是一种不推荐的方法或什么的,只是没有它,因为它从来没有影响任何东西。我有其他的排版和东西,我必须从教程工作,并认为这只是另一种。
将该方法添加到Vec3类型,如下所示:
pub fn normalized(self) -> Vec3 {
self / self.length()
}帮我解决了这个问题。现在很有魅力了。
https://stackoverflow.com/questions/73966449
复制相似问题