我目前正在阅读《计算机图形学从头开始》这本书,在我的rust项目中,我不能很好地理解第一章中关于raytracer的示例。我使用image板条箱来渲染图片。我将坐标从渲染器(x和y,原点左上角)转换到我的视区(原点在中间,z在10)。
fn canvas_to_viewport(x: u32, y: u32, scene: &Scene) -> Point {
let x: f64 = x as f64 - (scene.width as f64 / 2.) ;
let y: f64 = y as f64 - (scene.width as f64 / 2.) ;
// x * viewport width / camera width
// y * viewport height / camera height
Point {
x: x * 1.,
y: y * 1.,
z: 10.
}
}然后,我通过使用辅助函数intersect_ray_sphere查找与球体最近的交点的trace_ray函数来获取像素的颜色。
fn trace_ray(camera: Point, viewport: Point, t_min: f64, _t_max: f64, spheres: &Vec<Sphere>) -> Color {
let mut closest_t = 1000.;
let mut closest_sphere_color = Color (255,255,255);
for sphere in spheres {
let (t1, t2) = intersect_ray_sphere(camera, viewport, &sphere);
if t1 > t_min && t1 < closest_t {
closest_t = t1;
closest_sphere_color = sphere.color;
};
if t2 > t_min && t2 < closest_t {
closest_t = t2;
closest_sphere_color = sphere.color;
};
}
closest_sphere_color
}
fn intersect_ray_sphere(o: Point, d: Point, sphere: &Sphere) -> (f64, f64) {
let r = sphere.radius;
let co = Point {
x: o.x - sphere.center.x,
y: o.y - sphere.center.y,
z: o.z - sphere.center.z
};
let a = dot_product(&d, &d);
let b = 2. * dot_product(&co, &d);
let c = dot_product(&co, &co) - r*r;
let discriminant = b*b - 4.*a*c;
if discriminant < 0. {
return (1000., 1000.);
};
let t1 = (-b + discriminant.sqrt()) / (2.*a);
let t2 = (-b - discriminant.sqrt()) / (2.*a);
return (t1, t2)
}距离中间较远的球体被扭曲,如您在这里看到的:

我已经尝试了几乎所有的参数,但似乎无法弄清楚。每一次的帮助都会非常感谢。
发布于 2021-10-06 22:28:14
我认为你错过了对t1 < t_max和t2 < t_max的检查,尽管我认为如果你的t_max是无限的,这并不重要。
此外,在出现负判别式的情况下,如果您愿意,实际上可以使用f64::INFINITY返回inf;使用1000很可能是您看到的扭曲效果的罪魁祸首。
https://stackoverflow.com/questions/69471181
复制相似问题