【问题标题】:"Specular" color with phong shading and raytracing overflows带有 phong 着色和光线跟踪溢出的“镜面”颜色
【发布时间】:2019-04-13 05:01:52
【问题描述】:

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

specular_color: inf inf inf

找出原因并不复杂:

是这样计算的:

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

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

reflected*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);

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

当它只做漫射光时,它总是能正常工作。

但是,hit_normal 是新代码,计算如下:

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

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

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

【问题讨论】:

  • 您可以使用调试器检查值以查看哪些值是问题。

标签: c++ graphics raytracing phong shading


【解决方案1】:

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

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

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

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

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

希望对你有帮助

【讨论】:

  • 感谢您的回答。我用作基础的代码就是这样做的:scratchapixel.com/code.php?id=32&origin=/lessons/…(第 477 和 564 行)。你能发展出“如果方向也颠倒了也没关系”?关于法线,我的想法是使用这段代码来模拟每个点的法线,给它平滑的阴影而不是平坦的阴影。所以我认为“从三角形顶点正常”?
  • 我更详细地介绍了这一点,矢量的方向只是需要注意的事情
猜你喜欢
  • 2019-10-21
  • 1970-01-01
  • 2012-01-18
  • 2014-03-26
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-20
相关资源
最近更新 更多