用于多灯的 GLSL 照明不起作用?
GLSL Lighting for multiple light not working?
我正在尝试渲染多个定向光源和多个点光源,但它只渲染光阵列中的最后一个定向光源和最后一个点光源。我检查了所有用于照明的数据是否已正确发送到 glsl 片段着色器,但它似乎不起作用。
NUM_DIR_LIGHTS-1
和 NUM_POINT_LIGHTS-1
被动态插入片段着色器并且也有正确的值。
片段颜色输出的计算:
vec4 ambient = vec4(0.0);
vec4 diffuse = vec4(0.0);
vec4 specular = vec4(0.0);
vec4 diffuseTexel = texture(u_Material.DiffuseMap, v_TexCoord);
vec4 specularTexel = texture(u_Material.SpecularMap, v_TexCoord);
vec4 normalTexel = texture(u_Material.NormalMap, v_TexCoord);
vec3 viewDir = normalize(u_CameraPosition - v_Position);
float dirShadow = 0.0;
// calculate material for all directional lights
vec3 normalFromMap = normalize(transpose(inverse(v_ModelRotation)) * normalTexel.xyz);
vec3 normalizedNormal = normalize(v_Normal);
for (int i = 0; i < NUM_DIR_LIGHTS-1; i++)
{
vec3 lightDir = normalize(-u_DirectionalLights[i].Direction);
// if material is mapped then apply lighting with lighting maps
if (u_Material.IsMapped)
{
// ambient lighting
ambient += vec4(u_DirectionalLights[i].Color * u_DirectionalLights[i].Intensity * diffuseTexel.rgb, 1.0);
// diffuse lighting
float diff = max(dot(normalFromMap, lightDir), 0.0);
diffuse += vec4(u_DirectionalLights[i].Color * diff * diffuseTexel.rgb, 1.0);
// specular lighting
vec3 reflectDir = reflect(-lightDir, normalFromMap);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
specular += vec4(u_DirectionalLights[i].Color * spec * specularTexel.rgb, 1.0);
dirShadow += calcDirLightShadow(i, lightDir, normalTexel.xyz);
}
else
{
// ambient lighting for material
ambient += vec4(u_DirectionalLights[i].Color * (u_Material.Ambient + u_DirectionalLights[i].Intensity * u_Material.Diffuse), 1.0);
// diffuse lighting for material
float diff = max(dot(normalizedNormal, lightDir), 0.0);
diffuse += vec4(u_DirectionalLights[i].Color * u_DirectionalLights[i].Intensity * diff * u_Material.Diffuse, 1.0);
// specular lighting for material
vec3 reflectDir = reflect(-lightDir, normalizedNormal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
specular += vec4(u_DirectionalLights[i].Color * u_DirectionalLights[i].Intensity * spec * u_Material.Specular, 1.0);
dirShadow += calcDirLightShadow(i, lightDir, v_Normal);
}
}
// calculate material for all point lights
vec3 pointAmbient = vec3(0.0);
vec3 pointDiffuse = vec3(0.0);
vec3 pointSpecular = vec3(0.0);
for (int i = 0; i < NUM_POINT_LIGHTS-1; i++)
{
// if material is mapped then apply lighting with lighting maps
if (u_Material.IsMapped)
{
// ambient lighting
pointAmbient += u_PointLights[i].Color * u_PointLights[i].Intensity * diffuseTexel.rgb;
// diffuse lighting
vec3 lightDir = normalize(u_PointLights[i].Position - v_Position);
float diff = max(dot(normalFromMap, lightDir), 0.0);
pointDiffuse += u_PointLights[i].Color * diff * diffuseTexel.rgb;
// specular lighting
vec3 reflectDir = reflect(-lightDir, normalFromMap);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
pointSpecular += u_PointLights[i].Color * spec * specularTexel.rgb;
}
else
{
// ambient lighting for material
pointAmbient += u_PointLights[i].Color * (u_Material.Ambient + u_PointLights[i].Intensity * u_Material.Diffuse);
// diffuse lighting for material
vec3 lightDir = normalize(u_PointLights[i].Position - v_Position);
float diff = max(dot(normalizedNormal, lightDir), 0.0);
pointDiffuse += u_PointLights[i].Color * u_PointLights[i].Intensity * diff * u_Material.Diffuse;
// specular lighting for material
vec3 reflectDir = reflect(-lightDir, normalizedNormal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
pointSpecular += u_PointLights[i].Color * u_PointLights[i].Intensity * spec * u_Material.Specular;
}
// calculate attenuation
float distance = length(u_PointLights[i].Position - v_Position);
float attenuation = 1.0f / (u_PointLights[i].Constant + u_PointLights[i].Linear *
distance + u_PointLights[i].Quadratic * (distance * distance));
// include attenuation in lighting
pointAmbient *= attenuation;
pointDiffuse *= attenuation;
pointSpecular *= attenuation;
}
// calculate directional lighting with shadow
vec3 lighting = vec3(ambient + (1.0 - dirShadow) * (diffuse + specular));
return vec4(lighting + pointAmbient + pointDiffuse + pointSpecular, 1.0);
我希望有人能理解为什么它没有渲染所有灯光。
问题是
for (int i = 0; i < NUM_POINT_LIGHTS-1; i++)
{
// [...]
pointAmbient *= attenuation;
pointDiffuse *= attenuation;
pointSpecular *= attenuation;
}
此处光源的总和乘以循环中遍历光源的衰减。这意味着已经添加的光源乘以后面光源的衰减。已经添加的光源发出的光会随着每添加一个新光源而变得越来越弱。
可能的解决方案:
vec3 pointAmbient = vec3(0.0);
vec3 pointDiffuse = vec3(0.0);
vec3 pointSpecular = vec3(0.0);
for (int i = 0; i < NUM_POINT_LIGHTS-1; i++)
{
// calculate attenuation
float distance = length(u_PointLights[i].Position - v_Position);
float attenuation = 1.0f / (u_PointLights[i].Constant + u_PointLights[i].Linear *
distance + u_PointLights[i].Quadratic * (distance * distance));
// if material is mapped then apply lighting with lighting maps
if (u_Material.IsMapped)
{
// ambient lighting
pointAmbient += attenuation * u_PointLights[i].Color * u_PointLights[i].Intensity * diffuseTexel.rgb;
// diffuse lighting
vec3 lightDir = normalize(u_PointLights[i].Position - v_Position);
float diff = max(dot(normalFromMap, lightDir), 0.0);
pointDiffuse += attenuation * u_PointLights[i].Color * diff * diffuseTexel.rgb;
// specular lighting
vec3 reflectDir = reflect(-lightDir, normalFromMap);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
pointSpecular += attenuation * u_PointLights[i].Color * spec * specularTexel.rgb;
}
else
{
// ambient lighting for material
pointAmbient += attenuation * u_PointLights[i].Color * (u_Material.Ambient + u_PointLights[i].Intensity * u_Material.Diffuse);
// diffuse lighting for material
vec3 lightDir = normalize(u_PointLights[i].Position - v_Position);
float diff = max(dot(normalizedNormal, lightDir), 0.0);
pointDiffuse += attenuation * u_PointLights[i].Color * u_PointLights[i].Intensity * diff * u_Material.Diffuse;
// specular lighting for material
vec3 reflectDir = reflect(-lightDir, normalizedNormal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
pointSpecular += attenuation * u_PointLights[i].Color * u_PointLights[i].Intensity * spec * u_Material.Specular;
}
}
我正在尝试渲染多个定向光源和多个点光源,但它只渲染光阵列中的最后一个定向光源和最后一个点光源。我检查了所有用于照明的数据是否已正确发送到 glsl 片段着色器,但它似乎不起作用。
NUM_DIR_LIGHTS-1
和 NUM_POINT_LIGHTS-1
被动态插入片段着色器并且也有正确的值。
片段颜色输出的计算:
vec4 ambient = vec4(0.0);
vec4 diffuse = vec4(0.0);
vec4 specular = vec4(0.0);
vec4 diffuseTexel = texture(u_Material.DiffuseMap, v_TexCoord);
vec4 specularTexel = texture(u_Material.SpecularMap, v_TexCoord);
vec4 normalTexel = texture(u_Material.NormalMap, v_TexCoord);
vec3 viewDir = normalize(u_CameraPosition - v_Position);
float dirShadow = 0.0;
// calculate material for all directional lights
vec3 normalFromMap = normalize(transpose(inverse(v_ModelRotation)) * normalTexel.xyz);
vec3 normalizedNormal = normalize(v_Normal);
for (int i = 0; i < NUM_DIR_LIGHTS-1; i++)
{
vec3 lightDir = normalize(-u_DirectionalLights[i].Direction);
// if material is mapped then apply lighting with lighting maps
if (u_Material.IsMapped)
{
// ambient lighting
ambient += vec4(u_DirectionalLights[i].Color * u_DirectionalLights[i].Intensity * diffuseTexel.rgb, 1.0);
// diffuse lighting
float diff = max(dot(normalFromMap, lightDir), 0.0);
diffuse += vec4(u_DirectionalLights[i].Color * diff * diffuseTexel.rgb, 1.0);
// specular lighting
vec3 reflectDir = reflect(-lightDir, normalFromMap);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
specular += vec4(u_DirectionalLights[i].Color * spec * specularTexel.rgb, 1.0);
dirShadow += calcDirLightShadow(i, lightDir, normalTexel.xyz);
}
else
{
// ambient lighting for material
ambient += vec4(u_DirectionalLights[i].Color * (u_Material.Ambient + u_DirectionalLights[i].Intensity * u_Material.Diffuse), 1.0);
// diffuse lighting for material
float diff = max(dot(normalizedNormal, lightDir), 0.0);
diffuse += vec4(u_DirectionalLights[i].Color * u_DirectionalLights[i].Intensity * diff * u_Material.Diffuse, 1.0);
// specular lighting for material
vec3 reflectDir = reflect(-lightDir, normalizedNormal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
specular += vec4(u_DirectionalLights[i].Color * u_DirectionalLights[i].Intensity * spec * u_Material.Specular, 1.0);
dirShadow += calcDirLightShadow(i, lightDir, v_Normal);
}
}
// calculate material for all point lights
vec3 pointAmbient = vec3(0.0);
vec3 pointDiffuse = vec3(0.0);
vec3 pointSpecular = vec3(0.0);
for (int i = 0; i < NUM_POINT_LIGHTS-1; i++)
{
// if material is mapped then apply lighting with lighting maps
if (u_Material.IsMapped)
{
// ambient lighting
pointAmbient += u_PointLights[i].Color * u_PointLights[i].Intensity * diffuseTexel.rgb;
// diffuse lighting
vec3 lightDir = normalize(u_PointLights[i].Position - v_Position);
float diff = max(dot(normalFromMap, lightDir), 0.0);
pointDiffuse += u_PointLights[i].Color * diff * diffuseTexel.rgb;
// specular lighting
vec3 reflectDir = reflect(-lightDir, normalFromMap);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
pointSpecular += u_PointLights[i].Color * spec * specularTexel.rgb;
}
else
{
// ambient lighting for material
pointAmbient += u_PointLights[i].Color * (u_Material.Ambient + u_PointLights[i].Intensity * u_Material.Diffuse);
// diffuse lighting for material
vec3 lightDir = normalize(u_PointLights[i].Position - v_Position);
float diff = max(dot(normalizedNormal, lightDir), 0.0);
pointDiffuse += u_PointLights[i].Color * u_PointLights[i].Intensity * diff * u_Material.Diffuse;
// specular lighting for material
vec3 reflectDir = reflect(-lightDir, normalizedNormal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
pointSpecular += u_PointLights[i].Color * u_PointLights[i].Intensity * spec * u_Material.Specular;
}
// calculate attenuation
float distance = length(u_PointLights[i].Position - v_Position);
float attenuation = 1.0f / (u_PointLights[i].Constant + u_PointLights[i].Linear *
distance + u_PointLights[i].Quadratic * (distance * distance));
// include attenuation in lighting
pointAmbient *= attenuation;
pointDiffuse *= attenuation;
pointSpecular *= attenuation;
}
// calculate directional lighting with shadow
vec3 lighting = vec3(ambient + (1.0 - dirShadow) * (diffuse + specular));
return vec4(lighting + pointAmbient + pointDiffuse + pointSpecular, 1.0);
我希望有人能理解为什么它没有渲染所有灯光。
问题是
for (int i = 0; i < NUM_POINT_LIGHTS-1; i++)
{
// [...]
pointAmbient *= attenuation;
pointDiffuse *= attenuation;
pointSpecular *= attenuation;
}
此处光源的总和乘以循环中遍历光源的衰减。这意味着已经添加的光源乘以后面光源的衰减。已经添加的光源发出的光会随着每添加一个新光源而变得越来越弱。
可能的解决方案:
vec3 pointAmbient = vec3(0.0);
vec3 pointDiffuse = vec3(0.0);
vec3 pointSpecular = vec3(0.0);
for (int i = 0; i < NUM_POINT_LIGHTS-1; i++)
{
// calculate attenuation
float distance = length(u_PointLights[i].Position - v_Position);
float attenuation = 1.0f / (u_PointLights[i].Constant + u_PointLights[i].Linear *
distance + u_PointLights[i].Quadratic * (distance * distance));
// if material is mapped then apply lighting with lighting maps
if (u_Material.IsMapped)
{
// ambient lighting
pointAmbient += attenuation * u_PointLights[i].Color * u_PointLights[i].Intensity * diffuseTexel.rgb;
// diffuse lighting
vec3 lightDir = normalize(u_PointLights[i].Position - v_Position);
float diff = max(dot(normalFromMap, lightDir), 0.0);
pointDiffuse += attenuation * u_PointLights[i].Color * diff * diffuseTexel.rgb;
// specular lighting
vec3 reflectDir = reflect(-lightDir, normalFromMap);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
pointSpecular += attenuation * u_PointLights[i].Color * spec * specularTexel.rgb;
}
else
{
// ambient lighting for material
pointAmbient += attenuation * u_PointLights[i].Color * (u_Material.Ambient + u_PointLights[i].Intensity * u_Material.Diffuse);
// diffuse lighting for material
vec3 lightDir = normalize(u_PointLights[i].Position - v_Position);
float diff = max(dot(normalizedNormal, lightDir), 0.0);
pointDiffuse += attenuation * u_PointLights[i].Color * u_PointLights[i].Intensity * diff * u_Material.Diffuse;
// specular lighting for material
vec3 reflectDir = reflect(-lightDir, normalizedNormal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.Shininess);
pointSpecular += attenuation * u_PointLights[i].Color * u_PointLights[i].Intensity * spec * u_Material.Specular;
}
}