带有平方衰减的阴影总是使所有东西变黑

时间:2019-02-21 22:07:57

标签: graphics 3d raytracing lighting shading

我最近尝试更改当前在RayTracer中计算漫射照明的方式。过去是这样计算的:

 float lambert = (light_ray_dir * normal) * coef;
 red += lambert * current.color.red * mat.kd.red;
 green += lambert * current.color.green * mat.kd.green;
blue += lambert * current.color.blue * mat.kd.blue;

其中coef是一个衰减系数,对于每个像素,衰减系数从1开始,然后对于由该线生成的每个反射射线衰减:

coef *= mat.reflection;

效果很好。

但是我决定尝试一些更现实的方法并实现这一点:

float squared_attenuation = LIGHT_FALLOFF * lenght;
light_intensity.setX ((current.color.red /*INTENSITY*/)/ squared_attenuation);
light_intensity.setY ((current.color.green  /*INTENSITY*/)/ squared_attenuation);
light_intensity.setZ ((current.color.blue  /*INTENSITY*/)/ squared_attenuation);
red   += ALBEDO * light_intensity.getX() * lambert * mat.kd.red;
green += ALBEDO * light_intensity.getY() * lambert * mat.kd.green;
blue  += ALBEDO * light_intensity.getZ() * lambert * mat.kd.blue;

其中LIGHT_FALLOFF是恒定值:

#define LIGHT_FALLOFF M_PI * 4

长度是从点光源中心到相交点的向量的长度:

inline float normalize_return_lenght ()  {
     float lenght = sqrtf (x*x + y*y + z*z);
     float inv_length = 1/lenght;
     x = x * inv_length, y = y * inv_length, z = z * inv_length;
     return lenght;
  }

float lenght = light_ray_dir.normalize_return_lenght ();

问题在于,这一切只会产生黑屏!罪魁祸首是在light_intensity.set中作为除数的长度。它使最终的颜色值是某个值^ -5。但是,即使我将其替换为一个(破坏了实现实际光衰减的目标),我仍然获得的色彩值仍接近于零,从而获得黑色图像。

我试图在对象附近添加另一个光源,但是要着色的模型是由具有不同坐标的多个多边形组成的,因此很难为其确定良好的位置。

所以我问。对您来说,这似乎很正常,或者似乎是个错误?从理论上讲,对我来说并不奇怪,因为衰减是平方的。

似乎没有,关于在何处放置光源或任何可以得到并非全黑的图像的提示?

感谢您阅读所有这些内容!

P.S:强度被注释掉是因为在我以前编写代码的示例中,强度是一个

1 个答案:

答案 0 :(得分:1)

因此,您假设该光的亮度为“ 1”? 你的灯有多远? 如果您的光源距离有10个单位,则它们的贡献为1/10,或者很小。这可能就是为什么图像较暗的原因。 如果要执行此操作,则需要具有相当大的光强度数值。在我的一个场景中,我有一盏灯,距离大约1000个单位(假装是太阳),强度为380000! 另一件事……模拟现实,您应该使用1 / length ^ 2。光强度与距离的平方成正比,而不仅与距离成正比。 祝你好运!