math - 光子映射的渲染方程

标签 math graphics 3d rendering raytracing

这是一篇很长的文章,感谢所有阅读本文的人!

因此,对于我自己的个人项目,我正在实现一个光子贴图,以与我构建的光线追踪器一起使用,但我无法理解渲染方程。我已经编写了代码来分散普通光子和焦散光子,将它们存储在 KD 树中,并在树中有效地查找它们以用于渲染。

因此渲染方程如下: Lr(x,w) = 积分( fr(x, w', w) * Li(x, w') cos(Theta i) * dw'i )

其中x是场景中的给定点,w'是入射光的方向,w是反射光,Theta_i是入射角(我认为)。

第一个问题:

这涉及术语 fr(x, w', w),即 BRDF(双向反射分布函数)。现在我不确定我是否理解正确,但基本上 BRDF 基本上是一个着色函数?也就是说,对于我的程序的基本光线追踪功能,我使用 phong 反射模型来进行直接照明和反射。重新使用我的 phong 反射代码并用它来表示积分中的 BRDF 是否有效?

第二个问题: 我的另一个问题与我们何时将渲染方程分解为其组成部分有关。例如,为了计算漫反射,我们这样做:

漫反射率 = 积分( fr,d(x, w', w), * Li,d(x,w') cos(theta_i) dw'i)

因此,在任何给定点,我都已经在其周围存储了一堆漫反射光子。根据我对这个方程的理解,我是否只需将每个光子的强度乘以 phong 模型的漫反射分量乘以角度的余弦并将它们全部相加?

我为该特定段编写的代码如下所示:

Color result = Color(0,0,0) // r = g = b = 0;
for(int i = 0; i < # photons surrounding point x; i ++)
{
   result += Phong_Diffuse(photon_i, x, camera_ray) * photon_i.color * photon_i.angle
}

然后,我将其添加到从直接照明 ( Phong_DIFF_&_SPEC(light_source, x, camera_ray) ) 获得的颜色以及从镜面反射获得的颜色中。我在这里做的事情正确吗?

我似乎没有达到预期的效果。原因之一是,如果我缩放光子,使每个光子的强度为 Light_source/num_Photons,那么即使每个位置有数百个光子,它也几乎不会对我的场景产生明显的影响,因为我总共有 500,000 个光子。如果我不缩放光子或捏造缩放比例,颜色看起来仍然不正常。

此外,当我在 Cornell_box 上进行测试时,即使使用漫反射,天花板仍然明显非常暗,而根据我看到的其他 Cornell 盒子的图片,天花板应该要亮得多。

我也不认为这与我存储光子的方式有关,因为我尝试过直接可视化我的光子(因此整个场景只是由光子所在的彩色点组成)并且它们看起来大致均匀地分布在正确的位置,当我测试看到我正在收集最接近给定点的光子时,这似乎也有效。

感谢所有愿意花时间阅读这篇冗长杂乱的文章的人,也感谢所有花时间回复的人! =)

最佳答案

对于你的第一个问题,答案是肯定的。 BRDF 只是一种概率分布,描述入射方向为 i 的光子被反射到方向 o(或被吸收)的概率。这也是您的 Phong 模型所描述的。

对于你的第二个问题,我猜你的问题在于比例因子。当您在半径为 R 的邻域中收集光子时(无论 R 是恒定的,还是随着 k 个最近邻而变化),您必须将累积的能量除以面积半径为 R 的圆盘(因此,如果该面积远小于 1,这将提高您的强度)。 除此之外,你的计算似乎是正确的:你获取所有光子的方向,在 BRDF 中使用它们来查看它们反射到相机的概率(或者换句话说,光子反射到相机时剩余多少能量) ),并对所有内容进行求和。我猜你的 Phong_Diffuse 包含一个漫反射组件(因此得名),如果是这样,那也是正确的。
另一种可能性是漫反射太弱,无法产生可见的漫反射。

关于math - 光子映射的渲染方程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13713580/

相关文章:

c# - C# 中的 FILETIME 舍入以适应 FAT 舍入

java - Android - 在位图上绘制文本很困难

java - 在java中旋转图像

c++ - 如何强制 Mac 窗口到前台?

java - 将 Canvas3D 写入文件

python - 更改 Mayavi 中的间距

javascript - 反转 Web 墨卡托方程以将像素转换为纬度经度

algorithm - 我如何评估节点的连通性?

c# - 如何计算一个数字的总位数?

javascript - 如何在 Canvas 中拖动图像/对象?