summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/main.cpp165
-rw-r--r--source/shaders/light_subject.fs.glsl178
2 files changed, 265 insertions, 78 deletions
diff --git a/source/main.cpp b/source/main.cpp
index 94974e5..1562ed1 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -780,40 +780,108 @@ int main(int argc, char* argv[])
int shine_factor_loc = glGetUniformLocation(shader_program, "material.shininess");
glUniform1f(shine_factor_loc, specular_shine_factor);
- // light uniforms
- Vec3 light_location = Vec3{ 0.0f, 0.0f, 3.0f };
- Vec3 light_direction = Vec3{ -0.0f, -0.0f, -0.3f };
- Vec3 light_ambient = Vec3{ 0.2f, 0.2f, 0.2f };
- Vec3 light_diffuse = Vec3{ 0.5f, 0.5f, 0.5f };
- Vec3 light_specular = Vec3{ 1.0f, 1.0f, 1.0f };
-
- int light_ambient_loc = glGetUniformLocation(shader_program, "pointLight.ambient");
- glUniform3fv(light_ambient_loc, 1, light_ambient.data);
-
- int light_diffuse_loc = glGetUniformLocation(shader_program, "pointLight.diffuse");
- glUniform3fv(light_diffuse_loc, 1, light_diffuse.data);
-
- int light_specular_loc = glGetUniformLocation(shader_program, "pointLight.specular");
- glUniform3fv(light_specular_loc, 1, light_diffuse.data);
-
- int light_pos_loc = glGetUniformLocation(shader_program, "pointLight.position");
- glUniform3fv(light_pos_loc, 1, light_location.data);
-
+ // directional light things
+ // - directional light params
+ Vec3 DL_direction = Vec3{ 0.0f, -1.0f, 0.0f };
+ Vec3 DL_ambient = Vec3{ 0.2f, 0.2f, 0.2f };
+ Vec3 DL_diffuse = Vec3{ 0.5f, 0.5f, 0.5f };
+ Vec3 DL_specular = Vec3{ 1.0f, 1.0f, 1.0f };
+
+ int DL_ambient_loc = glGetUniformLocation(shader_program, "dirLight.ambient");
+ int DL_diffuse_loc = glGetUniformLocation(shader_program, "dirLight.diffuse");
+ int DL_specular_loc = glGetUniformLocation(shader_program, "dirLight.specular");
+ int DL_dir_loc = glGetUniformLocation(shader_program, "dirLight.direction");
+
+ glUniform3fv(DL_dir_loc, 1, DL_direction.data);
+ glUniform3fv(DL_ambient_loc, 1, DL_ambient.data);
+ glUniform3fv(DL_diffuse_loc, 1, DL_diffuse.data);
+ glUniform3fv(DL_specular_loc, 1, DL_specular.data);
+
+ // pointlight things
+ // - point light params
+ Vec3 MPL_position[4] = {
+ Vec3{ 0.0f, 0.0f, 5.0f },
+ Vec3{ 0.0f, 0.0f, -8.0f },
+ Vec3{ -5.0f, 0.0f, -5.0f },
+ Vec3{ 5.0f, 0.0f, -5.0f },
+ };
+ Vec3 MPL_ambient[4] = {
+ Vec3{ 0.2f, 0.2f, 0.2f },
+ Vec3{ 0.2f, 0.2f, 0.2f },
+ Vec3{ 0.2f, 0.2f, 0.2f },
+ Vec3{ 0.2f, 0.2f, 0.2f }
+ };
+ Vec3 MPL_diffuse[4] = {
+ Vec3{ 0.5f, 0.5f, 0.5f },
+ Vec3{ 0.5f, 0.5f, 0.5f },
+ Vec3{ 0.5f, 0.5f, 0.5f },
+ Vec3{ 0.5f, 0.5f, 0.5f }
+ };
+ Vec3 MPL_specular[4] = {
+ Vec3{ 1.0f, 1.0f, 1.0f },
+ Vec3{ 1.0f, 1.0f, 1.0f },
+ Vec3{ 1.0f, 1.0f, 1.0f },
+ Vec3{ 1.0f, 1.0f, 1.0f }
+ };
+
+ for (int i=0; i < 4; i++)
+ {
+ char buffer[64];
+ sprintf(buffer, "multiPointLight[%i].ambient", i);
+ int MPL_ambient_loc = glGetUniformLocation(shader_program, buffer);
+ sprintf(buffer, "multiPointLight[%i].diffuse", i);
+ int MPL_diffuse_loc = glGetUniformLocation(shader_program, buffer);
+ sprintf(buffer, "multiPointLight[%i].specular", i);
+ int MPL_specular_loc = glGetUniformLocation(shader_program, buffer);
+ sprintf(buffer, "multiPointLight[%i].position", i);
+ int MPL_pos_loc = glGetUniformLocation(shader_program, buffer);
+ sprintf(buffer, "multiPointLight[%i].kC", i);
+ int MPL_kc_loc = glGetUniformLocation(shader_program, buffer);
+ sprintf(buffer, "multiPointLight[%i].kL", i);
+ int MPL_kl_loc = glGetUniformLocation(shader_program, buffer);
+ sprintf(buffer, "multiPointLight[%i].kQ", i);
+ int MPL_kq_loc = glGetUniformLocation(shader_program, buffer);
+
+ glUniform3fv(MPL_pos_loc, 1, MPL_position[i].data);
+ glUniform3fv(MPL_ambient_loc, 1, MPL_ambient[i].data);
+ glUniform3fv(MPL_diffuse_loc, 1, MPL_diffuse[i].data);
+ glUniform3fv(MPL_specular_loc, 1, MPL_specular[i].data);
+ // attenuation factors
+ glUniform1f(MPL_kc_loc, 1.0f);
+ glUniform1f(MPL_kl_loc, 0.09f);
+ glUniform1f(MPL_kq_loc, 0.032f);
+ }
+
+
+
+ // spotlight things
+ // - spot light params
+ Vec3 SL_ambient = Vec3{ 0.2f, 0.2f, 0.2f };
+ Vec3 SL_diffuse = Vec3{ 0.5f, 0.5f, 0.5f };
+ Vec3 SL_specular = Vec3{ 1.0f, 1.0f, 1.0f };
+
+ int SL_ambient_loc = glGetUniformLocation(shader_program, "spotLight.ambient");
+ int SL_diffuse_loc = glGetUniformLocation(shader_program, "spotLight.diffuse");
+ int SL_specular_loc = glGetUniformLocation(shader_program, "spotLight.specular");
+ int SL_pos_loc = glGetUniformLocation(shader_program, "spotLight.position");
+ int SL_kc_loc = glGetUniformLocation(shader_program, "spotLight.kC");
+ int SL_kl_loc = glGetUniformLocation(shader_program, "spotLight.kL");
+ int SL_kq_loc = glGetUniformLocation(shader_program, "spotLight.kQ");
+ int SL_radius_inner = glGetUniformLocation(shader_program, "spotLight.radius_inner");
+ int SL_radius_outer = glGetUniformLocation(shader_program, "spotLight.radius_outer");
+ int SL_front_loc = glGetUniformLocation(shader_program, "spotLight.front");
+
+ glUniform3fv(SL_ambient_loc, 1, SL_ambient.data);
+ glUniform3fv(SL_diffuse_loc, 1, SL_diffuse.data);
+ glUniform3fv(SL_specular_loc, 1, SL_specular.data);
// attenuation factors
- int kc_loc = glGetUniformLocation(shader_program, "pointLight.kC");
- glUniform1f(kc_loc, 1.0f);
-
- int kl_loc = glGetUniformLocation(shader_program, "pointLight.kL");
- glUniform1f(kl_loc, 0.09f);
-
- int kq_loc = glGetUniformLocation(shader_program, "pointLight.kQ");
- glUniform1f(kq_loc, 0.032f);
- // texture uniforms
- //int smiling_loc = glGetUniformLocation(shader_program, "smilingTexture");
- //glUniform1i(smiling_loc, 0);
-
- //int container_loc = glGetUniformLocation(shader_program, "containerTexture");
- //glUniform1i(container_loc, 1);
+ glUniform1f(SL_kc_loc, 1.0f);
+ glUniform1f(SL_kl_loc, 0.09f);
+ glUniform1f(SL_kq_loc, 0.032f);
+ // radius
+ glUniform1f(SL_radius_inner, cosf(To_Radian(10.0f)));
+ glUniform1f(SL_radius_outer, cosf(To_Radian(15.00f)));
+ // end spotlight things
int light_uniform_loc = glGetUniformLocation(shader_program, "lightColor");
glUniform3fv(light_uniform_loc, 1, light_color.data);
@@ -824,7 +892,7 @@ int main(int argc, char* argv[])
// objects
Vec3 model_translations[] = {
Vec3{ 0.0, 0.0, 0.0},
- Vec3{ -1.0, -1.0, -2.0},
+ Vec3{ -1.0, 0.0, -2.0},
Vec3{ 2.0, 0.0, -5.0},
Vec3{ -3.0, 5.0, -6.0},
Vec3{ 3.0, -7.0, -6.0},
@@ -859,14 +927,8 @@ int main(int argc, char* argv[])
glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer);
glUseProgram(light_sp);
- Mat4 light_model = translation_matrix4m(light_location.x, light_location.y, light_location.z);
-
- uint32_t light_model_loc = glGetUniformLocation(light_sp, "Model");
- glUniformMatrix4fv(light_model_loc, 1, GL_TRUE, light_model.buffer);
-
uint32_t light_view_loc = glGetUniformLocation(light_sp, "View");
glUniformMatrix4fv(light_view_loc, 1, GL_TRUE, view.buffer);
-
uint32_t light_proj_loc = glGetUniformLocation(light_sp, "Projection");
glUniformMatrix4fv(light_proj_loc, 1, GL_TRUE, proj.buffer);
@@ -1004,22 +1066,27 @@ int main(int argc, char* argv[])
}
// light_location.z = 10.00 * sinf(time_curr/10.0);
view = camera_create4m(camera_pos, add3v(camera_pos, camera_look), preset_up_dir);
+
// object shader program stuff
glUseProgram(shader_program);
- //glUniform1f(shine_factor_loc, specular_shine_factor);
+
+ // Update spot light params
+ glUniform3fv(SL_pos_loc, 1, camera_pos.data);
+ glUniform3fv(SL_front_loc, 1, camera_look.data);
glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer);
glUniform3fv(camera_pos_loc, 1, camera_pos.data);
// light/lamp shader program stuff
- glUseProgram(light_sp);
- glUniformMatrix4fv(light_view_loc, 1, GL_TRUE, view.buffer);
+ //glUseProgram(light_sp);
+ //glUniformMatrix4fv(light_view_loc, 1, GL_TRUE, view.buffer);
time_prev = time_curr;
// OUTPUT
- glClearColor(1.0f, 0.6f, .6f, 1.0f);
+ //glClearColor(1.0f, 0.6f, .6f, 1.0f);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glActiveTexture(GL_TEXTURE1);
@@ -1027,7 +1094,15 @@ int main(int argc, char* argv[])
glUseProgram(light_sp);
glBindVertexArray(light_VAO);
- glDrawArrays(GL_TRIANGLES, 0, 36);
+ for (int i = 0; i < 4; i++)
+ {
+ Mat4 light_model = translation_matrix4m(MPL_position[i].x, MPL_position[i].y, MPL_position[i].z);
+ uint32_t light_model_loc = glGetUniformLocation(light_sp, "Model");
+ glUniformMatrix4fv(light_model_loc, 1, GL_TRUE, light_model.buffer);
+
+ glUniformMatrix4fv(light_view_loc, 1, GL_TRUE, view.buffer);
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+ }
glBindVertexArray(0);
glUseProgram(0);
diff --git a/source/shaders/light_subject.fs.glsl b/source/shaders/light_subject.fs.glsl
index aa3cf36..f3e1d58 100644
--- a/source/shaders/light_subject.fs.glsl
+++ b/source/shaders/light_subject.fs.glsl
@@ -1,5 +1,21 @@
#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;
@@ -35,53 +51,149 @@ struct PointLight {
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() {
- 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 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);