Play with lights

This commit is contained in:
Abdelrahman Said 2024-12-22 01:36:08 +00:00
parent e720355d04
commit b7e5eea448
2 changed files with 61 additions and 30 deletions

View File

@ -8,9 +8,12 @@ struct Material {
struct Light { struct Light {
vec3 position; vec3 position;
vec3 direction;
vec3 ambient; vec3 ambient;
vec3 diffuse; vec3 diffuse;
vec3 specular; vec3 specular;
float cutoff;
float outer_cutoff;
}; };
in vec3 vert_normal; in vec3 vert_normal;
@ -28,14 +31,17 @@ void main() {
float specular_strength = 0.5; float specular_strength = 0.5;
vec3 normal = normalize(vert_normal); 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 view_direction = normalize(camera_position - frag_position);
vec3 reflect_direction = reflect(-light_direction, normal); vec3 reflect_direction = reflect(-light_direction, normal);
float diff = max(dot(normal, light_direction), 0.0); float diff = max(dot(normal, light_direction), 0.0);
float spec = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess); float spec = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess);
vec3 diff_tex = vec3(texture(material.diffuse, uv_coords)); vec3 diff_tex = vec3(texture(material.diffuse, uv_coords));
vec3 ambient = light.ambient * diff_tex; vec3 ambient = light.ambient * diff_tex;
vec3 diffuse = light.diffuse * (diff * diff_tex); vec3 diffuse = light.diffuse * (diff * diff_tex) * intensity;
vec3 specular = light.specular * (spec * vec3(texture(material.specular, uv_coords))); vec3 specular = light.specular * (spec * vec3(texture(material.specular, uv_coords))) * intensity;
color = vec4(ambient + diffuse + specular, 1.0); color = vec4(ambient + diffuse + specular, 1.0);
}; };

View File

@ -56,6 +56,7 @@ class Shader {
void set_int(const char *name, int value); void set_int(const char *name, int value);
void set_float(const char *name, float value); void set_float(const char *name, float value);
void set_vec3(const char *name, glm::vec3 vector); 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_mat3(const char *name, glm::mat3 matrix);
void set_mat4(const char *name, glm::mat4 matrix); void set_mat4(const char *name, glm::mat4 matrix);
GLuint program; GLuint program;
@ -204,8 +205,8 @@ int main() {
glm::vec3 camera_position = glm::vec3(-2.0f, 0.0f, 6.0f); glm::vec3 camera_position = glm::vec3(-2.0f, 0.0f, 6.0f);
glm::vec3 camera_forward = glm::vec3(0.0f); glm::vec3 camera_forward = glm::vec3(0.0f);
glm::vec3 world_up = glm::vec3(0.0f, 1.0f, 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_pos_dir = glm::vec3(1.0f, 0.5f, 0.0f);
glm::vec3 light_diffuse = glm::vec3(0.5f, 0.5f, 0.5f); glm::vec3 light_diffuse = glm::vec3(0.75f, 0.75f, 0.75f);
float yaw = -70.0f; float yaw = -70.0f;
float pitch = 0.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.ambient", glm::vec3(0.2f, 0.2f, 0.2f));
main_shader.set_vec3 ("light.diffuse", light_diffuse); 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_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); light_shader.set_mat4("projection", projection);
const float light_radius = 3.0f; std::vector<glm::vec3> 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; const float sensitivity = 0.1f;
int last_mouse_x = WINDOW_HALF_WIDTH; int last_mouse_x = WINDOW_HALF_WIDTH;
int last_mouse_y = WINDOW_HALF_HEIGHT; int last_mouse_y = WINDOW_HALF_HEIGHT;
@ -236,12 +253,7 @@ int main() {
uint32_t ticks = SDL_GetTicks(); uint32_t ticks = SDL_GetTicks();
float seconds = ticks * 0.001f; float seconds = ticks * 0.001f;
delta = (ticks - last_frame) * 0.001f; delta = (ticks - last_frame) * 0.001f;
light_position = glm::vec3(sin(seconds) * light_radius, light_position.y, cos(seconds) * light_radius); light_pos_dir = glm::vec3(sin(seconds) * light_radius, light_pos_dir.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)
);
last_frame = ticks; last_frame = ticks;
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
@ -306,16 +318,22 @@ int main() {
view = glm::lookAt(camera_position, camera_position + camera_forward, world_up); view = glm::lookAt(camera_position, camera_position + camera_forward, world_up);
main_shader.set_vec3("camera_position", camera_position); 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); main_shader.set_mat4("view", view);
light_shader.set_mat4("view", view); light_shader.set_mat4("view", view);
glClearColor(0.04f, 0.08f, 0.08f, 1.0f); glClearColor(0.04f, 0.08f, 0.08f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)); 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)); normal_mat = glm::transpose(glm::inverse(model));
main_shader.activate(); main_shader.activate();
main_shader.set_vec3("light.position", light_position); 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_vec3("light.diffuse", light_diffuse);
main_shader.set_mat4("model", model); main_shader.set_mat4("model", model);
main_shader.set_mat3("normal_mat", normal_mat); main_shader.set_mat3("normal_mat", normal_mat);
@ -323,14 +341,16 @@ int main() {
specular_map.activate(); specular_map.activate();
glBindVertexArray(vao); glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0);
}
model = glm::translate(glm::mat4(1.0f), light_position); // Draw light source
model = glm::scale(model, glm::vec3(0.2f)); // model = glm::translate(glm::mat4(1.0f), glm::vec3(light_pos_dir));
light_shader.activate(); // model = glm::scale(model, glm::vec3(0.2f));
light_shader.set_mat4("model", model); // light_shader.activate();
light_shader.set_vec3("light_diffuse", light_diffuse); // light_shader.set_mat4("model", model);
glBindVertexArray(light_vao); // light_shader.set_vec3("light_diffuse", light_diffuse);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); // glBindVertexArray(light_vao);
// glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0);
SDL_GL_SwapWindow(window); 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); 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) { void Shader::set_mat3(const char *name, glm::mat3 matrix) {
activate(); activate();
glUniformMatrix3fv(glGetUniformLocation(program, name), 1, GL_FALSE, glm::value_ptr(matrix)); glUniformMatrix3fv(glGetUniformLocation(program, name), 1, GL_FALSE, glm::value_ptr(matrix));