我已经用C ++编写了raytracer。这是用于计算扩散成分的代码段:
//diffuse component
color diffuse(0, 0, 0);
if (intrs.mat.diffuseness > 0)
{
for (auto &light : lights)
{
//define ray from hit object to light
ray light_dir(intrs.point, (light->point - intrs.point).normalize());
double nl = light_dir.direction*intrs.normal; //dot product
double diminish_coeff = 1.0;
double dist = intrs.point.sqrDistance(light->point);
//check whether it reaches the light
if (nl > 0)
{
for (int i = 0; i < (int)shapes.size(); ++i)
{
shape::intersection temp_intrs(shapes[i]->intersect(light_dir, shapes[i]->interpolate_normals));
if (temp_intrs.valid && temp_intrs.point.sqrDistance(intrs.point) < dist)
{
diminish_coeff *= shadow_darkness;
break;
}
}
}
diffuse += intrs.mat.diffuseness * intrs.mat.col * light->light_color * light->light_intensity * nl*diminish_coeff;
}
}
当然,我不能发布整个代码,但是我想我在这里要清楚-intrs
是射线和对象的当前交集,shapes
是场景中所有对象的向量。
颜色以(0,1)范围内的RGB表示。颜色的加法和乘法是简单的逐成员加法和乘法。仅当光线跟踪结束并且要写入图像文件时,我才将颜色乘以255,如果分量大于该值,则将其钳位到255。
当前,场景中只有一个点光源,它是白色的:color(1,1,1),强度= 1.0。
所以,这是不对的-左边的橱柜应该是绿色的,盒子应该是红色的。
我的实现中是否存在明显的问题?我似乎无法弄清楚。如有必要,我将发布更多代码。
答案 0 :(得分:1)
您的diffuse +=
行似乎应该位于if (nl > 0)
条件的内部,而不是外部。
答案 1 :(得分:0)
我发现了问题。由于某种原因,我的intrs.normal
向量没有被标准化。感谢大家的帮助。