summaryrefslogtreecommitdiff
path: root/source/shaders/light_subject.fs.glsl
blob: aa3cf36fee27977b09172e07d3b369436c9e972a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#version 330 core

struct Material {
  sampler2D diffuse;
  sampler2D specular;
  float shininess;
};

struct Light {
  vec3 ambient;
  vec3 diffuse;
  vec3 specular;

  vec3 position;
};

struct DirectionalLight {
  vec3 direction;

  vec3 ambient;
  vec3 diffuse;
  vec3 specular;
};

struct PointLight {
  vec3 position;

  vec3 ambient;
  vec3 diffuse;
  vec3 specular;

  // attentuation factors
  float kC;
  float kL;
  float kQ;
};

in vec2 texCoords;
in vec3 fragNormal;
in vec3 worldPosition;

uniform Material  material;
uniform Light     light;
uniform DirectionalLight dirLight;
uniform PointLight pointLight;
uniform vec3			cameraPosition;
uniform vec3      lightColor;

out vec4 FragColor;

void main() {
     float lightDistance = length(pointLight.position - worldPosition);
     float attenuationFactor = 1.0 / 
     (pointLight.kC + (pointLight.kL * lightDistance) + (pointLight.kQ * lightDistance * lightDistance));

		 vec3 ambientLight = attenuationFactor * pointLight.ambient * vec3(texture(material.diffuse, texCoords));

//	 @note: Diffuse calculations
     //vec3 lightDir = normalize(light.position - worldPosition);
     /*
     @note: an explanation of why the light direction vector is taken from fragment to the 
     light source.
     Basic LA really, we need to calculate the angle between the direction of the 2 vectors:
      a. The direction at which light incidents with the fragment
      b. The normal vector
     The reason the light direction is taken from the fragment to the light source, is precisely so we can calculate
     the angle between the normal and the direction at which light would hit. This if taken as starting from the light
     source would actually be incorrect, since we would be calculating the angle between the light source in the direction
     of the fragment and the normal. Consider what happens when it is directly above. The angle becomes 180, not 0. This 
     is because the normal moves in the direction opposite to the lights direction if taken this way, which is not what
     we expect or want.
     Reversing this, allows us to consider the angle at the point in which light hits the fragment, and the normal vector
     of the fragment. 
     */
     vec3 lightDir = normalize(pointLight.position - worldPosition);
     float diffuseStrength = max(dot(lightDir, fragNormal), 0.0);
     vec3 diffuseLight = attenuationFactor * pointLight.diffuse * diffuseStrength * vec3(texture(material.diffuse, texCoords));

//	 @note: Specular calculations
		 vec3  viewDir		      = normalize(cameraPosition - worldPosition);
		 vec3  reflectDir				= reflect(-lightDir, fragNormal);
		 float specularity			= max(dot(viewDir, reflectDir), 0.0);
		 float shinePower				= pow(specularity, material.shininess);
		 vec3  specularLight		= attenuationFactor * pointLight.specular * shinePower * vec3(texture(material.specular, texCoords));

     vec3 color = ambientLight + diffuseLight + specularLight;
     FragColor = vec4(color, 1.0);
}