我目前正在开发一个简单的raytracer,到目前为止,我已经成功实现了多个功能,例如抗锯齿,景深和带有区域灯的柔和阴影。
代表我的作品的图像可能是这样的:
(这里没有AA)
下一步是使用某种全局照明算法将现实添加到渲染中,因此我决定转向光子映射方式,这似乎是最简单的方法。
为此,我阅读了一些我在网上找到的论文,例如http://graphics.stanford.edu/courses/cs348b-01/course8.pdf。
写得很好。
现在,我的程序可以在场景中拍摄光子,并在第一次反弹(散射或镜面反射)后存储它们,然后将每个光子的功率缩放到LIGHT_POWER / PHOTON_AMOUNT。
这些图像直接表示了这一点,在这些图像中,我拍摄了1000k和50k光子,每个光子可以反弹6次,在全局 map 中总共有5000k和250k光子:
我以为效果是对的,所以我转到下一部分,该部分使用光线跟踪射线的交点上一定半径内的光子来计算间接照明。
在我的raytracer中,执行以下操作:
我为每个像素发送
(dot(N, L) * primitive.color * primitive.diffuseFactor * light.power)
和镜面反射项; 对于半径内的每个光子
计算光的方式与直接照明相同
(点(-photonDir,N)* native.color * photonColor)
并总结一切。
问题是这样做无法获得理想的结果,特别是与我在网上发现的图像相比,天花板非常暗(如果天花板有地板,我无法获得与地板一样明亮的天花板)直接照明的其他贡献,以及如果其上的光子仅是红色或绿色,如何将其变为白色)。
代表问题的图像如下:
这是使用15万个光子渲染的,每个光子有4个反弹,并且直接照明已被PI划分。
另外,如果您知道如何从角落清除那些丑陋的文物,请告诉我。
最佳答案
首先,非常感谢您的所有帮助。
其次,我在这里宣布,在遇到一些麻烦之后,经过一段时间我不接触代码,我终于明白了。
我不了解自己在做什么错,也许是在半球内获得随机方向的算法,也许是光子收集通道...
关键是在重新格式化代码后(并执行了最后的采集步骤和2.2 Gamma 校正),我能够用200k光子,10次漫反射,20个直接照明的样本和100个FG样本渲染以下内容(随机-余弦加权-方向)。
我对此感到非常满意,因为它看起来几乎与用V-Ray追踪的c4d路径中的场景再现相同。
我还不清楚存储光子入射方向的实用工具是什么,ahahahahahahah,但是可以用,所以没关系。
再次感谢。
关于c++ - 实现光子贴图时遇到问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27691721/