最终效果
demo演示
多光源
- 原理:
- 所有投光物分别计算,对当前片段的影响,再+求和,渲染出物体的材质效果
- 每个投光物:根据冯氏光照(环境,漫反射,镜面)分解计算对片段的强度影响,再与当前片段颜色值(单一颜色 / 纹理颜色)* 相乘
- 每个投光物也会对(环境,漫反射,镜面)有不同的影响程度
- 通过struct和函数,进行整理归纳,比如绘制多个点光源,有不同的位置,之间把每次的位置传入点光源结构体中
Fragment_glsl
layout(location = 0) out vec4 FragColor;
sampler2D specular_Texture;
uniform Material material;
uniform DirLight dirLight;
uniform PointLight pointLights[10];
uniform SpotLight spotLight;
uniform ConstVal constVal;
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
vec3 viewPos = normalize(constVal.camera_Position - v_Position);
vec3 norm = normalize(v_Normal);
vec3 result = CalcDirLight(dirLight, norm, viewPos);
for(int i = 0; i < 10; i++)
result += CalcPointLight(pointLights[i], norm, v_Position, viewPos);
result += CalcSpotLight(spotLight, norm, v_Position, viewPos);
FragColor = vec4(result, 1.0);
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
vec3 lightDir = normalize(-light.direction);
float diff = max(dot(normal, lightDir), 0.0);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 ambient = light.ambient * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
vec3 diffuse = light.diffuse * diff * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
vec3 specular = light.specular * spec * vec3(texture(material.specular_Texture, v_TexCoord));
return (ambient + diffuse + specular);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
vec3 lightDir = normalize(light.position - fragPos);
float diff = max(dot(normal, lightDir), 0.0);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (constVal.constant + constVal.linear * distance + constVal.quadratic * (distance * distance));
vec3 ambient = light.ambient * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
vec3 diffuse = light.color * light.diffuse * diff * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
vec3 specular = light.color * light.specular * spec * vec3(texture(material.specular_Texture, v_TexCoord));
specular *= attenuation ;
return (ambient + diffuse + specular);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
vec3 lightDir = normalize(constVal.camera_Position - fragPos);
float diff = max(dot(normal, lightDir), 0.0);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
float distance = length(constVal.camera_Position - fragPos);
float attenuation = 1.0 / (constVal.constant + constVal.linear * distance + constVal.quadratic * (distance * distance));
float theta = dot(lightDir, normalize(-constVal.camera_Direction));
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
vec3 ambient = light.ambient * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
vec3 diffuse = light.diffuse * diff * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
vec3 specular = light.specular * spec * vec3(texture(material.specular_Texture, v_TexCoord));
ambient *= attenuation * intensity;
diffuse *= attenuation * intensity;
specular *= attenuation * intensity;
return (ambient + diffuse + specular);