From 54c16a561d077d09b56c57ddf728b364fc255991 Mon Sep 17 00:00:00 2001 From: iurii Date: Sun, 8 Sep 2024 02:41:19 +0300 Subject: more lights --- res/shaders/colors.fs | 137 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 23 deletions(-) (limited to 'res/shaders') diff --git a/res/shaders/colors.fs b/res/shaders/colors.fs index 228f555..d10e45a 100644 --- a/res/shaders/colors.fs +++ b/res/shaders/colors.fs @@ -14,6 +14,7 @@ struct Light { vec3 direction; float cutOff; + float outerCutOff; vec3 ambient; vec3 diffuse; @@ -32,37 +33,127 @@ uniform vec3 view_position; uniform Material material; uniform Light light; -void main() { - vec3 light_dir = normalize(light.position - FragPos); - float theta = dot(light_dir, normalize(-light.direction)); +struct DirLight { + vec3 direction; - if (theta > light.cutOff) { - // ambient - vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; +uniform DirLight dirLight; - // diffuse - vec3 norm = normalize(Normal); - float diff = max(dot(norm, light_dir), 0.0); - vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; +struct PointLight { + vec3 position; - // specular - vec3 view_dir = normalize(view_position - FragPos); - vec3 reflect_dir = reflect(-light_dir, norm); - float spec = pow(max(dot(view_dir, reflect_dir), 0.0), material.shininess); - vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; + float constant; + float linear; + float quadratic; - float distance = length(light.position - FragPos); - float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; +#define NR_POINT_LIGHTS 4 +uniform PointLight pointLights[NR_POINT_LIGHTS]; - diffuse *= attenuation; - specular *= attenuation; +struct SpotLight { + vec3 position; + vec3 direction; + + float cutOff; + float outerCutOff; + + float constant; + float linear; + float quadratic; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; +uniform SpotLight spotLight; + +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); + +void main() +{ + vec3 norm = normalize(Normal); + vec3 viewDir = normalize(view_position - FragPos); + + vec3 result = CalcDirLight(dirLight, norm, viewDir); - vec3 result = ambient + diffuse + specular; - FragColor = vec4(result, 1.0); - } else { - FragColor = vec4(light.ambient * texture(material.diffuse, TexCoords).rgb, 1.0); + for (int i = 0; i < NR_POINT_LIGHTS; i++) { + result += CalcPointLight(pointLights[i], norm, FragPos, viewDir); } + result += CalcSpotLight(spotLight, norm, FragPos, viewDir); + FragColor = vec4(result, 1.0); +} + +// calculates the color when using a directional light. +vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir) +{ + vec3 lightDir = normalize(-light.direction); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + // combine results + vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); + return (ambient + diffuse + specular); +} + +// calculates the color when using a point light. +vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + // combine results + vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); + ambient *= attenuation; + diffuse *= attenuation; + specular *= attenuation; + return (ambient + diffuse + specular); +} + +// calculates the color when using a spot light. +vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + // spotlight intensity + float theta = dot(lightDir, normalize(-light.direction)); + float epsilon = light.cutOff - light.outerCutOff; + float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); + // combine results + vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); + ambient *= attenuation * intensity; + diffuse *= attenuation * intensity; + specular *= attenuation * intensity; + return (ambient + diffuse + specular); } -- cgit 1.4.1-2-gfad0