aboutsummaryrefslogtreecommitdiff
path: root/shaders/color.fsh
diff options
context:
space:
mode:
authorjvech <jmvalenciae@unal.edu.co>2022-09-16 16:21:37 -0500
committerjvech <jmvalenciae@unal.edu.co>2022-09-16 16:21:37 -0500
commitfc8d7fed3ccdf0998a7b9809aa825f2d14876b29 (patch)
tree45d1b4ff6435e79939be1198316e7973ab5695bb /shaders/color.fsh
parent6781af306edc8f6b0928013ed9ec2fa87d63da81 (diff)
learn: 17. Multiple lights
Diffstat (limited to 'shaders/color.fsh')
-rw-r--r--shaders/color.fsh127
1 files changed, 114 insertions, 13 deletions
diff --git a/shaders/color.fsh b/shaders/color.fsh
index c2a8dc7..a0958ed 100644
--- a/shaders/color.fsh
+++ b/shaders/color.fsh
@@ -1,4 +1,5 @@
-# version 330 core
+#version 330 core
+#define NR_POINT_LIGHTS 4
struct Material {
sampler2D diffuse;
@@ -6,13 +7,41 @@ struct Material {
float shininess;
};
-struct Light {
+struct DirLight {
+ vec3 direction;
+
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+};
+
+struct PointLight {
vec3 position;
+
+ float constant;
+ float linear;
+ float quadratic;
+
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
+struct FlashLight {
+ vec3 position;
+ vec3 direction;
+
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+
+ float cutOff;
+ float outerCutOff;
+ float constant;
+ float linear;
+ float quadratic;
+};
+
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoords;
@@ -21,24 +50,96 @@ out vec4 FragColor;
uniform vec3 viewPos;
uniform Material material;
-uniform Light light;
+uniform DirLight dirLight;
+uniform PointLight pointLight[NR_POINT_LIGHTS];
+uniform FlashLight flashLight;
-void main()
+vec3 calcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
- // ambient
+ vec3 lightDir = normalize(-light.direction);
+ // diffuse
+ float diff = max(dot(normal, lightDir), 0.0);
+ // specular
+ vec3 reflectDir = reflect(-lightDir, normal);
+ float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
+
vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb;
-
+ vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb;
+ vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb;
+
+ return (ambient + diffuse + specular);
+}
+
+vec3 calcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
+{
+ vec3 lightDir = normalize(light.position - fragPos);
// diffuse
- vec3 norm = normalize(Normal);
- vec3 lightDir = normalize(light.position - FragPos);
- float diff = max(dot(norm, lightDir), 0.0);
+ float diff = max(dot(normal, lightDir), 0.0);
+
+ //specular
+ vec3 reflectDir = reflect(-lightDir, normal);
+ float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
+
+ //attenuation
+ float dist = length(light.position - fragPos);
+ float attenuation = 1.0 / (light.constant + light.linear * dist +
+ light.quadratic * (dist * dist));
+
+ vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb;
vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb;
+ vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb;
- // specular
- vec3 viewDir = normalize(viewPos - FragPos);
- vec3 reflectDir = reflect(-lightDir, norm);
+ ambient *= attenuation;
+ diffuse *= attenuation;
+ specular *= attenuation;
+
+ return ambient + diffuse + specular;
+}
+
+vec3 calcFlashLight(FlashLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
+{
+ vec3 lightDir = normalize(light.position - fragPos);
+ float theta = dot(lightDir, normalize(-light.direction));
+ float epsilon = light.cutOff - light.outerCutOff;
+ float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
+
+ // diffuse
+ float diff = max(dot(normal, lightDir), 0.0);
+
+ //specular
+ vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
+
+ //attenuation
+ float dist = length(light.position - fragPos);
+ float attenuation = 1.0 / (light.constant + light.linear * dist +
+ light.quadratic * (dist * dist));
+
+ vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb;
+ vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb;
vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb;
- FragColor = vec4((specular + ambient + diffuse), 1.0f);
+ diffuse *= attenuation * intensity;
+ specular *= attenuation * intensity;
+
+ return ambient + diffuse + specular;
+}
+
+void main()
+{
+ // properties
+ vec3 norm = normalize(Normal);
+ vec3 viewDir = normalize(viewPos - FragPos);
+
+ // 1. Directional light
+ vec3 result = calcDirLight(dirLight, norm, viewDir);
+
+ // 2. Point lights
+ for (int i = 0; i < NR_POINT_LIGHTS; i++)
+ result += calcPointLight(pointLight[i], norm, FragPos, viewDir);
+
+ // 3. Spot light
+ result += calcFlashLight(flashLight, norm, FragPos, viewDir);
+
+ FragColor = vec4(result, 1.0);
}
Feel free to download, copy and edit any repo