From b7e5eea448e5383a39b713dfbfa5601c63a1d28e Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 22 Dec 2024 01:36:08 +0000 Subject: [PATCH] Play with lights --- shaders/frag.glsl | 12 +++++-- src/main.cc | 79 +++++++++++++++++++++++++++++++---------------- 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/shaders/frag.glsl b/shaders/frag.glsl index 4a6b971..2750366 100644 --- a/shaders/frag.glsl +++ b/shaders/frag.glsl @@ -8,9 +8,12 @@ struct Material { struct Light { vec3 position; + vec3 direction; vec3 ambient; vec3 diffuse; vec3 specular; + float cutoff; + float outer_cutoff; }; in vec3 vert_normal; @@ -27,15 +30,18 @@ void main() { float ambient_strength = 0.15; float specular_strength = 0.5; vec3 normal = normalize(vert_normal); - vec3 light_direction = normalize(light.position - frag_position); + vec3 light_direction = normalize(light.position - frag_position); + float theta = dot(light_direction, normalize(-light.direction)); + float epsilon = light.cutoff - light.outer_cutoff; + float intensity = clamp((theta - light.outer_cutoff) / epsilon, 0.0, 1.0); vec3 view_direction = normalize(camera_position - frag_position); vec3 reflect_direction = reflect(-light_direction, normal); float diff = max(dot(normal, light_direction), 0.0); float spec = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); vec3 diff_tex = vec3(texture(material.diffuse, uv_coords)); vec3 ambient = light.ambient * diff_tex; - vec3 diffuse = light.diffuse * (diff * diff_tex); - vec3 specular = light.specular * (spec * vec3(texture(material.specular, uv_coords))); + vec3 diffuse = light.diffuse * (diff * diff_tex) * intensity; + vec3 specular = light.specular * (spec * vec3(texture(material.specular, uv_coords))) * intensity; color = vec4(ambient + diffuse + specular, 1.0); }; diff --git a/src/main.cc b/src/main.cc index 2d75f87..598230e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -56,6 +56,7 @@ class Shader { void set_int(const char *name, int value); void set_float(const char *name, float value); void set_vec3(const char *name, glm::vec3 vector); + void set_vec4(const char *name, glm::vec4 vector); void set_mat3(const char *name, glm::mat3 matrix); void set_mat4(const char *name, glm::mat4 matrix); GLuint program; @@ -204,8 +205,8 @@ int main() { glm::vec3 camera_position = glm::vec3(-2.0f, 0.0f, 6.0f); glm::vec3 camera_forward = glm::vec3(0.0f); glm::vec3 world_up = glm::vec3(0.0f, 1.0f, 0.0f); - glm::vec3 light_position = glm::vec3(1.0f, 0.5f, 0.0f); - glm::vec3 light_diffuse = glm::vec3(0.5f, 0.5f, 0.5f); + glm::vec3 light_pos_dir = glm::vec3(1.0f, 0.5f, 0.0f); + glm::vec3 light_diffuse = glm::vec3(0.75f, 0.75f, 0.75f); float yaw = -70.0f; float pitch = 0.0f; @@ -221,9 +222,25 @@ int main() { main_shader.set_vec3 ("light.ambient", glm::vec3(0.2f, 0.2f, 0.2f)); main_shader.set_vec3 ("light.diffuse", light_diffuse); main_shader.set_vec3 ("light.specular", glm::vec3(1.0f, 1.0f, 1.0f)); + main_shader.set_float("light.constant", 1.0f); + main_shader.set_float("light.linear", 0.07f); + main_shader.set_float("light.quadratic", 0.017f); light_shader.set_mat4("projection", projection); - const float light_radius = 3.0f; + std::vector cube_positions = { + glm::vec3( 0.0f, 0.0f, 0.0f), + glm::vec3( 4.0f, 6.0f, -15.0f), + glm::vec3(-3.5f, -3.2f, -2.5f), + glm::vec3(-5.8f, -3.0f, -12.3f), + glm::vec3( 4.4f, -1.4f, -3.5f), + glm::vec3(-3.7f, 4.0f, -7.5f), + glm::vec3( 3.3f, -3.0f, -2.5f), + glm::vec3( 3.5f, 3.0f, -2.5f), + glm::vec3( 3.5f, 1.2f, -1.5f), + glm::vec3(-3.3f, 2.0f, -1.5f) + }; + + const float light_radius = 6.0f; const float sensitivity = 0.1f; int last_mouse_x = WINDOW_HALF_WIDTH; int last_mouse_y = WINDOW_HALF_HEIGHT; @@ -236,12 +253,7 @@ int main() { uint32_t ticks = SDL_GetTicks(); float seconds = ticks * 0.001f; delta = (ticks - last_frame) * 0.001f; - light_position = glm::vec3(sin(seconds) * light_radius, light_position.y, cos(seconds) * light_radius); - light_diffuse = glm::vec3( - clamp(sin(seconds * 3.0f) + 1.0f, 0.0f, 1.0f), - clamp(cos(seconds * 8.0f) + 1.0f, 0.0f, 1.0f), - clamp(tan(seconds * 5.0f) + 3.0f, 0.0f, 1.0f) - ); + light_pos_dir = glm::vec3(sin(seconds) * light_radius, light_pos_dir.y, cos(seconds) * light_radius); last_frame = ticks; while (SDL_PollEvent(&event)) { @@ -306,31 +318,39 @@ int main() { view = glm::lookAt(camera_position, camera_position + camera_forward, world_up); main_shader.set_vec3("camera_position", camera_position); + main_shader.set_vec3("light.position", camera_position); + main_shader.set_vec3("light.direction", camera_forward); + main_shader.set_float("light.cutoff", glm::cos(glm::radians(12.5))); + main_shader.set_float("light.outer_cutoff", glm::cos(glm::radians(17.5))); main_shader.set_mat4("view", view); light_shader.set_mat4("view", view); glClearColor(0.04f, 0.08f, 0.08f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)); - normal_mat = glm::transpose(glm::inverse(model)); - main_shader.activate(); - main_shader.set_vec3("light.position", light_position); - main_shader.set_vec3("light.diffuse", light_diffuse); - main_shader.set_mat4("model", model); - main_shader.set_mat3("normal_mat", normal_mat); - diffuse_map.activate(); - specular_map.activate(); - glBindVertexArray(vao); - glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); + for (int i = 0; i < cube_positions.size(); ++i) { + model = glm::translate(glm::mat4(1.0f), cube_positions[i]); + model = glm::rotate(model, glm::radians(10.0f * i), glm::vec3(1.0f, 0.3f, 0.5f)); + normal_mat = glm::transpose(glm::inverse(model)); + main_shader.activate(); + main_shader.set_vec4("light.pos_dir", glm::vec4(light_pos_dir, 1.0f)); + main_shader.set_vec3("light.diffuse", light_diffuse); + main_shader.set_mat4("model", model); + main_shader.set_mat3("normal_mat", normal_mat); + diffuse_map.activate(); + specular_map.activate(); + glBindVertexArray(vao); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); + } - model = glm::translate(glm::mat4(1.0f), light_position); - model = glm::scale(model, glm::vec3(0.2f)); - light_shader.activate(); - light_shader.set_mat4("model", model); - light_shader.set_vec3("light_diffuse", light_diffuse); - glBindVertexArray(light_vao); - glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); + // Draw light source + // model = glm::translate(glm::mat4(1.0f), glm::vec3(light_pos_dir)); + // model = glm::scale(model, glm::vec3(0.2f)); + // light_shader.activate(); + // light_shader.set_mat4("model", model); + // light_shader.set_vec3("light_diffuse", light_diffuse); + // glBindVertexArray(light_vao); + // glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); SDL_GL_SwapWindow(window); } @@ -378,6 +398,11 @@ void Shader::set_vec3(const char *name, glm::vec3 vector) { glUniform3f(glGetUniformLocation(program, name), vector.x, vector.y, vector.z); } +void Shader::set_vec4(const char *name, glm::vec4 vector) { + activate(); + glUniform4f(glGetUniformLocation(program, name), vector.x, vector.y, vector.z, vector.w); +} + void Shader::set_mat3(const char *name, glm::mat3 matrix) { activate(); glUniformMatrix3fv(glGetUniformLocation(program, name), 1, GL_FALSE, glm::value_ptr(matrix));