Create a scene with multiple lights
This commit is contained in:
parent
b7e5eea448
commit
c65a3ba314
@ -1,12 +1,31 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#define POINT_LIGHT_COUNT 4
|
||||||
|
|
||||||
struct Material {
|
struct Material {
|
||||||
sampler2D diffuse;
|
sampler2D diffuse;
|
||||||
sampler2D specular;
|
sampler2D specular;
|
||||||
float shininess;
|
float shininess;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Light {
|
struct DirLight {
|
||||||
|
vec3 direction;
|
||||||
|
vec3 ambient;
|
||||||
|
vec3 diffuse;
|
||||||
|
vec3 specular;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PointLight {
|
||||||
|
vec3 position;
|
||||||
|
vec3 ambient;
|
||||||
|
vec3 diffuse;
|
||||||
|
vec3 specular;
|
||||||
|
float constant;
|
||||||
|
float linear;
|
||||||
|
float quadratic;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpotLight {
|
||||||
vec3 position;
|
vec3 position;
|
||||||
vec3 direction;
|
vec3 direction;
|
||||||
vec3 ambient;
|
vec3 ambient;
|
||||||
@ -23,19 +42,64 @@ in vec2 uv_coords;
|
|||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
uniform Material material;
|
uniform Material material;
|
||||||
uniform Light light;
|
uniform DirLight directional_light;
|
||||||
|
uniform PointLight point_lights[POINT_LIGHT_COUNT];
|
||||||
|
uniform SpotLight spot_light;
|
||||||
uniform vec3 camera_position;
|
uniform vec3 camera_position;
|
||||||
|
|
||||||
|
vec3 calc_dir_light(DirLight light, vec3 normal, vec3 view_direction);
|
||||||
|
vec3 calc_point_light(PointLight light, vec3 normal, vec3 frag_position, vec3 view_direction);
|
||||||
|
vec3 calc_spot_light(SpotLight light, vec3 normal, vec3 frag_position, vec3 view_direction);
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float ambient_strength = 0.15;
|
vec3 normal = normalize(vert_normal);
|
||||||
float specular_strength = 0.5;
|
vec3 view_direction = normalize(camera_position - frag_position);
|
||||||
vec3 normal = normalize(vert_normal);
|
|
||||||
|
vec3 result = calc_dir_light(directional_light, normal, view_direction);
|
||||||
|
|
||||||
|
for (int i = 0; i < POINT_LIGHT_COUNT; ++i) {
|
||||||
|
result += calc_point_light(point_lights[i], normal, frag_position, view_direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
result += calc_spot_light(spot_light, normal, frag_position, view_direction);
|
||||||
|
|
||||||
|
color = vec4(result, 1.0);
|
||||||
|
};
|
||||||
|
|
||||||
|
vec3 calc_dir_light(DirLight light, vec3 normal, vec3 view_direction) {
|
||||||
|
vec3 light_direction = normalize(-light.direction);
|
||||||
|
vec3 reflect_direction = reflect(-light_direction, normal);
|
||||||
|
float diff = max(dot(normal, light_direction), 0.0);
|
||||||
|
vec3 diff_tex = vec3(texture(material.diffuse, uv_coords));
|
||||||
|
float spec = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess);
|
||||||
|
vec3 ambient = light.ambient * diff_tex;
|
||||||
|
vec3 diffuse = light.diffuse * (diff * diff_tex);
|
||||||
|
vec3 specular = light.specular * (spec * vec3(texture(material.specular, uv_coords)));
|
||||||
|
|
||||||
|
return ambient + diffuse + specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 calc_point_light(PointLight light, vec3 normal, vec3 frag_position, vec3 view_direction) {
|
||||||
vec3 light_direction = normalize(light.position - frag_position);
|
vec3 light_direction = normalize(light.position - frag_position);
|
||||||
|
vec3 reflect_direction = reflect(-light_direction, normal);
|
||||||
|
float distance = length(light.position - frag_position);
|
||||||
|
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
|
||||||
|
float diff = max(dot(normal, light_direction), 0.0);
|
||||||
|
vec3 diff_tex = vec3(texture(material.diffuse, uv_coords));
|
||||||
|
float spec = pow(max(dot(reflect_direction, view_direction), 0.0), material.shininess);
|
||||||
|
vec3 ambient = light.ambient * diff_tex * attenuation;
|
||||||
|
vec3 diffuse = light.diffuse * (diff * diff_tex) * attenuation;
|
||||||
|
vec3 specular = light.specular * (spec * vec3(texture(material.specular, uv_coords))) * attenuation;
|
||||||
|
|
||||||
|
return ambient + diffuse + specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 calc_spot_light(SpotLight light, vec3 normal, vec3 frag_position, vec3 view_direction) {
|
||||||
|
vec3 light_direction = normalize(light.position - frag_position);
|
||||||
|
vec3 reflect_direction = reflect(-light_direction, normal);
|
||||||
float theta = dot(light_direction, normalize(-light.direction));
|
float theta = dot(light_direction, normalize(-light.direction));
|
||||||
float epsilon = light.cutoff - light.outer_cutoff;
|
float epsilon = light.cutoff - light.outer_cutoff;
|
||||||
float intensity = clamp((theta - light.outer_cutoff) / epsilon, 0.0, 1.0);
|
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 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));
|
||||||
@ -43,5 +107,5 @@ void main() {
|
|||||||
vec3 diffuse = light.diffuse * (diff * diff_tex) * intensity;
|
vec3 diffuse = light.diffuse * (diff * diff_tex) * intensity;
|
||||||
vec3 specular = light.specular * (spec * vec3(texture(material.specular, uv_coords))) * intensity;
|
vec3 specular = light.specular * (spec * vec3(texture(material.specular, uv_coords))) * intensity;
|
||||||
|
|
||||||
color = vec4(ambient + diffuse + specular, 1.0);
|
return ambient + diffuse + specular;
|
||||||
};
|
}
|
||||||
|
93
src/main.cc
93
src/main.cc
@ -205,8 +205,9 @@ 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_pos_dir = glm::vec3(1.0f, 0.5f, 0.0f);
|
glm::vec3 light_ambient = glm::vec3(0.2f, 0.2f, 0.2f);
|
||||||
glm::vec3 light_diffuse = glm::vec3(0.75f, 0.75f, 0.75f);
|
glm::vec3 light_diffuse = glm::vec3(0.75f, 0.75f, 0.75f);
|
||||||
|
glm::vec3 light_specular = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
float yaw = -70.0f;
|
float yaw = -70.0f;
|
||||||
float pitch = 0.0f;
|
float pitch = 0.0f;
|
||||||
@ -219,12 +220,7 @@ int main() {
|
|||||||
main_shader.set_mat4 ("projection", projection);
|
main_shader.set_mat4 ("projection", projection);
|
||||||
main_shader.set_vec3 ("material.specular", glm::vec3(0.5f, 0.5f, 0.5f));
|
main_shader.set_vec3 ("material.specular", glm::vec3(0.5f, 0.5f, 0.5f));
|
||||||
main_shader.set_float("material.shininess", 32.0f);
|
main_shader.set_float("material.shininess", 32.0f);
|
||||||
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);
|
light_shader.set_mat4("projection", projection);
|
||||||
|
|
||||||
std::vector<glm::vec3> cube_positions = {
|
std::vector<glm::vec3> cube_positions = {
|
||||||
@ -240,7 +236,60 @@ int main() {
|
|||||||
glm::vec3(-3.3f, 2.0f, -1.5f)
|
glm::vec3(-3.3f, 2.0f, -1.5f)
|
||||||
};
|
};
|
||||||
|
|
||||||
const float light_radius = 6.0f;
|
std::vector<glm::vec3> point_light_positions = {
|
||||||
|
glm::vec3( 0.7f, 0.2f, 2.0f),
|
||||||
|
glm::vec3( 2.3f, -3.3f, -4.0f),
|
||||||
|
glm::vec3(-4.0f, 2.0f, -12.0f),
|
||||||
|
glm::vec3( 0.0f, 0.0f, -3.0f)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup lights
|
||||||
|
main_shader.set_vec3("directional_light.direction", glm::vec3(-0.2f, -1.0f, -0.3f));
|
||||||
|
main_shader.set_vec3("directional_light.ambient", light_ambient);
|
||||||
|
main_shader.set_vec3("directional_light.diffuse", light_diffuse);
|
||||||
|
main_shader.set_vec3("directional_light.specular", light_specular);
|
||||||
|
|
||||||
|
main_shader.set_vec3("spot_light.ambient", light_ambient);
|
||||||
|
main_shader.set_vec3("spot_light.diffuse", light_diffuse);
|
||||||
|
main_shader.set_vec3("spot_light.specular", light_specular);
|
||||||
|
|
||||||
|
for (int i = 0; i < point_light_positions.size(); ++i) {
|
||||||
|
char base[256] = {0};
|
||||||
|
char position[512] = {0};
|
||||||
|
char ambient[512] = {0};
|
||||||
|
char diffuse[512] = {0};
|
||||||
|
char specular[512] = {0};
|
||||||
|
char constant[512] = {0};
|
||||||
|
char linear[512] = {0};
|
||||||
|
char quadratic[512] = {0};
|
||||||
|
|
||||||
|
snprintf(base, sizeof(base) - 1, "point_lights[%d]", i);
|
||||||
|
snprintf(position, sizeof(position) - 1, "%s.position", base);
|
||||||
|
snprintf(ambient, sizeof(ambient) - 1, "%s.ambient", base);
|
||||||
|
snprintf(diffuse, sizeof(diffuse) - 1, "%s.diffuse", base);
|
||||||
|
snprintf(specular, sizeof(specular) - 1, "%s.specular", base);
|
||||||
|
snprintf(constant, sizeof(constant) - 1, "%s.constant", base);
|
||||||
|
snprintf(linear, sizeof(linear) - 1, "%s.linear", base);
|
||||||
|
snprintf(quadratic, sizeof(quadratic) - 1, "%s.quadratic", base);
|
||||||
|
|
||||||
|
main_shader.set_vec3(position, point_light_positions[i]);
|
||||||
|
main_shader.set_vec3(ambient, light_ambient);
|
||||||
|
main_shader.set_vec3(diffuse, light_diffuse);
|
||||||
|
main_shader.set_vec3(specular, light_specular);
|
||||||
|
main_shader.set_float(constant, 1.0f);
|
||||||
|
main_shader.set_float(linear, 0.09f);
|
||||||
|
main_shader.set_float(quadratic, 0.032f);
|
||||||
|
|
||||||
|
memset(base, 0, sizeof(base));
|
||||||
|
memset(position, 0, sizeof(position));
|
||||||
|
memset(ambient, 0, sizeof(ambient));
|
||||||
|
memset(diffuse, 0, sizeof(diffuse));
|
||||||
|
memset(specular, 0, sizeof(specular));
|
||||||
|
memset(constant, 0, sizeof(constant));
|
||||||
|
memset(linear, 0, sizeof(linear));
|
||||||
|
memset(quadratic, 0, sizeof(quadratic));
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
@ -251,9 +300,7 @@ int main() {
|
|||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
uint32_t ticks = SDL_GetTicks();
|
uint32_t ticks = SDL_GetTicks();
|
||||||
float seconds = ticks * 0.001f;
|
|
||||||
delta = (ticks - last_frame) * 0.001f;
|
delta = (ticks - last_frame) * 0.001f;
|
||||||
light_pos_dir = glm::vec3(sin(seconds) * light_radius, light_pos_dir.y, cos(seconds) * light_radius);
|
|
||||||
last_frame = ticks;
|
last_frame = ticks;
|
||||||
|
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
@ -318,10 +365,10 @@ 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("spot_light.position", camera_position);
|
||||||
main_shader.set_vec3("light.direction", camera_forward);
|
main_shader.set_vec3("spot_light.direction", camera_forward);
|
||||||
main_shader.set_float("light.cutoff", glm::cos(glm::radians(12.5)));
|
main_shader.set_float("spot_light.cutoff", glm::cos(glm::radians(12.5)));
|
||||||
main_shader.set_float("light.outer_cutoff", glm::cos(glm::radians(17.5)));
|
main_shader.set_float("spot_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);
|
||||||
|
|
||||||
@ -333,8 +380,6 @@ int main() {
|
|||||||
model = glm::rotate(model, glm::radians(10.0f * i), glm::vec3(1.0f, 0.3f, 0.5f));
|
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_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_mat4("model", model);
|
||||||
main_shader.set_mat3("normal_mat", normal_mat);
|
main_shader.set_mat3("normal_mat", normal_mat);
|
||||||
diffuse_map.activate();
|
diffuse_map.activate();
|
||||||
@ -344,13 +389,15 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw light source
|
// Draw light source
|
||||||
// model = glm::translate(glm::mat4(1.0f), glm::vec3(light_pos_dir));
|
for (int i = 0; i < point_light_positions.size(); ++i) {
|
||||||
// model = glm::scale(model, glm::vec3(0.2f));
|
model = glm::translate(glm::mat4(1.0f), point_light_positions[i]);
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user