带有phong阴影和光线追踪的“特殊”颜色溢出

时间:2019-04-06 00:25:50

标签: c++ graphics raytracing phong shading

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

  

specular_color:inf inf inf

找出原因并不复杂:

它是这样计算的:

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

其中mat.ns是镜面指数,显示期望值。

reflected * camera_dir是原因,因为它总是以很大的值结尾。在我的四个测试用例中,有三个是五位数。另一个是六位数的值(接近7)。因此,将五到六位数的值带到任何不太接近一个指数的指数上都可能会使float变量溢出。

现在的问题是,为什么这些值如此之大,无论它们是否可以那样。如果他们不能,则可能是先前代码中存在错误。如果可以的话,所缺少的只是标准化反射向量(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);

当前是光源的名称,交点是射线与三角形的相遇点。

当它仅散射光时,它总是可以正常工作。

hit_normal是新代码,其计算公式为:

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

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

那么似乎更有可能?上面的代码中可能存在更复杂的错误,或者只是缺少对反射向量的归一化。还是别的?感谢您的宝贵时间。

1 个答案:

答案 0 :(得分:0)

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

enter image description here

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

R表示反射向量,L表示光的方向,N表示要渲染的点处的表面的法线,还请注意,您已经对表达式的两个部分进行了换位-如果您期望两个都换位光线矢量和反射矢量指向远离曲面的方向,但是根据您的模型,您可能对此进行了不同的计算。

enter image description here

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

我也对您的正常计算有所了解。您是要从三角形顶点计算法线吗?还是说每个顶点的法线都正确?

希望这会有所帮助