more lighting
This commit is contained in:
parent
28c4f16d71
commit
954075bd4f
9 changed files with 171 additions and 27 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
builddir/
|
||||
.cache/
|
||||
|
|
BIN
assets/container2.qoi
Normal file
BIN
assets/container2.qoi
Normal file
Binary file not shown.
BIN
assets/container2_specular.qoi
Normal file
BIN
assets/container2_specular.qoi
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/fish.png
BIN
assets/fish.png
Binary file not shown.
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 7.2 KiB |
|
@ -31,11 +31,27 @@ struct DirectionalLight {
|
|||
vec3 specular;
|
||||
};
|
||||
|
||||
struct SpotLight {
|
||||
vec3 position;
|
||||
vec3 direction;
|
||||
float cutOff;
|
||||
float outerCutOff;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
};
|
||||
|
||||
#define POINT_LIGHTS_COUNT 4
|
||||
|
||||
uniform Material material;
|
||||
uniform vec3 viewPos;
|
||||
|
||||
uniform SpotLight spotLight;
|
||||
uniform DirectionalLight directionalLight;
|
||||
uniform PointLight pointLights[POINT_LIGHTS_COUNT];
|
||||
|
||||
|
@ -55,12 +71,12 @@ vec3 ComputeDirectionalLight(DirectionalLight light, vec3 norm, vec3 viewDir)
|
|||
return (ambient + diffuse + specular);
|
||||
}
|
||||
|
||||
vec3 ComputePointLight(PointLight light, vec3 norm, vec3 viewDir)
|
||||
vec3 ComputePointLight(PointLight light, vec3 norm, vec3 viewDir, vec3 fragPos)
|
||||
{
|
||||
float distance = length(light.position - FragPos);
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
|
||||
|
||||
vec3 lightDir = normalize(light.position - FragPos);
|
||||
vec3 lightDir = normalize(light.position - fragPos);
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
|
@ -73,16 +89,40 @@ vec3 ComputePointLight(PointLight light, vec3 norm, vec3 viewDir)
|
|||
return (ambient * attenuation + diffuse * attenuation + specular * attenuation);
|
||||
}
|
||||
|
||||
vec3 ComputeSpotLight(SpotLight light, vec3 norm, vec3 viewDir, vec3 fragPos) {
|
||||
vec3 lightDir = normalize(light.position - fragPos);
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
|
||||
float theta = dot(lightDir, normalize(-light.direction));
|
||||
float epsilon = light.cutOff - light.outerCutOff;
|
||||
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
|
||||
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
|
||||
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
|
||||
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
|
||||
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
|
||||
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
|
||||
|
||||
// we leave ambient alone so there's always a little light
|
||||
return ((ambient * attenuation) + (diffuse * intensity * attenuation) + (specular * intensity * attenuation));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
|
||||
vec3 result = vec3(0.0);
|
||||
|
||||
result += ComputeDirectionalLight(directionalLight, norm, viewDir);
|
||||
for (int i = 0; i < POINT_LIGHTS_COUNT; i++) {
|
||||
result += ComputePointLight(pointLights[i], norm, viewDir);
|
||||
result += ComputePointLight(pointLights[i], norm, viewDir, FragPos);
|
||||
}
|
||||
result += ComputeSpotLight(spotLight, norm, viewDir, FragPos);
|
||||
|
||||
FragColor = vec4(result, 1.0);
|
||||
}
|
||||
|
|
113
src/main.cpp
113
src/main.cpp
|
@ -24,10 +24,10 @@ std::function<void(double x, double y)> cursor_position_callback = nullptr;
|
|||
int main()
|
||||
{
|
||||
qoi_desc fish_desc;
|
||||
void *fish_rgba = qoi_read("assets/fish.qoi", &fish_desc, 4);
|
||||
void *fish_rgba = qoi_read("assets/container2.qoi", &fish_desc, 4);
|
||||
|
||||
qoi_desc fish_map_desc;
|
||||
void *fish_map_rgba = qoi_read("assets/fish-map.qoi", &fish_map_desc, 4);
|
||||
void *fish_map_rgba = qoi_read("assets/container2_specular.qoi", &fish_map_desc, 4);
|
||||
|
||||
|
||||
if (!glfwInit()) {
|
||||
|
@ -107,6 +107,27 @@ int main()
|
|||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
// positions all containers
|
||||
glm::vec3 cube_positions[] = {
|
||||
glm::vec3( 0.0f, 0.0f, 0.0f),
|
||||
glm::vec3( 2.0f, 5.0f, -15.0f),
|
||||
glm::vec3(-1.5f, -2.2f, -2.5f),
|
||||
glm::vec3(-3.8f, -2.0f, -12.3f),
|
||||
glm::vec3( 2.4f, -0.4f, -3.5f),
|
||||
glm::vec3(-1.7f, 3.0f, -7.5f),
|
||||
glm::vec3( 1.3f, -2.0f, -2.5f),
|
||||
glm::vec3( 1.5f, 2.0f, -2.5f),
|
||||
glm::vec3( 1.5f, 0.2f, -1.5f),
|
||||
glm::vec3(-1.3f, 1.0f, -1.5f)
|
||||
};
|
||||
// positions of the point lights
|
||||
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)
|
||||
};
|
||||
|
||||
unsigned int fish_texture;
|
||||
glGenTextures(1, &fish_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, fish_texture);
|
||||
|
@ -131,6 +152,8 @@ int main()
|
|||
glGenVertexArrays(1, &object_vao);
|
||||
glBindVertexArray(object_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, cube_buffer);
|
||||
|
||||
// position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (const void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
@ -145,6 +168,8 @@ int main()
|
|||
glGenVertexArrays(1, &light_source_vao);
|
||||
glBindVertexArray(light_source_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, cube_buffer);
|
||||
|
||||
// position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (const void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
@ -165,8 +190,6 @@ int main()
|
|||
float delta_time = 0.0f;
|
||||
float last_frame_time = 0.0f;
|
||||
|
||||
glm::vec3 light_position(1.2f, 1.0f, 2.0f);
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
float current_frame_time = glfwGetTime();
|
||||
delta_time = current_frame_time - last_frame_time;
|
||||
|
@ -195,7 +218,7 @@ int main()
|
|||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
{
|
||||
/* lit object */
|
||||
/* lit objects */
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, fish_texture);
|
||||
|
@ -203,33 +226,81 @@ int main()
|
|||
glBindTexture(GL_TEXTURE_2D, fish_map_texture);
|
||||
|
||||
glUseProgram(lighting_program);
|
||||
|
||||
glBindVertexArray(object_vao);
|
||||
glUniformMatrix4fv(glGetUniformLocation(lighting_program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
glUniformMatrix4fv(glGetUniformLocation(lighting_program, "view"), 1, GL_FALSE, glm::value_ptr(camera.view));
|
||||
glUniformMatrix4fv(glGetUniformLocation(lighting_program, "model"), 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f)));
|
||||
glUniform3fv(glGetUniformLocation(lighting_program, "viewPos"), 1, glm::value_ptr(camera.position));
|
||||
|
||||
glUniform1i(glGetUniformLocation(lighting_program, "material.diffuse"), 0);
|
||||
glUniform1i(glGetUniformLocation(lighting_program, "material.specular"), 1);
|
||||
glUniform1f(glGetUniformLocation(lighting_program, "material.shininess"), 32.0f);
|
||||
program_set(lighting_program, "projection", projection);
|
||||
program_set(lighting_program, "view", camera.view);
|
||||
program_set(lighting_program, "viewPos", camera.position);
|
||||
|
||||
glUniform3fv(glGetUniformLocation(lighting_program, "light.position"), 1, glm::value_ptr(light_position));
|
||||
glUniform3f(glGetUniformLocation(lighting_program, "light.ambient"), 0.2f, 0.2f, 0.2f);
|
||||
glUniform3f(glGetUniformLocation(lighting_program, "light.diffuse"), 0.5f, 0.5f, 0.5f);
|
||||
glUniform3f(glGetUniformLocation(lighting_program, "light.specular"), 1.0f, 1.0f, 1.0f);
|
||||
program_set(lighting_program, "material.shininess", 32.0f);
|
||||
|
||||
program_set(lighting_program, "directionalLight.direction", -0.2f, -1.0f, -0.3f);
|
||||
program_set(lighting_program, "directionalLight.ambient", 0.05f, 0.05f, 0.05f);
|
||||
program_set(lighting_program, "directionalLight.diffuse", 0.4f, 0.4f, 0.4f);
|
||||
program_set(lighting_program, "directionalLight.specular", 0.5f, 0.5f, 0.5f);
|
||||
// point light 1
|
||||
program_set(lighting_program, "pointLights[0].position", point_light_positions[0]);
|
||||
program_set(lighting_program, "pointLights[0].ambient", 0.05f, 0.05f, 0.05f);
|
||||
program_set(lighting_program, "pointLights[0].diffuse", 0.8f, 0.8f, 0.8f);
|
||||
program_set(lighting_program, "pointLights[0].specular", 1.0f, 1.0f, 1.0f);
|
||||
program_set(lighting_program, "pointLights[0].constant", 1.0f);
|
||||
program_set(lighting_program, "pointLights[0].linear", 0.09f);
|
||||
program_set(lighting_program, "pointLights[0].quadratic", 0.032f);
|
||||
// point light 2
|
||||
program_set(lighting_program, "pointLights[1].position", point_light_positions[1]);
|
||||
program_set(lighting_program, "pointLights[1].ambient", 0.05f, 0.05f, 0.05f);
|
||||
program_set(lighting_program, "pointLights[1].diffuse", 0.8f, 0.8f, 0.8f);
|
||||
program_set(lighting_program, "pointLights[1].specular", 1.0f, 1.0f, 1.0f);
|
||||
program_set(lighting_program, "pointLights[1].constant", 1.0f);
|
||||
program_set(lighting_program, "pointLights[1].linear", 0.09f);
|
||||
program_set(lighting_program, "pointLights[1].quadratic", 0.032f);
|
||||
// point light 3
|
||||
program_set(lighting_program, "pointLights[2].position", point_light_positions[2]);
|
||||
program_set(lighting_program, "pointLights[2].ambient", 0.05f, 0.05f, 0.05f);
|
||||
program_set(lighting_program, "pointLights[2].diffuse", 0.8f, 0.8f, 0.8f);
|
||||
program_set(lighting_program, "pointLights[2].specular", 1.0f, 1.0f, 1.0f);
|
||||
program_set(lighting_program, "pointLights[2].constant", 1.0f);
|
||||
program_set(lighting_program, "pointLights[2].linear", 0.09f);
|
||||
program_set(lighting_program, "pointLights[2].quadratic", 0.032f);
|
||||
// point light 4
|
||||
program_set(lighting_program, "pointLights[3].position", point_light_positions[3]);
|
||||
program_set(lighting_program, "pointLights[3].ambient", 0.05f, 0.05f, 0.05f);
|
||||
program_set(lighting_program, "pointLights[3].diffuse", 0.8f, 0.8f, 0.8f);
|
||||
program_set(lighting_program, "pointLights[3].specular", 1.0f, 1.0f, 1.0f);
|
||||
program_set(lighting_program, "pointLights[3].constant", 1.0f);
|
||||
program_set(lighting_program, "pointLights[3].linear", 0.09f);
|
||||
program_set(lighting_program, "pointLights[3].quadratic", 0.032f);
|
||||
// spot light
|
||||
program_set(lighting_program, "spotLight.position", camera.position);
|
||||
program_set(lighting_program, "spotLight.direction", camera.front);
|
||||
program_set(lighting_program, "spotLight.ambient", 0.0f, 0.0f, 0.0f);
|
||||
program_set(lighting_program, "spotLight.diffuse", 1.0f, 1.0f, 1.0f);
|
||||
program_set(lighting_program, "spotLight.specular", 1.0f, 1.0f, 1.0f);
|
||||
program_set(lighting_program, "spotLight.constant", 1.0f);
|
||||
program_set(lighting_program, "spotLight.linear", 0.09f);
|
||||
program_set(lighting_program, "spotLight.quadratic", 0.032f);
|
||||
program_set(lighting_program, "spotLight.cutOff", glm::cos(glm::radians(12.5f)));
|
||||
program_set(lighting_program, "spotLight.outerCutOff", glm::cos(glm::radians(15.0f)));
|
||||
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
program_set(lighting_program, "model", glm::rotate(glm::translate(glm::mat4(1.0f), cube_positions[i]), glm::radians(20.0f * i), glm::vec3(1.0f, 0.3f, 0.5f)));
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
}
|
||||
}
|
||||
|
||||
/* lamp object */
|
||||
{
|
||||
glUseProgram(light_cube_program);
|
||||
glBindVertexArray(light_source_vao);
|
||||
glUniformMatrix4fv(glGetUniformLocation(light_cube_program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
glUniformMatrix4fv(glGetUniformLocation(light_cube_program, "view"), 1, GL_FALSE, glm::value_ptr(camera.view));
|
||||
glUniformMatrix4fv(glGetUniformLocation(light_cube_program, "model"), 1, GL_FALSE, glm::value_ptr(glm::scale(glm::translate(glm::mat4(1.0f), light_position), glm::vec3(0.2f))));
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
program_set(light_cube_program, "view", camera.view);
|
||||
program_set(light_cube_program, "projection", projection);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
program_set(light_cube_program, "model", glm::scale(glm::translate(glm::mat4(1.0f), point_light_positions[i]), glm::vec3(0.2f)));
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,3 +103,28 @@ done:
|
|||
if (fragment_shader_source) free(fragment_shader_source);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void program_set(unsigned int program, const char *uniform, int value)
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(program, uniform), value);
|
||||
}
|
||||
|
||||
void program_set(unsigned int program, const char *uniform, float value)
|
||||
{
|
||||
glUniform1f(glGetUniformLocation(program, uniform), value);
|
||||
}
|
||||
|
||||
void program_set(unsigned int program, const char *uniform, glm::vec3 vec)
|
||||
{
|
||||
glUniform3fv(glGetUniformLocation(program, uniform), 1, &vec[0]);
|
||||
}
|
||||
|
||||
void program_set(unsigned int program, const char *uniform, float x, float y, float z)
|
||||
{
|
||||
glUniform3f(glGetUniformLocation(program, uniform), x, y, z);
|
||||
}
|
||||
|
||||
void program_set(unsigned int program, const char *uniform, const glm::mat4 &mat)
|
||||
{
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, uniform), 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "vendor/glm/glm/mat4x4.hpp"
|
||||
#include "vendor/glm/glm/vec3.hpp"
|
||||
|
||||
unsigned int create_program(const char *vertex_shader_path, const char *fragment_shader_path);
|
||||
void program_set(unsigned int program, const char *uniform, int value);
|
||||
void program_set(unsigned int program, const char *uniform, float value);
|
||||
void program_set(unsigned int program, const char *uniform, glm::vec3 vec);
|
||||
void program_set(unsigned int program, const char *uniform, float x, float y, float z);
|
||||
void program_set(unsigned int program, const char *uniform, const glm::mat4 &mat);
|
||||
|
|
Loading…
Reference in a new issue