无法实现光子映射

时间:2014-12-29 15:35:29

标签: c++ raytracing

我目前正在开发一个简单的光线跟踪器,直到现在我已经成功实现了几个功能,例如抗锯齿,景深和带有区域光的柔和阴影。 代表我工作的图像可能是这样的:


(这里没有AA)

下一步是使用一些全局照明算法为渲染添加现实,所以我决定转向光子映射方式,这似乎是最简单的方法。

为此,我阅读了一些我在网上发现的论文,例如:http://graphics.stanford.edu/courses/cs348b-01/course8.pdf 写得非常好。

现在我的程序可以在场景中拍摄光子并在第一次反射(漫反射或镜面反射)后存储它们,然后将每个光子的功率缩放到LIGHT_POWER / PHOTON_AMOUNT。 在这些图像中可以直观地看到这一点,在这些图像中我拍摄了1000k和50k光子,每个光子允许反射6次,在全球地图中总共有5000k和250k光子:

我认为效果是正确的,所以我移动到下一部分,即光线追踪光线交叉点上某一半径范围内的光子用于计算间接照明。

在我的光线跟踪器中,我按如下方式执行:

  1. 对于每个像素,我通过它发送光线以与场景相交并计算直接照明(dot(N, L) * primitive.color * primitive.diffuseFactor * light.power)和镜面反射词;

  2. 这是一个棘手的部分:我寻找最近的光子,这些光子位于交叉点周围的固定半径圆盘中,并以这种方式对每个光源产生的光进行求和:

    对于半径内的每个光子       以与直接照明相同的方式计算光线          (dot(-photonDir,N)* primitive.color * photonColor)       并总结一切。

  3. 当处理完每个有趣的光子并将其添加到最终颜色时,我将其除以定义搜索区域的光盘区域。

  4. 问题在于这样做我没有得到理想的结果,特别是与我在网上发现的图像相比,天花板非常暗(我无法知道天花板如何像地板一样明亮如果后者有直接照明的额外贡献,如果它上面的光子只是红色或绿色,它可以是白色的。)

    表示问题的图像如下:

    使用150k光子渲染,每次反射4次,直接照射除以PI。

    另外,如果您知道如何从角落移除那些丑陋的文物,请告诉我。

1 个答案:

答案 0 :(得分:4)

首先,非常感谢你的帮助。

其次,我在这里宣布,经过一些麻烦,经过一段时间我没有触及代码,我终于明白了。

我还没有理解我做错了什么,可能是在半球内获得随机方向的算法,可能是光子聚集传递...... 重点是在重新格式化代码之后(并且在实施最终聚集步骤和2.2伽马校正之后),我能够使用200k光子,10个漫反射,20个直接照明样本和100个FG样本渲染以下内容(随机 - 余弦加权方向)。

The final result

我对此非常满意,因为它看起来与使用V-Ray跟踪的c4d路径中的场景再现几乎相同。

我仍然无法清楚存储光子事件方向的实用程序,ahahahahahahah,但是它有效,所以没关系。

再次感谢。