0

我最近尝试改变我在 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。但是,即使我将其替换为一个(破坏了我实现真实光衰减的目标),我仍然会得到接近于零的颜色值,因此是黑色图像。

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

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

似乎没有,有一些关于在哪里放置光源的提示,或者任何可以获得不是全黑的图像的东西?

感谢您阅读这一切!

PS:Intensity 被注释掉了,因为在我用来编写代码的示例中,它是一个

4

1 回答 1

1

所以你假设光的亮度为“1”?你的灯有多远?如果你的灯在 - 比如说 - 10 个单位之外,那么它们对灯光的贡献将是 1/10,或者是一个非常小的数字。这可能就是您的图像变暗的原因。如果你要这样做,你需要有相当大的数字来表示你的光强度。在我的一个场景中,我有一个距离大约 1000 单位的光(假装是太阳),强度为 380000!另一件事......要模拟现实,您应该使用 1 / length^2。光强度随距离的平方而下降,而不仅仅是距离。祝你好运!

于 2019-02-21T22:49:27.460 回答