我正在做一个关于光线追踪的项目,现在我可以做一些基本的渲染。
下面的图片有:
镜面反射, 折射, 纹理映射 和影子。
我正在尝试做有光泽的反射,到目前为止,这是我得到的。 有人能告诉我这个有光泽的反射图像是否有任何问题?
相比之下,下面的图像来自镜面反射
这是关于光泽反射的代码,基本上,一旦主光线与对象相交。 从这个交叉点,它将随机拍摄另外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;
答案 0 :(得分:5)
除了编码时永远不会很好的硬编码常数之外,还有一个更微妙的问题,尽管你的图像整体看起来很好。
蒙特卡洛积分包括将积分除以生成这些样本的概率密度函数(pdf)。因此,您的代码中存在两个问题:
x
和y
组件进一步按1./16.
展开,因为显然没有理由进一步更改您的PDF格式。如果你能够根据Phong的模型乘以余弦定律来准确地对你的光线进行采样,那么你的想法就是然后你甚至不必将你的被积函数乘以BRDF。在实践中,没有确切的公式可以准确地对BRDF进行采样(除朗伯特之外),因此您需要计算:
pixel value = sum BRDF*cosine*incoming_light / pdf
如果BRDF*cosine = pdf
,则主要取消。
当然,您的图像总体看起来不错,所以如果您对物理合理性不感兴趣,那么这也可能是好的。
关于计算机图形和蒙特卡罗集成(使用适当的公式)的各种pdf的一个很好的资料来源是PhilipDutré的Global Illumination Compendium。