Redo the lighting in the shaders
This commit is contained in:
parent
7f2ff589ac
commit
3a61b8495e
|
@ -162,10 +162,6 @@ int main(int argc, char *argv[]) {
|
||||||
5, 6, 12, 12, 6, 13
|
5, 6, 12, 12, 6, 13
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<se::gfx::Texture>>> textures;
|
|
||||||
textures.emplace(white_texture.type, std::vector<std::shared_ptr<se::gfx::Texture>>{ std::make_shared<se::gfx::Texture>(white_texture) });
|
|
||||||
se::gfx::Material white_material(textures, 1.f, 0.f, 0.f, 0.f, 0.f);
|
|
||||||
|
|
||||||
// Create a renderer
|
// Create a renderer
|
||||||
auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader);
|
auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader);
|
||||||
game.add_renderable(renderer);
|
game.add_renderable(renderer);
|
||||||
|
@ -184,7 +180,7 @@ int main(int argc, char *argv[]) {
|
||||||
model_comp.model.vertically_flip_tex_coords(); */
|
model_comp.model.vertically_flip_tex_coords(); */
|
||||||
|
|
||||||
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/viper/viper.obj");
|
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/viper/viper.obj");
|
||||||
entity.add_component<se::ModelComponent>("examples/dev_testing/resources/halo/halo.fbx");
|
entity.add_component<se::ModelComponent>("examples/dev_testing/resources/halot/chief.fbx");
|
||||||
|
|
||||||
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/scientist/scientist.fbx");
|
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/scientist/scientist.fbx");
|
||||||
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/paradigm/paradigm.fbx");
|
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/paradigm/paradigm.fbx");
|
||||||
|
|
|
@ -18,8 +18,8 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override {
|
virtual void update(const float& delta_time) override {
|
||||||
shader.use();
|
shader.use();
|
||||||
shader.set_uniform_float_vec3("light_position", position, false);
|
shader.set_uniform_float_vec3("u_light_position", position, false);
|
||||||
shader.set_uniform_float_vec3("light_color", color, false);
|
shader.set_uniform_float_vec3("u_light_color", color, false);
|
||||||
shader.unuse();
|
shader.unuse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,29 @@ namespace simpleengine::gfx {
|
||||||
public:
|
public:
|
||||||
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> textures;
|
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> textures;
|
||||||
|
|
||||||
float ambient_scalar;
|
float ambient_strength;
|
||||||
float diffuse_scalar;
|
float diffuse_strength;
|
||||||
float specular_scalar;
|
|
||||||
float shine;
|
|
||||||
float reflectivity;
|
|
||||||
|
|
||||||
Material(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> textures, float shine = 1.f, float reflectivity = 0.f, float specular_scalar = 0.f, float ambient_scalar = 0.f, float diffuse_scalar = 0.f) :
|
/**
|
||||||
textures(textures), ambient_scalar(ambient_scalar), diffuse_scalar(diffuse_scalar), specular_scalar(specular_scalar),
|
* @brief This strengthens the brightness of a specular highlight.
|
||||||
shine(shine), reflectivity(reflectivity) {
|
*
|
||||||
|
*/
|
||||||
|
float specular_strength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The shininess value of the highlight. (Radius of specular highlight?)
|
||||||
|
|
||||||
|
* The higher the shininess value of an object, the more it properly reflects the light
|
||||||
|
* instead of scattering it all around and thus the smaller the highlight becomes.
|
||||||
|
*
|
||||||
|
* The shader multiplies this by 32 to get the specular highlight.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
float shine_factor;
|
||||||
|
|
||||||
|
Material(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> textures, float shine = 1.f, float specular_scalar = 1.f, float ambient_scalar = 0.2f, float diffuse_scalar = 1.f) :
|
||||||
|
textures(textures), ambient_strength(ambient_scalar), diffuse_strength(diffuse_scalar), specular_strength(specular_scalar),
|
||||||
|
shine_factor(shine) {
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,52 +3,67 @@
|
||||||
in vec3 vs_position;
|
in vec3 vs_position;
|
||||||
in vec3 vs_color;
|
in vec3 vs_color;
|
||||||
in vec3 vs_normal;
|
in vec3 vs_normal;
|
||||||
|
in vec3 vs_world_normal; // Normal in world space
|
||||||
in vec2 vs_texcoord;
|
in vec2 vs_texcoord;
|
||||||
|
|
||||||
in mat4 vs_transform;
|
in mat4 vs_transform;
|
||||||
in vec3 vs_to_light;
|
|
||||||
in vec3 vs_to_camera;
|
in vec3 vs_view_pos;
|
||||||
|
in vec3 vs_light_pos;
|
||||||
|
in vec3 vs_frag_pos;
|
||||||
|
|
||||||
const int SAMP_DIFFUSE = 0;
|
const int SAMP_DIFFUSE = 0;
|
||||||
uniform sampler2D u_samplers[16];
|
const int SAMP_SPECULAR = 1;
|
||||||
uniform float u_texture_shine[16];
|
|
||||||
uniform float u_texture_reflectivity[16];
|
|
||||||
|
|
||||||
uniform vec3 light_color;
|
struct Material {
|
||||||
|
sampler2D diffuse;
|
||||||
|
sampler2D specular_map;
|
||||||
|
|
||||||
|
float ambient_strength;
|
||||||
|
float diffuse_strength;
|
||||||
|
float specular_strength;
|
||||||
|
|
||||||
|
float shine_factor;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform Material u_material;
|
||||||
|
|
||||||
|
uniform vec3 u_light_color;
|
||||||
|
|
||||||
out vec4 fs_color;
|
out vec4 fs_color;
|
||||||
|
|
||||||
vec3 calculate_specular(vec3 unit_normal, float shine_damper, float reflectivity);
|
vec3 calculate_lighting();
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Lighting
|
|
||||||
vec3 unit_normal = normalize(vs_normal);
|
|
||||||
vec3 unit_light_vector = normalize(vs_to_light);
|
|
||||||
|
|
||||||
float dot_prod = dot(unit_normal, unit_light_vector);
|
|
||||||
float brightness = max(dot_prod, 0.f);
|
|
||||||
vec3 diffuse = brightness * light_color;
|
|
||||||
|
|
||||||
// Calculate the specular
|
|
||||||
float shine_damper = u_texture_shine[SAMP_DIFFUSE];
|
|
||||||
float reflectivity = u_texture_reflectivity[SAMP_DIFFUSE];
|
|
||||||
vec3 final_specular = calculate_specular(unit_normal, shine_damper, reflectivity);
|
|
||||||
|
|
||||||
// Combine diffuse lighting, specular, and the texture into one color.
|
// Combine diffuse lighting, specular, and the texture into one color.
|
||||||
fs_color = vec4(diffuse, 1.f) * texture(u_samplers[SAMP_DIFFUSE], vs_texcoord) + vec4(final_specular, 1.f);
|
//fs_color = vec4(diffuse, 1.f) * texture(u_material.diffuse, vs_texcoord) + vec4(final_specular, 1.f);
|
||||||
|
|
||||||
|
vec3 lighting = calculate_lighting();
|
||||||
|
|
||||||
|
fs_color = vec4(lighting, 1.f) * texture(u_material.diffuse, vs_texcoord);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 calculate_specular(vec3 unit_normal, float shine_damper, float reflectivity) {
|
vec3 calculate_lighting() {
|
||||||
vec3 final_specular = vec3(0.f);
|
// Ambient
|
||||||
if (reflectivity > 0) {
|
//float ambient_strength = 0.1;
|
||||||
vec3 unit_vector_to_camera = normalize(vs_to_camera);
|
vec3 ambient = u_material.ambient_strength * u_light_color;
|
||||||
vec3 light_direction = -unit_vector_to_camera;
|
|
||||||
vec3 reflected_light_dir = reflect(light_direction, unit_normal);
|
|
||||||
float specular_factor = dot(reflected_light_dir, unit_vector_to_camera);
|
|
||||||
specular_factor = max(specular_factor, 0.f);
|
|
||||||
float damped_specular = pow(specular_factor, shine_damper);
|
|
||||||
final_specular = damped_specular * reflectivity * light_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
return final_specular;
|
// Diffuse
|
||||||
|
vec3 norm = normalize(vs_world_normal);
|
||||||
|
vec3 light_dir = normalize(vs_light_pos - vs_frag_pos);
|
||||||
|
float diff = max(dot(norm, light_dir), 0.f);
|
||||||
|
vec3 diffuse = (diff * u_material.diffuse_strength) * u_light_color;
|
||||||
|
|
||||||
|
// Specular
|
||||||
|
float specular_strength = 0.5;
|
||||||
|
vec3 view_dir = normalize(vs_view_pos - vs_frag_pos);
|
||||||
|
vec3 reflect_dir = reflect(-light_dir, norm);
|
||||||
|
float spec = pow(max(dot(view_dir, reflect_dir), -0.f), 32 * u_material.shine_factor);
|
||||||
|
vec3 specular = specular_strength * (spec * u_material.specular_strength) * u_light_color;
|
||||||
|
|
||||||
|
//specular = specular * vec3(texture(u_material.specular_map, vs_texcoord)); // TODO check if its set before applying it.
|
||||||
|
|
||||||
|
return ambient + diffuse + specular;
|
||||||
}
|
}
|
|
@ -8,29 +8,37 @@ layout (location = 3) in vec2 vertex_texcoord;
|
||||||
out vec3 vs_position;
|
out vec3 vs_position;
|
||||||
out vec3 vs_color;
|
out vec3 vs_color;
|
||||||
out vec3 vs_normal;
|
out vec3 vs_normal;
|
||||||
|
out vec3 vs_world_normal; // normal in world space
|
||||||
out vec2 vs_texcoord;
|
out vec2 vs_texcoord;
|
||||||
|
|
||||||
out mat4 vs_transform;
|
out mat4 vs_transform;
|
||||||
out vec3 vs_to_light;
|
|
||||||
out vec3 vs_to_camera;
|
|
||||||
|
|
||||||
uniform mat4 transform_matrix;
|
out vec3 vs_view_pos;
|
||||||
uniform mat4 view_matrix;
|
out vec3 vs_light_pos;
|
||||||
uniform mat4 projection_matrix;
|
out vec3 vs_frag_pos;
|
||||||
uniform vec3 light_position;
|
|
||||||
|
uniform mat4 u_transform_matrix;
|
||||||
|
uniform mat4 u_view_matrix;
|
||||||
|
uniform mat4 u_projection_matrix;
|
||||||
|
|
||||||
|
uniform vec3 u_view_pos;
|
||||||
|
uniform vec3 u_light_position;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 world_pos = (transform_matrix * vec4(vertex_position, 1.f));
|
vec4 world_pos = (u_transform_matrix * vec4(vertex_position, 1.f));
|
||||||
|
|
||||||
// Directly pass things to the fragment shader.
|
// Directly pass things to the fragment shader.
|
||||||
vs_position = world_pos.xyz;
|
vs_position = world_pos.xyz;
|
||||||
vs_transform = transform_matrix;
|
vs_transform = u_transform_matrix;
|
||||||
vs_texcoord = vertex_texcoord;
|
vs_texcoord = vertex_texcoord;
|
||||||
vs_color = vertex_color;
|
vs_color = vertex_color;
|
||||||
|
|
||||||
gl_Position = projection_matrix * view_matrix * world_pos;
|
gl_Position = u_projection_matrix * u_view_matrix * world_pos;
|
||||||
|
|
||||||
vs_normal = (transform_matrix * vec4(vertex_normal, 0.f)).xyz;
|
vs_normal = (u_transform_matrix * vec4(vertex_normal, 0.f)).xyz;
|
||||||
vs_to_light = light_position - world_pos.xyz;
|
|
||||||
vs_to_camera = (inverse(view_matrix) * vec4(0.f, 0.f, 0.f, 1.f)).xyz - world_pos.xyz;
|
vs_view_pos = u_view_pos;
|
||||||
|
vs_light_pos = u_light_position;
|
||||||
|
vs_frag_pos = vec3(u_transform_matrix * vec4(vertex_position, 1.f));
|
||||||
|
vs_world_normal = mat3(transpose(inverse(u_transform_matrix))) * vertex_normal; // TODO: Do this calculation on the CPU then send to GPU via a uniform
|
||||||
}
|
}
|
|
@ -63,19 +63,19 @@ namespace simpleengine {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
|
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
|
||||||
rotation.z += camera_speed * .3;
|
rotation.z += camera_speed * .4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
|
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
|
||||||
rotation.z -= camera_speed * .3;
|
rotation.z -= camera_speed * .4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
|
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
|
||||||
rotation.y -= camera_speed * .3;
|
rotation.y -= camera_speed * .4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
|
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
|
||||||
rotation.y += camera_speed * .3;
|
rotation.y += camera_speed * .4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit the pitch of the camera.
|
// Limit the pitch of the camera.
|
||||||
|
@ -96,8 +96,9 @@ namespace simpleengine {
|
||||||
view_matrix = glm::lookAt(position, position + camera_front, camera_up);
|
view_matrix = glm::lookAt(position, position + camera_front, camera_up);
|
||||||
|
|
||||||
shader.use();
|
shader.use();
|
||||||
shader.set_uniform_matrix_4f("view_matrix", view_matrix, false);
|
shader.set_uniform_float_vec3("u_view_pos", position, false);
|
||||||
shader.set_uniform_matrix_4f("projection_matrix", projection_matrix, false);
|
shader.set_uniform_matrix_4f("u_view_matrix", view_matrix, false);
|
||||||
|
shader.set_uniform_matrix_4f("u_projection_matrix", projection_matrix, false);
|
||||||
shader.unuse();
|
shader.unuse();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -101,7 +101,7 @@ namespace simpleengine::gfx {
|
||||||
auto white_texture = gfx::Texture::white_texture();
|
auto white_texture = gfx::Texture::white_texture();
|
||||||
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> default_textures;
|
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> default_textures;
|
||||||
default_textures.emplace(white_texture.type, std::vector<std::shared_ptr<Texture>>{ std::make_shared<Texture>(white_texture) });
|
default_textures.emplace(white_texture.type, std::vector<std::shared_ptr<Texture>>{ std::make_shared<Texture>(white_texture) });
|
||||||
gfx::Material mat(default_textures, 1.f, 0.f, 0.f, 0.f, 0.f);
|
gfx::Material mat(default_textures);
|
||||||
|
|
||||||
if (mesh->mMaterialIndex >= 0) {
|
if (mesh->mMaterialIndex >= 0) {
|
||||||
std::cout << "TODO: Process model materials!" << std::endl;
|
std::cout << "TODO: Process model materials!" << std::endl;
|
||||||
|
@ -110,14 +110,25 @@ namespace simpleengine::gfx {
|
||||||
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
||||||
|
|
||||||
// Load Diffuse texture maps
|
// Load Diffuse texture maps
|
||||||
std::vector<std::shared_ptr<Texture>> diffuse_maps = load_material_texture(processed_textures, material, aiTextureType_DIFFUSE);
|
aiTextureType loading_type = aiTextureType_DIFFUSE;
|
||||||
if (!diffuse_maps.empty()) textures.emplace(aiTextureType_DIFFUSE, diffuse_maps);
|
std::vector<std::shared_ptr<Texture>> diffuse_maps = load_material_texture(processed_textures, material, loading_type);
|
||||||
|
if (!diffuse_maps.empty()) textures.emplace(loading_type, diffuse_maps);
|
||||||
|
|
||||||
|
// Load specular texture maps
|
||||||
|
loading_type = aiTextureType_SPECULAR;
|
||||||
|
std::vector<std::shared_ptr<Texture>> spec_maps = load_material_texture(processed_textures, material, loading_type);
|
||||||
|
if (!spec_maps.empty()) textures.emplace(loading_type, spec_maps);
|
||||||
|
|
||||||
|
// Load normals texture maps
|
||||||
|
loading_type = aiTextureType_NORMALS;
|
||||||
|
std::vector<std::shared_ptr<Texture>> normal_maps = load_material_texture(processed_textures, material, loading_type);
|
||||||
|
if (!normal_maps.empty()) textures.emplace(loading_type, normal_maps);
|
||||||
|
|
||||||
// TODO Handle other types of texture maps
|
// TODO Handle other types of texture maps
|
||||||
|
|
||||||
if (!textures.empty()) {
|
if (!textures.empty()) {
|
||||||
// TODO: Find a way to let the user set the scalars.
|
// TODO: Find a way to let the user set the scalars.
|
||||||
mat = Material(textures, 1.f, 0.f, 0.f, 0.f, 0.f);
|
mat = Material(textures);
|
||||||
|
|
||||||
// Add `textures` into the `processed_textures` list.
|
// Add `textures` into the `processed_textures` list.
|
||||||
for (const auto& pair : textures) {
|
for (const auto& pair : textures) {
|
||||||
|
@ -186,7 +197,7 @@ namespace simpleengine::gfx {
|
||||||
ss << model_directory << "/" << texture_path;
|
ss << model_directory << "/" << texture_path;
|
||||||
std::string full_path = ss.str();
|
std::string full_path = ss.str();
|
||||||
|
|
||||||
Texture texture(full_path.c_str(), type, /* TextureFlags::TexFlags_FLIP_VERTICALLY | */ TextureFlags::TexFlags_IMG_2D | TextureFlags::TexFlags_MIPMAP);
|
Texture texture(full_path.c_str(), type, TextureFlags::TexFlags_IMG_2D | TextureFlags::TexFlags_MIPMAP);
|
||||||
texture.path = texture_path;
|
texture.path = texture_path;
|
||||||
textures.emplace_back(std::make_shared<Texture>(texture));
|
textures.emplace_back(std::make_shared<Texture>(texture));
|
||||||
|
|
||||||
|
|
|
@ -93,19 +93,39 @@ namespace simpleengine::gfx {
|
||||||
RenderingJob& job = rendering_queue.front();
|
RenderingJob& job = rendering_queue.front();
|
||||||
Mesh& mesh = job.rendering_mesh;
|
Mesh& mesh = job.rendering_mesh;
|
||||||
|
|
||||||
shader.set_uniform_matrix_4f("transform_matrix", job.transform_mat, false);
|
shader.set_uniform_matrix_4f("u_transform_matrix", job.transform_mat, false);
|
||||||
|
|
||||||
std::optional<Material>& material = mesh.material;
|
std::optional<Material>& material = mesh.material;
|
||||||
|
|
||||||
shader.set_uniform_int("u_textures", 0, false);
|
|
||||||
|
|
||||||
if (material.has_value()) {
|
if (material.has_value()) {
|
||||||
shader.set_uniform_float("u_texture_shine", material->shine, false);
|
shader.set_uniform_float("u_material.ambient_strength", material->ambient_strength, false);
|
||||||
shader.set_uniform_float("u_texture_reflectivity", material->reflectivity, false);
|
shader.set_uniform_float("u_material.diffuse_strength", material->diffuse_strength, false);
|
||||||
|
shader.set_uniform_float("u_material.specular_strength", material->specular_strength, false);
|
||||||
|
shader.set_uniform_float("u_material.shine_factor", material->shine_factor, false);
|
||||||
|
//shader.set_uniform_float("u_material.reflect_factor", .1f, false);
|
||||||
|
|
||||||
int texture_count = 0;
|
|
||||||
auto diffuse_maps = material->textures.find(aiTextureType_DIFFUSE);
|
auto diffuse_maps = material->textures.find(aiTextureType_DIFFUSE);
|
||||||
for (const auto& texture : diffuse_maps->second) {
|
auto diffuse_map = diffuse_maps->second.front();
|
||||||
|
|
||||||
|
shader.set_uniform_int("u_material.diffuse", 0, false);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
diffuse_map->bind();
|
||||||
|
|
||||||
|
auto specular_maps = material->textures.find(aiTextureType_SPECULAR);
|
||||||
|
|
||||||
|
|
||||||
|
if (specular_maps != material->textures.end()) {
|
||||||
|
auto spec = specular_maps->second.front();
|
||||||
|
|
||||||
|
shader.set_uniform_int("u_material.specular_map", 1, false);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
spec->bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
//diffuse_map
|
||||||
|
/* for (const auto& texture : diffuse_maps->second) {
|
||||||
// We can only bind to 16 textures at a time (indexes are 0-15)
|
// We can only bind to 16 textures at a time (indexes are 0-15)
|
||||||
if (texture_count >= 16) break;
|
if (texture_count >= 16) break;
|
||||||
|
|
||||||
|
@ -113,7 +133,7 @@ namespace simpleengine::gfx {
|
||||||
glBindTextureUnit(texture_count, texture->get_texture_id());
|
glBindTextureUnit(texture_count, texture->get_texture_id());
|
||||||
|
|
||||||
texture_count++;
|
texture_count++;
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.vao.bind();
|
mesh.vao.bind();
|
||||||
|
|
Loading…
Reference in New Issue