diff options
Diffstat (limited to 'source/lessons/lighting/shaders')
4 files changed, 236 insertions, 0 deletions
| diff --git a/source/lessons/lighting/shaders/light_source.fs.glsl b/source/lessons/lighting/shaders/light_source.fs.glsl new file mode 100644 index 0000000..9e834cb --- /dev/null +++ b/source/lessons/lighting/shaders/light_source.fs.glsl @@ -0,0 +1,5 @@ +#version 330 core +out vec4 FragColor; +void main() { +    FragColor = vec4(1.0); +} diff --git a/source/lessons/lighting/shaders/light_source.vs.glsl b/source/lessons/lighting/shaders/light_source.vs.glsl new file mode 100644 index 0000000..bf372d5 --- /dev/null +++ b/source/lessons/lighting/shaders/light_source.vs.glsl @@ -0,0 +1,10 @@ +#version 330 core +layout(location = 0) in vec3 position; + +uniform mat4 Model; +uniform mat4 View; +uniform mat4 Projection; + +void main() { +    gl_Position = Projection * View * Model * vec4(position.x, position.y, position.z, 1.0); +} diff --git a/source/lessons/lighting/shaders/light_subject.fs.glsl b/source/lessons/lighting/shaders/light_subject.fs.glsl new file mode 100644 index 0000000..f3e1d58 --- /dev/null +++ b/source/lessons/lighting/shaders/light_subject.fs.glsl @@ -0,0 +1,200 @@ +#version 330 core + +/* +@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.  +*/ + +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; +}; + +struct SpotLight { +  vec3 position; + +  vec3 ambient; +  vec3 diffuse; +  vec3 specular; + +  // attenuation factors +  float kC; +  float kL; +  float kQ; + +  // vector for the direction directly in front of the spotlight +  vec3 front; + +  // spot radius +  float radius_inner; +  float radius_outer; // to smooth out the light + +}; + +// this is the result of a light creation. This contains the multipliers for each kind of a light we want +// to have. +struct LightFactor { +  vec3 ambient; +  vec3 diffuse; +  vec3 specular; +}; + +in vec2 texCoords; +in vec3 fragNormal; +in vec3 worldPosition; + +uniform Material  material; + +uniform Light     light; +uniform DirectionalLight dirLight; +uniform PointLight pointLight; +uniform PointLight multiPointLight[4]; +uniform SpotLight spotLight; + +uniform vec3			cameraPosition; +uniform vec3      lightColor; + +out vec4 FragColor; + +LightFactor make_directional_light(DirectionalLight light, vec3 CONST_viewDir) { +  LightFactor res; + +  vec3 DL_lightDir = normalize(-light.direction); +  res.ambient = light.ambient; + +  float DL_diffuseStrength = max(dot(DL_lightDir, fragNormal), 0.0); +  res.diffuse = light.diffuse * DL_diffuseStrength; + +  vec3  DL_reflectDir	    = reflect(-DL_lightDir, fragNormal); +  float DL_specularity		= max(dot(CONST_viewDir, DL_reflectDir), 0.0); +  float DL_shinePower			= pow(DL_specularity, material.shininess); +  res.specular	= light.specular * DL_shinePower; + +  return res; +}; + +LightFactor make_point_light(PointLight light, vec3 CONST_viewDir) { +  LightFactor res; + +  float PL_lightDistance = length(light.position - worldPosition); +  float PL_attenuationFactor = 1.0 /  +  (light.kC + (light.kL * PL_lightDistance) + (light.kQ * PL_lightDistance * PL_lightDistance)); +  res.ambient = PL_attenuationFactor * light.ambient; + +  vec3 PL_lightDir = normalize(light.position - worldPosition); +  float PL_diffuseStrength = max(dot(PL_lightDir, fragNormal), 0.0); +  res.diffuse = PL_attenuationFactor * light.diffuse * PL_diffuseStrength; + +  vec3  PL_reflectDir		= reflect(-PL_lightDir, fragNormal); +  float PL_specularity	= max(dot(CONST_viewDir, PL_reflectDir), 0.0); +  float PL_shinePower		= pow(PL_specularity, material.shininess); +  res.specular		      = PL_attenuationFactor * PL_shinePower * light.specular; + +  return res; +} + +LightFactor make_spot_light(SpotLight light, vec3 CONST_viewDir) { +  LightFactor res; + +  float SL_lightDistance = length(light.position - worldPosition); +  float SL_attenuationFactor = 1.0 /  +  (light.kC + (light.kL * SL_lightDistance) + (light.kQ * SL_lightDistance * SL_lightDistance)); +  vec3 SL_lightDir = normalize(light.position - worldPosition); + +  res.ambient = SL_attenuationFactor * light.ambient; + +  float SL_diffAmount = dot(SL_lightDir, normalize(-light.front)); +  float SL_spotLightFadeFactor = clamp((SL_diffAmount - light.radius_outer)/(light.radius_inner - light.radius_outer), 0.0f, 1.0f); +  float SL_diffuseStrength = max(dot(SL_lightDir, fragNormal), 0.0); +  res.diffuse = SL_spotLightFadeFactor * SL_attenuationFactor * light.diffuse * SL_diffuseStrength; + +  vec3  SL_reflectDir		= reflect(-SL_lightDir, fragNormal); +  float SL_specularity	= max(dot(CONST_viewDir, SL_reflectDir), 0.0); +  float SL_shinePower		= pow(SL_specularity, material.shininess); +  res.specular		      = SL_spotLightFadeFactor * SL_attenuationFactor * SL_shinePower * light.specular; + +  return res; +} + +void main() { +     vec3  CONST_viewDir		  = normalize(cameraPosition - worldPosition); +     vec3 combinedAmbience = vec3(0.0); +     vec3 combinedDiffuse  = vec3(0.0); +     vec3 combinedSpecular = vec3(0.0); + +     // directional light calculations and stuff +     //LightFactor DL_factors = make_directional_light(dirLight, CONST_viewDir); +     //combinedAmbience += DL_factors.ambient; +     //combinedDiffuse += DL_factors.diffuse; +     //combinedSpecular += DL_factors.specular; + +     // pointlight calculations and stuff +     //LightFactor PL_factors = make_point_light(pointLight, CONST_viewDir); +     //combinedAmbience += PL_factors.ambient; +     //combinedDiffuse += PL_factors.diffuse; +     //combinedSpecular += PL_factors.specular; + +     // multiple point lights +     for (int i=0; i<4; i++) +     { +       PointLight pl = multiPointLight[i]; +       LightFactor MPL_factors = make_point_light(pl, CONST_viewDir); +       combinedAmbience += MPL_factors.ambient; +       combinedDiffuse += MPL_factors.diffuse; +       combinedSpecular += MPL_factors.specular; +     } + +     // spotlight calculations +     LightFactor SL_factors = make_spot_light(spotLight, CONST_viewDir); +     combinedAmbience += SL_factors.ambient; +     combinedDiffuse += SL_factors.diffuse; +     combinedSpecular += SL_factors.specular; + +     vec3 ambientLight  = combinedAmbience * vec3(texture(material.diffuse, texCoords)); +     vec3 diffuseLight  = combinedDiffuse  * vec3(texture(material.diffuse, texCoords)); +     vec3 specularLight = combinedSpecular * vec3(texture(material.specular, texCoords)); + +     vec3 color = ambientLight + diffuseLight + specularLight; +     FragColor = vec4(color, 1.0); +} diff --git a/source/lessons/lighting/shaders/light_subject.vs.glsl b/source/lessons/lighting/shaders/light_subject.vs.glsl new file mode 100644 index 0000000..49e58d8 --- /dev/null +++ b/source/lessons/lighting/shaders/light_subject.vs.glsl @@ -0,0 +1,21 @@ +#version 330 core + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec2 inTexCoords; + +uniform mat4 Model; +uniform mat4 View; +uniform mat4 Projection; + +out vec3 fragNormal; +out vec3 worldPosition; +out vec2 texCoords; + +void main() { +    gl_Position = Projection * View * Model * vec4(position, 1.0); +    worldPosition = vec3(Model * vec4(position, 1.0)); +    fragNormal = mat3(transpose(inverse(Model))) * normal; +		fragNormal = normalize(normal); +    texCoords = inTexCoords; +} | 
