opengl-es 前像素照明问题
opengl-es pre pixel lighting issue
有个问题我似乎无法解决..
我有一个片段着色器:
precision mediump float;
uniform vec3 u_AmbientColor;
uniform vec3 u_LightPos;
uniform float u_Attenuation_Constant;
uniform float u_Attenuation_Linear;
uniform float u_Attenuation_Quadradic;
uniform vec3 u_LightColor;
varying vec3 v_Normal;
varying vec3 v_fragPos;
vec4 fix(vec3 v);
void main() {
vec3 color = vec3(1.0,1.0,1.0);
vec3 vectorToLight = u_LightPos - v_fragPos;
float distance = length(vectorToLight);
vec3 direction = vectorToLight / distance;
float attenuation = 1.0/(u_Attenuation_Constant +
u_Attenuation_Linear * distance + u_Attenuation_Quadradic * distance * distance);
vec3 diffuse = u_LightColor * attenuation * max(normalize(v_Normal) * direction,0.0);
vec3 d = u_AmbientColor + diffuse;
gl_FragColor = fix(color * d);
}
vec4 fix(vec3 v){
float r = min(1.0,max(0.0,v.r));
float g = min(1.0,max(0.0,v.g));
float b = min(1.0,max(0.0,v.b));
return vec4(r,g,b,1.0);
}
我一直在关注我在网上找到的一些教程,
无论如何,ambientColor 和 lightColor 制服是 (0.2,0.2,0.2) 和 (1.0,1.0,1.0)
分别。 v_Normal 是在顶点着色器中使用
模型视图矩阵的倒置转置矩阵。
v_fragPos是位置与普通模型视图矩阵相乘的模型结果
现在,我希望当我将灯光位置移近我渲染的立方体时,它只会显得更亮,但生成的图像却大不相同:
(小方块有灯位指示)
现在,我只是不明白这是怎么发生的?
我的意思是,我将每个颜色分量乘以相同的值。
所以,怎么好像变化这么大??
编辑:我注意到如果我将相机移到立方体前面,光线只是蓝色阴影..这是同样的问题,但也许这是我不知道的线索..
Lambertian reflectance is computed with the Dot product 法向量和到光源的向量,而不是分量乘积。
参见 How does the calculation of the light model work in a shader program?
使用 dot
函数代替 *
(乘法)运算符:
vec3 diffuse = u_LightColor * attenuation * max(normalize(v_Normal) * direction,0.0);
vec3 diffuse = u_LightColor * attenuation * max(dot(normalize(v_Normal), direction), 0.0);
您可以简化 fix
函数中的代码。 min
和max
可以用clamp
代替。此函数在组件方面工作,因此不必为每个组件单独调用它们:
vec4 fix(vec3 v)
{
return vec4(clamp(v, 0.0, 1.0), 1.0);
}
有个问题我似乎无法解决.. 我有一个片段着色器:
precision mediump float;
uniform vec3 u_AmbientColor;
uniform vec3 u_LightPos;
uniform float u_Attenuation_Constant;
uniform float u_Attenuation_Linear;
uniform float u_Attenuation_Quadradic;
uniform vec3 u_LightColor;
varying vec3 v_Normal;
varying vec3 v_fragPos;
vec4 fix(vec3 v);
void main() {
vec3 color = vec3(1.0,1.0,1.0);
vec3 vectorToLight = u_LightPos - v_fragPos;
float distance = length(vectorToLight);
vec3 direction = vectorToLight / distance;
float attenuation = 1.0/(u_Attenuation_Constant +
u_Attenuation_Linear * distance + u_Attenuation_Quadradic * distance * distance);
vec3 diffuse = u_LightColor * attenuation * max(normalize(v_Normal) * direction,0.0);
vec3 d = u_AmbientColor + diffuse;
gl_FragColor = fix(color * d);
}
vec4 fix(vec3 v){
float r = min(1.0,max(0.0,v.r));
float g = min(1.0,max(0.0,v.g));
float b = min(1.0,max(0.0,v.b));
return vec4(r,g,b,1.0);
}
我一直在关注我在网上找到的一些教程, 无论如何,ambientColor 和 lightColor 制服是 (0.2,0.2,0.2) 和 (1.0,1.0,1.0) 分别。 v_Normal 是在顶点着色器中使用 模型视图矩阵的倒置转置矩阵。
v_fragPos是位置与普通模型视图矩阵相乘的模型结果
现在,我希望当我将灯光位置移近我渲染的立方体时,它只会显得更亮,但生成的图像却大不相同:
(小方块有灯位指示) 现在,我只是不明白这是怎么发生的? 我的意思是,我将每个颜色分量乘以相同的值。 所以,怎么好像变化这么大??
编辑:我注意到如果我将相机移到立方体前面,光线只是蓝色阴影..这是同样的问题,但也许这是我不知道的线索..
Lambertian reflectance is computed with the Dot product 法向量和到光源的向量,而不是分量乘积。
参见 How does the calculation of the light model work in a shader program?
使用 dot
函数代替 *
(乘法)运算符:
vec3 diffuse = u_LightColor * attenuation * max(normalize(v_Normal) * direction,0.0);
vec3 diffuse = u_LightColor * attenuation * max(dot(normalize(v_Normal), direction), 0.0);
您可以简化 fix
函数中的代码。 min
和max
可以用clamp
代替。此函数在组件方面工作,因此不必为每个组件单独调用它们:
vec4 fix(vec3 v)
{
return vec4(clamp(v, 0.0, 1.0), 1.0);
}