我正在做一个关于光线追踪的项目,现在我可以做一些基本的渲染。
下图有:
镜面反射, 折射, 纹理映射 和阴影。
我正在尝试进行光泽反射,到目前为止这就是我得到的。 谁能告诉我这个光泽反射图像是否有任何问题?
相比之下,下图是镜面反射的结果
这是我关于光泽反射的代码,基本上,一旦主光线与物体相交。 从这个交点开始,它会随机射出另外 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;
最佳答案
除了编码时从来都不好的硬编码常量之外,还有一个更微妙的问题,尽管您的图像总体看起来不错。
蒙特卡洛积分包括对被积函数除以生成这些样本的概率密度函数 (pdf) 求和。因此您的代码中有两个问题:
- 尽管您似乎使用了 Phong 模型的 pdf,但您还没有除以 pdf(如果我很好地识别它;至少它不是统一的 pdf)
- 您已进一步扩展您的
x
和y
组件1./16.
显然没有任何理由进一步更改您的 pdf。
这个想法是,如果您能够根据 Phong 模型乘以余弦定律精确地对光线进行采样,那么您甚至不必将被积函数乘以 BRDF。在实践中,没有精确的公式可以精确采样 BRDF(朗伯式除外),因此您需要计算:
pixel value = sum BRDF*cosine*incoming_light / pdf
这基本上抵消了 if BRDF*cosine = pdf
.
当然,您的图像整体看起来不错,所以如果您对物理合理性不感兴趣,那也可能很好。
关于计算机图形学和蒙特卡罗积分(带有适当的公式)中使用的各种 pdf 的一个很好的来源是 Global Illumination Compendium作者:菲利普·杜特雷。
关于graphics - 光线追踪中的光泽反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15846867/