光线跟踪中的光泽反射

fif*_*lus 2 graphics raytracing

我正在做一个关于光线追踪的项目,现在我可以做一些基本的渲染.

下图有:

镜面反射,折射,纹理映射和阴影.

在此输入图像描述

我正在努力做有光泽的反射,到目前为止这是我得到的.谁能告诉我这个有光泽的反射图像是否有任何问题?

在此输入图像描述

相比之下,下面的图像来自镜面反射

在此输入图像描述

这是关于光泽反射的代码,基本上,一旦主光线与对象相交.从这个交叉点,它会随机拍摄另外80条光线,并取出这80条光线的平均颜色.我对这段代码的问题是x和y的大小,我必须将它们除以某个值,在这种情况下是16,这样光泽反射光线不会太随机.这个逻辑有什么问题吗?

             Colour c(0, 0, 0);

                     for (int i = 0; i < 80; i++) {

                          Ray3D testRay;
                          double a = rand() / (double) RAND_MAX;
                          double b = rand() / (double) RAND_MAX;
                          double theta = acos(pow((1 - a), ray.intersection.mat->reflectivity));
                          double phi = 2 * M_PI * b;
                          double x = sin(phi) * cos(theta)/16;
                          double y = sin(phi) * sin(theta)/16;
                          double z = cos(phi);
                          Vector3D u = reflect.dir.cross(ray.intersection.normal);
                          Vector3D v = reflect.dir.cross(u);
                          testRay.dir = x  * u + y * v  + reflect.dir;
                          testRay.dir.normalize();

                          testRay.origin = reflect.origin;
                          testRay.nbounces = reflect.nbounces;
                          c = c + (ray.intersection.mat->reflectivity)*shadeRay(testRay);
                     }
                     col = col + c / 80;
Run Code Online (Sandbox Code Playgroud)

nbo*_*eel 5

除了编码时永远不会很好的硬编码常数,还有一个更微妙的问题,尽管你的图像整体看起来很好.

蒙特卡罗积分包括将被积函数除以生成这些样本的概率密度函数(pdf).因此,您的代码中存在两个问题:

  • 虽然你似乎使用了pdf for Phong模型(如果我认得它很好;至少它不是一个统一的pdf)你没有用pdf分
  • 你已经进一步缩小你xy通过组件1./16.的显然没有理由进一步改变你的PDF文件.

我们的想法是,如果你能够根据Phong的模型乘以余弦定律来准确地对你的光线进行采样,那么你甚至不需要将你的被积函数乘以BRDF.在实践中,没有确切的公式可以准确地对BRDF进行采样(除了Lambertian之外),因此您需要计算:
pixel value = sum BRDF*cosine*incoming_light / pdf
哪些主要取消if BRDF*cosine = pdf.

当然,你的图像整体看起来很好,所以如果你对物理合理性不感兴趣,那也可能是好的.
关于计算机图形和蒙特卡罗集成(使用适当的公式)的各种pdf的一个很好的资料来源是PhilipDutré 的全球照明纲要.