0

我在光线追踪器上实现了 phong 着色。不幸的是,我在运行它时收到了分段错误。可能的原因与“specular_color”Vec3f 变量有关(其中是由三个浮点数组成的对象)。当我打印它的值时,我收到:

specular_color: inf inf inf

找出原因并不复杂:

它是这样计算的:

specular_color += light_intensity * std::pow (reflected*camera_dir,mat.ns);

其中 mat.ns 是镜面反射指数,它展示了预期值。

reflect*camera_dir 是原因,因为它总是以一个很大的值结束。在我的四个测试用例中,有三个是一个五位数的值。另一个是六位数的值(接近七)。因此,任何不接近 1 的指数的五位或六位数值都可能会溢出浮点变量。

现在的问题是为什么这些价值如此之大,如果它们可以或不能那样。如果他们不能,那么之前的代码中可能存在错误。如果可以的话,所缺少的只是对反射向量进行归一化(camera_dir 已经是单一的)

反射矢量是这样计算的:

 Vec3f reflected = light_ray_dir - 2 * (light_ray_dir * hit_normal) * hit_normal;

其中 light_ray_dir 计算为:

Vec3f light_ray_dir (current.pos - intersection);

current 是光源的名称,intersection 是光线与三角形的交点。

当它只漫射光时,它总是工作得很好。

然而,hit_normal 是新代码,计算方式如下:

Vec3f hit_normal = (1 - u - v) * vert1 + u * vert2 + v * vert3;

u 和 v 是重心坐标,vertX 是三角形的顶点。

那么什么看起来更有可能呢?上述代码中可能存在更复杂的错误,或者只是缺少对反射向量的规范化。或者也许是别的什么?谢谢你的时间。

4

1 回答 1

0

是的,phong 反射模型使用归一化向量来计算反射光的强度。注意表达式中的帽子:

在此处输入图像描述

来源:https ://en.wikipedia.org/wiki/Phong_reflection_model

R 表示反射向量,L 表示光的方向,N 表示要渲染的点的表面法线,还要注意你已经转置了表达式的两个部分 - 如果你期望两个光向量,这可能是一个问题和反射矢量指向远离表面的方向,但根据您的模型,您可能会以不同的方式计算它。

在此处输入图像描述

我查看了您的代码,您的光线方向远离光线,而不是远离表面,所以我想主要要注意的是您的方向向量可能指向或指向表面,即符合或反对正常。我认为这不会导致 NaN。我会确保相机方向也被归一化,并在各处检查零长度向量,因为当你除以零时,这些向量会破坏你的正常计算。

我也看了你的正常计算。您的意思是从三角形顶点计算法线吗?或者你的意思是每个顶点的法线?

希望这可以帮助

于 2019-04-06T01:33:10.577 回答