[FEATURE] multiple light support

This commit is contained in:
Menno
2021-05-21 16:25:39 +02:00
parent bd227d3afe
commit 97a7501cda
4 changed files with 87 additions and 34 deletions

View File

@@ -13,13 +13,18 @@ namespace entities
private: private:
glm::vec3 position; glm::vec3 position;
glm::vec3 color; glm::vec3 color;
glm::vec3 attenuation = { 1, 0, 0 };
public: public:
Light(const glm::vec3& position, const glm::vec3& color) : position(position), color(color) { } Light(const glm::vec3& position, const glm::vec3& color) : position(position), color(color) { }
Light(const glm::vec3& position, const glm::vec3& color, const glm::vec3& attenuation)
: position(position), color(color), attenuation(attenuation) { }
glm::vec3 GetPosition() const { return position; } glm::vec3 GetPosition() const { return position; }
void setPosition(const glm::vec3& position) { this->position = position; } void setPosition(const glm::vec3& position) { this->position = position; }
glm::vec3 GetColor() const { return color; } glm::vec3 GetColor() const { return color; }
void setColor(const glm::vec3& color) { this->color = color; } void setColor(const glm::vec3& color) { this->color = color; }
glm::vec3 GetAttenuation() const { return attenuation; }
void SetAttenuation(const glm::vec3& attenuation) { this->attenuation = attenuation; }
}; };
} }

View File

@@ -63,9 +63,12 @@ int main(void)
z += (raw_model.model_size.x * 20); z += (raw_model.model_size.x * 20);
} }
entities::Light light(glm::vec3(0, 0, -30), glm::vec3(1, 1, 1)); std::vector<entities::Light> lights;
lights.push_back(entities::Light(glm::vec3(0, 1000, -7000), glm::vec3(5, 5, 5)));
shaders::EntityShader shader; lights.push_back(entities::Light(glm::vec3(0, 0, -30), glm::vec3(2, 0, 2), glm::vec3(0.0001f, 0.0001f, 0.0001f)));
lights.push_back(entities::Light(glm::vec3(0, 0, -200), glm::vec3(0, 2, 0), glm::vec3(0.0001f, 0.0001f, 0.0001f)));
shaders::EntityShader shader;
shader.Init(); shader.Init();
render_engine::renderer::Init(shader); render_engine::renderer::Init(shader);
@@ -82,7 +85,7 @@ int main(void)
render_engine::renderer::Prepare(); render_engine::renderer::Prepare();
shader.Start(); shader.Start();
shader.LoadSkyColor(render_engine::renderer::SKY_COLOR); shader.LoadSkyColor(render_engine::renderer::SKY_COLOR);
shader.LoadLight(light); shader.LoadLights(lights);
shader.LoadViewMatrix(camera); shader.LoadViewMatrix(camera);
/** /**

View File

@@ -18,14 +18,14 @@ namespace shaders
// Equal to the texture_coords // Equal to the texture_coords
out vec2 pass_texture_coords; out vec2 pass_texture_coords;
out vec3 surface_normal; out vec3 surface_normal;
out vec3 to_light_vector; out vec3 to_light_vector[4];
out vec3 to_camera_vector; out vec3 to_camera_vector;
out float visibility; out float visibility;
uniform mat4 model_matrix; uniform mat4 model_matrix;
uniform mat4 projection_matrix; uniform mat4 projection_matrix;
uniform mat4 view_matrix; uniform mat4 view_matrix;
uniform vec3 light_position; uniform vec3 light_position[4];
const float density = 0.0017; const float density = 0.0017;
const float gradient = 4; const float gradient = 4;
@@ -44,7 +44,10 @@ namespace shaders
pass_texture_coords = texture_coords; pass_texture_coords = texture_coords;
surface_normal = (model_matrix * vec4(normal, 0.0)).xyz; surface_normal = (model_matrix * vec4(normal, 0.0)).xyz;
to_light_vector = light_position - world_position.xyz; for (int i = 0; i < 4; i++)
{
to_light_vector[i] = light_position[i] - world_position.xyz;
}
to_camera_vector = (inverse(view_matrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - world_position.xyz; to_camera_vector = (inverse(view_matrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - world_position.xyz;
// Calculate the density/visibility of the vertex with the fog // Calculate the density/visibility of the vertex with the fog
@@ -64,7 +67,7 @@ namespace shaders
in vec2 pass_texture_coords; in vec2 pass_texture_coords;
in vec3 surface_normal; in vec3 surface_normal;
in vec3 to_light_vector; in vec3 to_light_vector[4];
in vec3 to_camera_vector; in vec3 to_camera_vector;
in float visibility; in float visibility;
@@ -72,33 +75,49 @@ namespace shaders
out vec4 out_color; out vec4 out_color;
// The texture of the model // The texture of the model
uniform sampler2D texture_sampler; uniform sampler2D model_texture;
uniform vec3 light_color; uniform vec3 light_color[4];
uniform vec3 attenuation[4];
uniform float shine_damper; uniform float shine_damper;
uniform float reflectivity; uniform float reflectivity;
uniform vec3 sky_color; uniform vec3 sky_color;
const float min_diffuse_lighting = 0.1;
void main(void) void main(void)
{ {
vec3 unit_normal = normalize(surface_normal); vec3 unit_normal = normalize(surface_normal);
vec3 unit_light_vector = normalize(to_light_vector); vec3 unit_camera_vector = normalize(to_camera_vector);
vec3 unit_camera_vector = normalize(to_camera_vector);
// Calculate the diffuse lighting vec3 total_diffuse = vec3(0.0);
float dot_diffuse = dot(unit_normal, unit_light_vector); vec3 total_specular = vec3(0.0);
float brightness = max(dot_diffuse, 0.1);
vec3 diffuse = brightness * light_color; for (int i = 0; i < 4; i++)
{
float distance = length(to_light_vector[i]);
float att_factor = attenuation[i].x + (attenuation[i].y * distance) + (attenuation[i].z * distance * distance);
vec3 unit_light_vector = normalize(to_light_vector[i]);
// Calculate the specular lighting // Calculate the diffuse lighting
vec3 light_direction = -unit_light_vector; float dot_diffuse = dot(unit_normal, unit_light_vector);
vec3 reflected_light_direction = reflect(light_direction, unit_normal); float brightness = max(dot_diffuse, 0.0);
float dot_specular = dot(reflected_light_direction, unit_camera_vector);
dot_specular = max(dot_specular, 0.0); // Calculate the specular lighting
float damped_specular = pow(dot_specular, shine_damper); vec3 light_direction = -unit_light_vector;
vec3 specular = damped_specular * reflectivity * light_color; vec3 reflected_light_direction = reflect(light_direction, unit_normal);
float dot_specular = dot(reflected_light_direction, unit_camera_vector);
dot_specular = max(dot_specular, 0.0);
float damped_specular = pow(dot_specular, shine_damper);
out_color = vec4(diffuse, 1.0) * texture(texture_sampler, pass_texture_coords) + vec4(specular, 1.0); total_diffuse = total_diffuse + (brightness * light_color[i]) / att_factor;
total_specular = total_specular + (damped_specular * reflectivity * light_color[i]) / att_factor;
}
total_diffuse = max(total_diffuse, min_diffuse_lighting);
out_color = vec4(total_diffuse, 1.0) * texture(model_texture, pass_texture_coords) + vec4(total_specular, 1.0);
out_color = mix(vec4(sky_color, 1.0), out_color, visibility); out_color = mix(vec4(sky_color, 1.0), out_color, visibility);
} }
)"; )";
@@ -124,10 +143,22 @@ namespace shaders
LoadMatrix(location_view_matrix, view_matrix); LoadMatrix(location_view_matrix, view_matrix);
} }
void EntityShader::LoadLight(entities::Light& light) const void EntityShader::LoadLights(std::vector<entities::Light>& lights) const
{ {
LoadVector(location_light_position, light.GetPosition()); for (int i = 0; i < MAX_LIGHTS; ++i)
LoadVector(location_light_color, light.GetColor()); {
if (i < lights.size())
{
LoadVector(location_light_position[i], lights[i].GetPosition());
LoadVector(location_light_color[i], lights[i].GetColor());
LoadVector(location_light_attenuation[i], lights[i].GetAttenuation());
} else
{
LoadVector(location_light_position[i], glm::vec3(0, 0, 0));
LoadVector(location_light_color[i], glm::vec3(0, 0, 0));
LoadVector(location_light_attenuation[i], glm::vec3(1, 0, 0));
}
}
} }
void EntityShader::LoadShineVariables(float shine_damper, float reflectivity) const void EntityShader::LoadShineVariables(float shine_damper, float reflectivity) const
@@ -155,10 +186,20 @@ namespace shaders
location_model_matrix = GetUniformLocation("model_matrix"); location_model_matrix = GetUniformLocation("model_matrix");
location_projection_matrix = GetUniformLocation("projection_matrix"); location_projection_matrix = GetUniformLocation("projection_matrix");
location_view_matrix = GetUniformLocation("view_matrix"); location_view_matrix = GetUniformLocation("view_matrix");
location_light_position = GetUniformLocation("light_position");
location_light_color = GetUniformLocation("light_color");
location_shine_damper = GetUniformLocation("shine_damper"); location_shine_damper = GetUniformLocation("shine_damper");
location_reflectivity = GetUniformLocation("reflectivity"); location_reflectivity = GetUniformLocation("reflectivity");
location_sky_color = GetUniformLocation("sky_color"); location_sky_color = GetUniformLocation("sky_color");
for (int i = 0; i < MAX_LIGHTS; ++i)
{
std::string light_pos = std::string("light_position[") + std::to_string(i) + "]";
location_light_position[i] = GetUniformLocation(light_pos.c_str());
std::string light_color = std::string("light_color[") + std::to_string(i) + "]";
location_light_color[i] = GetUniformLocation(light_color.c_str());
std::string light_attenuation = std::string("attenuation[") + std::to_string(i) + "]";
location_light_attenuation[i] = GetUniformLocation(light_attenuation.c_str());
}
} }
} }

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <vector>
#include "shader_program.h" #include "shader_program.h"
#include "../entities/camera.h" #include "../entities/camera.h"
#include "../entities/light.h" #include "../entities/light.h"
@@ -14,11 +15,14 @@ namespace shaders
class EntityShader : public ShaderProgram class EntityShader : public ShaderProgram
{ {
private: private:
const static int MAX_LIGHTS = 4;
GLuint location_model_matrix; GLuint location_model_matrix;
GLuint location_projection_matrix; GLuint location_projection_matrix;
GLuint location_view_matrix; GLuint location_view_matrix;
GLuint location_light_position; GLuint location_light_position[MAX_LIGHTS];
GLuint location_light_color; GLuint location_light_color[MAX_LIGHTS];
GLuint location_light_attenuation[MAX_LIGHTS];
GLuint location_shine_damper; GLuint location_shine_damper;
GLuint location_reflectivity; GLuint location_reflectivity;
GLuint location_sky_color; GLuint location_sky_color;
@@ -48,11 +52,11 @@ namespace shaders
void LoadViewMatrix(entities::Camera& camera) const; void LoadViewMatrix(entities::Camera& camera) const;
/* /*
* @brief: A method to load a light into the shader * @brief: A method to load some lights into the shader
* *
* @param light: The light * @param lights: The lights
*/ */
void LoadLight(entities::Light& light) const; void LoadLights(std::vector<entities::Light>& lights) const;
/* /*
* @brief: A method to load the the shine variables from a model into the shader * @brief: A method to load the the shine variables from a model into the shader