使用方形衰减的阴影总是使一切变黑
Shading with squared falloff always makes everything black
我最近尝试更改我在 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
length是点光源中心到交点的向量长度:
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:强度被注释掉了,因为在我用来做我的代码的例子中,它是一个
所以您假设光的亮度为“1”?
你的灯有多远?
如果你的光 - 比如说 - 10 个单位,那么它们对光的贡献将是 1/10,或者一个非常小的数字。这可能是您的图像变暗的原因。
如果你要这样做,你需要有相当大的光强度数字。在我的一个场景中,我有一盏灯,距离大约 1000 个单位(假装是太阳),强度为 380000!
另一件事......为了模拟现实,你应该使用 1 / length^2。光强度随着距离的平方而下降,而不仅仅是随着距离而下降。
祝你好运!
我最近尝试更改我在 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
length是点光源中心到交点的向量长度:
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:强度被注释掉了,因为在我用来做我的代码的例子中,它是一个
所以您假设光的亮度为“1”? 你的灯有多远? 如果你的光 - 比如说 - 10 个单位,那么它们对光的贡献将是 1/10,或者一个非常小的数字。这可能是您的图像变暗的原因。 如果你要这样做,你需要有相当大的光强度数字。在我的一个场景中,我有一盏灯,距离大约 1000 个单位(假装是太阳),强度为 380000! 另一件事......为了模拟现实,你应该使用 1 / length^2。光强度随着距离的平方而下降,而不仅仅是随着距离而下降。 祝你好运!