平方衰减的阴影总会使一切变黑

问题描述 投票:0回答:1

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

我试图将更多的light_sources添加到更靠近对象的位置,但是应该被着色的模型由具有不同坐标的多个多边形组成,这使得很难确定它们的良好状态。

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

似乎没有,有一些关于放置光源的地方,或任何可以获得并非全黑的图像的暗示?

感谢您阅读所有这些!

P.S:Intensity被注释掉了,因为在我以前做代码的例子中,它是一个

graphics 3d raytracing lighting shading
1个回答
1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.