Redo the normal map lighting to be done in tangent space and with blinn-phong lighing

This commit is contained in:
SeanOMik 2022-10-02 11:39:07 -04:00
parent 366ab19544
commit 19d116ef65
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
9 changed files with 107 additions and 102 deletions

View File

@ -1,37 +1,39 @@
---
Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,-modernize-use-trailing-return-type'
Checks: "clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,-modernize-use-trailing-return-type"
WarningsAsErrors: true
HeaderFilterRegex: ''
HeaderFilterRegex: ""
AnalyzeTemporaryDtors: false
FormatStyle: google
FormatStyle: google
CheckOptions:
- key: cert-dcl16-c.NewSuffixes
value: 'L;LL;LU;LLU'
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
value: '0'
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
value: '1'
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: '1'
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold
value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines
value: '10'
- key: google-readability-namespace-comments.SpacesBeforeComments
value: '2'
- key: modernize-loop-convert.MaxCopySize
value: '16'
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: modernize-loop-convert.NamingStyle
value: CamelCase
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: modernize-use-nullptr.NullMacros
value: 'NULL'
...
- key: cert-dcl16-c.NewSuffixes
value: "L;LL;LU;LLU"
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
value: "0"
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
value: "1"
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: "1"
- key: google-readability-braces-around-statements.ShortStatementLines
value: "1"
- key: google-readability-function-size.StatementThreshold
value: "800"
- key: google-readability-namespace-comments.ShortNamespaceLines
value: "10"
- key: google-readability-namespace-comments.SpacesBeforeComments
value: "2"
- key: modernize-loop-convert.MaxCopySize
value: "16"
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: modernize-loop-convert.NamingStyle
value: CamelCase
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: modernize-use-nullptr.NullMacros
value: "NULL"
- key: readability-magic-numbers
value: "0"
---

View File

@ -179,7 +179,7 @@ int main(int argc, char *argv[]) {
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/paradigm/paradigm.fbx");
// entity.add_component<se::RotatingComponent>();
auto &transform_comp = entity.add_component<se::TransformComponent>();
transform_comp.translate(7.f, 0.f, 0.f);
transform_comp.translate(4.f, 0.f, 0.f);
// transform_comp.scale(0.05f);
// transform_comp.rotate_z(-90.f);
// transform_comp.rotate_y(-90.f);
@ -197,7 +197,7 @@ int main(int argc, char *argv[]) {
auto camera = std::make_shared<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0));
game.add_event(camera);
auto light = std::make_shared<se::gfx::Light>(core_shader, glm::vec3(-10.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f));
auto light = std::make_shared<se::gfx::Light>(core_shader, glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f));
game.add_event(light);
auto fps_counter = std::make_shared<FPSCounterEvent>();

View File

@ -32,7 +32,7 @@ namespace simpleengine::gfx {
*/
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) :
Material(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> textures, float shine = 1.f, float specular_scalar = 1.f, float ambient_scalar = 1.f, float diffuse_scalar = 1.f) :
textures(textures), ambient_strength(ambient_scalar), diffuse_strength(diffuse_scalar), specular_strength(specular_scalar),
shine_factor(shine) {

View File

@ -25,22 +25,16 @@ namespace simpleengine::gfx {
std::vector<GLuint> indicies;
std::vector<simpleengine::Vectorf> tangents;
std::vector<simpleengine::Vectorf> bitangents;
gfx::VBO tangent_vbo;
bool are_buffers_created = false;
gfx::VBO ebo;
gfx::VBO vbo;
gfx::VAO vao;
gfx::VBO tangent_vbo;
//gfx::VAO tangent_vao;
gfx::VBO bitangent_vbo;
//gfx::VAO bitangent_vao;
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material);
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies = std::vector<GLuint>(), std::optional<Material> material = std::nullopt);
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material, gfx::VBO ebo, gfx::VBO vbo, gfx::VAO vao, gfx::VBO tangent_vbo, gfx::VBO bitangent_vbo);
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material, gfx::VBO ebo, gfx::VBO vbo, gfx::VAO vao, gfx::VBO tangent_vbo);
virtual void destroy() override;

View File

@ -12,7 +12,11 @@ in vec3 vs_view_pos;
in vec3 vs_light_pos;
in vec3 vs_frag_pos;
in mat3 vs_tbn;
//in mat3 vs_tbn;
in vec3 vs_tangent_light_pos;
in vec3 vs_tangent_view_pos;
in vec3 vs_tangent_frag_pos;
const int SAMP_DIFFUSE = 0;
const int SAMP_SPECULAR = 1;
@ -50,32 +54,34 @@ void main() {
}
vec3 calculate_lighting() {
// Ambient
//float ambient_strength = 0.1;
vec3 ambient = u_material.ambient_strength * u_light_color;
vec3 normal = vs_world_normal;
vec3 normal = vec3(0.f, 0.f, 1.f); // default tangent-space normal
// Check if the normal map is set before trying to apply it.
if (u_material.has_normal_map) {
normal = texture(u_material.normal_map, vs_texcoord).rgb;
normal = normal * 2.0 - 1.0;
normal = normalize(vs_tbn * normal);
// transform normal vector to range [-1,1]
normal = normalize(normal * 2.f - 1.f); // this normal is in tangent space
}
// Diffuse
vec3 norm = normalize(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;
// Get diffuse color
vec3 diffuse_map = texture(u_material.diffuse, vs_texcoord).rgb;
// Ambient lighting
vec3 ambient = 0.1f * u_material.ambient_strength * diffuse_map;
// Diffuse lighting
vec3 light_dir = normalize(vs_tangent_light_pos - vs_tangent_frag_pos);
float diff = max(dot(light_dir, normal), 0.f);
vec3 diffuse = diff * u_material.diffuse_strength * diffuse_map;
// Specular lighting
vec3 view_dir = normalize(vs_tangent_view_pos - vs_tangent_frag_pos);
vec3 reflect_dir = reflect(-light_dir, normal);
vec3 halfway_dir = normalize(light_dir + view_dir);
float spec = pow(max(dot(normal, halfway_dir), 0.f), 32.f * u_material.shine_factor);
vec3 specular = vec3(0.2f * u_material.specular_strength) * spec;
// Check if the specular map is set before trying to apply it.
if (u_material.has_specular_map) {
specular = specular * texture(u_material.specular_map, vs_texcoord).r;

View File

@ -6,7 +6,6 @@ layout (location = 2) in vec3 vertex_normal;
layout (location = 3) in vec2 vertex_texcoord;
// TODO: Make these optional
layout (location = 4) in vec3 vertex_tangent;
layout (location = 5) in vec3 vertex_bitangent;
out vec3 vs_position;
out vec3 vs_color;
@ -20,7 +19,11 @@ out vec3 vs_view_pos;
out vec3 vs_light_pos;
out vec3 vs_frag_pos;
out mat3 vs_tbn;
//out mat3 vs_tbn;
out vec3 vs_tangent_light_pos;
out vec3 vs_tangent_view_pos;
out vec3 vs_tangent_frag_pos;
uniform mat4 u_transform_matrix;
uniform mat4 u_view_matrix;
@ -40,6 +43,7 @@ void main() {
gl_Position = u_projection_matrix * u_view_matrix * world_pos;
// Apply transform matrix to normal.
vs_normal = (u_transform_matrix * vec4(vertex_normal, 0.f)).xyz;
vs_view_pos = u_view_pos;
@ -47,9 +51,15 @@ void main() {
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
// Calculate the TBN (Tangent, Bi-tangent, and normal matrix)
vec3 T = normalize(vec3(u_transform_matrix * vec4(vertex_tangent, 1.f)));
vec3 B = normalize(vec3(u_transform_matrix * vec4(vertex_bitangent, 1.f)));
vec3 N = normalize(vec3(u_transform_matrix * vec4(vertex_normal, 1.f)));
vs_tbn = mat3(T, B, N);
// Calculate tangent space stuff.
mat3 normal_matrix = transpose(inverse(mat3(u_transform_matrix)));
vec3 T = normalize(normal_matrix * vertex_tangent);
vec3 N = normalize(normal_matrix * vertex_normal);
T = normalize(T - dot(T, N) * N);
vec3 B = cross(N, T);
mat3 TBN = transpose(mat3(T, B, N));
vs_tangent_light_pos = TBN * u_light_position;
vs_tangent_view_pos = TBN * u_view_pos;
vs_tangent_frag_pos = TBN * vs_frag_pos;
}

View File

@ -7,20 +7,20 @@ namespace simpleengine::gfx {
Mesh::Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material) :
material(std::make_optional(material)), vertices(vertices), indicies(indicies),
vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)),
vao(gfx::VAO::init()), tangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), bitangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)) {
vao(gfx::VAO::init()), tangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)) {
}
Mesh::Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, std::optional<Material> material) :
material(material), vertices(vertices), indicies(indicies),
vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)),
vao(gfx::VAO::init()), tangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), bitangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)) {
vao(gfx::VAO::init()), tangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)) {
}
Mesh::Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material, gfx::VBO ebo, gfx::VBO vbo, gfx::VAO vao,
gfx::VBO tangent_vbo, gfx::VBO bitangent_vbo) :
vertices(vertices), indicies(indicies), material(material), ebo(ebo), vbo(vbo), vao(vao), tangent_vbo(tangent_vbo), bitangent_vbo(bitangent_vbo) {
gfx::VBO tangent_vbo) :
vertices(vertices), indicies(indicies), material(material), ebo(ebo), vbo(vbo), vao(vao), tangent_vbo(tangent_vbo) {
}
@ -81,13 +81,9 @@ namespace simpleengine::gfx {
}
void Mesh::calculate_tangents() {
// Resize the tangent and bitangents
//tangents.clear();
// Resize the tangents vector, they will overwritten,
// so no need to clear the vector.
tangents.resize(vertices.size());
//bitangents.clear();
bitangents.resize(vertices.size());
/* std::vector<simpleengine::Vectorf> tangents;
std::vector<simpleengine::Vectorf> bitangents; */
for (int i = 0; i < indicies.size(); i += 3) {
int index0 = indicies[i];
@ -111,20 +107,12 @@ namespace simpleengine::gfx {
glm::vec2 delta_uv2 = lit_vertex2.tex_coord - lit_vertex0.tex_coord;
float r = 1.0f / (delta_uv1.x * delta_uv2.y - delta_uv1.y * delta_uv2.x);
glm::vec3 tangent = (delta_pos1 * delta_uv2.y - delta_pos2 * delta_uv1.y)*r;
glm::vec3 bitangent = (delta_pos2 * delta_uv1.x - delta_pos1 * delta_uv2.x)*r;
glm::vec3 tangent = (delta_pos1 * delta_uv2.y - delta_pos2 * delta_uv1.y)*r;
//glm::vec3 bitangent = (delta_pos2 * delta_uv1.x - delta_pos1 * delta_uv2.x)*r;
tangents[index0] = tangent;
tangents[index1] = tangent;
tangents[index2] = tangent;
bitangents[index0] = bitangent;
bitangents[index1] = bitangent;
bitangents[index2] = bitangent;
}
/* this->tangents = std::optional<std::pair<std::vector<simpleengine::Vectorf>, std::vector<simpleengine::Vectorf>>>(
{tangents, bitangents}
); */
}
}

View File

@ -28,18 +28,17 @@ namespace simpleengine::gfx {
if (model_processing_flags & ModelProcessingFlags::MdlProcFlag_FLIP_TEX_COORDS_HORIZONTALLY) {
horizontally_flip_tex_coords();
}
if (model_processing_flags & ModelProcessingFlags::MdlProcFlag_CALCULATE_TANGENT_SPACE) {
calculate_tangents();
}
}
void Model::load_model(std::string path) {
Assimp::Importer importer;
if (model_processing_flags & ModelProcessingFlags::MdlProcFlag_CALCULATE_TANGENT_SPACE) {
additional_assimp_flags |= aiProcess_CalcTangentSpace;
}
// assimp post processing options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html
const aiScene *scene = importer.ReadFile(path, additional_assimp_flags | aiProcess_Triangulate | aiProcess_FlipUVs
| aiProcess_CalcTangentSpace);
const aiScene *scene = importer.ReadFile(path, additional_assimp_flags | aiProcess_Triangulate | aiProcess_FlipUVs);
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
@ -70,6 +69,7 @@ namespace simpleengine::gfx {
gfx::Mesh Model::process_mesh(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMesh* mesh, const aiScene* scene) {
std::vector<LitVertex> vertices;
std::vector<unsigned int> indicies;
std::vector<Vectorf> tangents;
for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
LitVertex vertex;
@ -91,6 +91,10 @@ namespace simpleengine::gfx {
vertex.tex_coord = tex_coord;
}
if (mesh->HasTangentsAndBitangents()) {
tangents.emplace_back(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z);
}
vertices.push_back(vertex);
}
@ -173,6 +177,10 @@ namespace simpleengine::gfx {
se_mesh.calculate_normals();
}
if (mesh->HasTangentsAndBitangents()) {
se_mesh.tangents = tangents;
}
return se_mesh;
}

View File

@ -64,9 +64,6 @@ namespace simpleengine::gfx {
rendering_mesh.tangent_vbo.buffer(rendering_mesh.tangents.data(), 0, rendering_mesh.tangents.size() * sizeof(Vectorf));
vao.enable_attrib(rendering_mesh.tangent_vbo, 4, 3, GL_FLOAT, sizeof(Vectorf), 0, false);
rendering_mesh.bitangent_vbo.buffer(rendering_mesh.bitangents.data(), 0, rendering_mesh.bitangents.size() * sizeof(Vectorf));
vao.enable_attrib(rendering_mesh.bitangent_vbo, 5, 3, GL_FLOAT, sizeof(Vectorf), 0, false);
vbo.unbind();
vao.unbind();