我试图实现一个简单的观察者,我试图对点光源实现光衰减。
我遇到的问题如下:
我有那种不自然的线越过球体。
着色器中的相关代码是:
....
vec3 Ldist = uLightPosition-vPosition.xyz;
vec3 L = normalize(Ldist);
....
float NdotL = max(dot(N,L),0.0);
float attenuation = 1.0/ (Ldist*Ldist);
vec3 light = uAmbientColor;
if(NdotL>0.0){
specularWeighting = rho_s * computeBRDF(roughness, Didx, Gidx, Fidx, L, N, V);
light = light + NdotL*uLightColor*attenuation*(specularWeighting*specularColor*envColor.rgb + diffuseColor);
}
对于略微更高级的照明不熟悉,我真的无法看出可能出现的问题。
(我知道也许应该是一个不同的问题,但是这么小我想知道我是否也可以在这里问这个问题:是否有任何经验法则可以选择光线和强度位置以获得良好的结果像球体那样的单个物体?)
答案 0 :(得分:2)
以下内容并不合理:
vec3 Ldist = uLightPosition-vPosition.xyz;
[...]
float attenuation = 1.0/ (Ldist*Ldist);
首先,这甚至不应该编译,因为Ldist
是vec3
而*
运算符将执行组件明智的乘法,留下你的标量除以a向量。但是除了语法问题之外,假设只是len(LDist)
(我将在下文中称之为d
),衰减项仍然没有意义。通常,使用的衰减项是
1.0/(a + b*d + c * d*d)
a
,b
和c
分别是常数,线性和四次光衰减系数。这里要注意的重要一点是,如果该等式的分母变为< 1,“衰减”将是1 - 因此实现了相反的效果。由于在一般场景中,距离可以低至0,确保永远不会发生这种情况的唯一方法是设置a
> = 1,这通常是完成的。因此,我建议您至少使用1.0/(1.0+d)
作为衰减项,或者通常添加一些恒定的衰减系数。