Skip to content

Commit

Permalink
[OpenGl] add normal map render
Browse files Browse the repository at this point in the history
  • Loading branch information
sarthou committed Aug 14, 2024
1 parent 2f30c78 commit 8bc8033
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 27 deletions.
3 changes: 3 additions & 0 deletions include/overworld/Engine/Common/Models/Vertex.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ namespace owds {
class Vertex
{
public:
// Never change the attributes order
glm::vec3 position_;
glm::vec3 normal_;
glm::vec2 uv_;
glm::vec3 tangent_;
glm::vec3 bitangent_;
};

} // namespace owds
Expand Down
6 changes: 6 additions & 0 deletions include/overworld/Engine/Graphics/Assimp/ModelLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@

#include <filesystem>

#include "overworld/Engine/Common/Models/Mesh.h"
#include "overworld/Engine/Common/Models/Model.h"
#include "overworld/Engine/Common/Models/ModelLoader.h"

namespace owds::assimp {
class ModelLoader final : public owds::ModelLoader
{
public:
std::unique_ptr<owds::Model> load(const std::filesystem::path& path) const override;

private:
void computeTangentSpace(std::unique_ptr<owds::Model> model);
void computeTangentSpace(Mesh& mesh);
};
} // namespace owds::assimp

Expand Down
12 changes: 7 additions & 5 deletions include/overworld/Engine/Graphics/OpenGL/MeshHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace owds {
{
name = "material.texture_normal";
number = std::to_string(normal_nr++);
shader.setFloat("material.use_normal", 1.);
}
else if(textures[i].type_ == texture_height)
{
Expand Down Expand Up @@ -96,6 +97,7 @@ namespace owds {
glActiveTexture(GL_TEXTURE0 + texture_pose_offset + nb_used);
glBindTexture(GL_TEXTURE_2D, 0);
shader.setInt("material.texture_normal1", texture_pose_offset + nb_used);
shader.setFloat("material.use_normal", 0.);
nb_used++;
}

Expand Down Expand Up @@ -150,11 +152,11 @@ namespace owds {
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv_));
// vertex tangent
// glEnableVertexAttribArray(3);
// glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Tangent));
//// vertex bitangent
// glEnableVertexAttribArray(4);
// glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Bitangent));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, tangent_));
// vertex bitangent
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, bitangent_));
//// ids
// glEnableVertexAttribArray(5);
// glVertexAttribIPointer(5, 4, GL_INT, sizeof(Vertex), (void*)offsetof(Vertex, m_BoneIDs));
Expand Down
12 changes: 11 additions & 1 deletion shaders/light_shader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ out vec4 FragColor;
layout (location = 0) in vec3 FragPos;
layout (location = 1) in vec3 Normal;
layout (location = 2) in vec2 TexCoords;
layout (location = 3) in mat3 TBN;

struct Material {
sampler2D texture_diffuse1;
sampler2D texture_specular1;
//sampler2D emission;
sampler2D texture_normal1;

float shininess;
float specular;
vec4 color;
float use_normal; // 0 if no normal map
};

uniform Material material;
Expand Down Expand Up @@ -71,6 +74,13 @@ void main()
{
// properties
vec3 norm = normalize(Normal);
if(material.use_normal > 0)
{
norm = texture(material.texture_normal1, TexCoords).rgb;
norm = norm * 2.0 - 1.0;
norm = normalize(TBN * norm);
}

vec3 viewDir = normalize(view_pose - FragPos);

// phase 1: Directional lighting
Expand Down
18 changes: 13 additions & 5 deletions shaders/light_shader.vs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,29 @@
layout (location = 0) in vec3 aPos; // the position variable has attribute position 0
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in vec3 aTangent;
layout (location = 4) in vec3 aBitangent;

layout (location = 0) out vec3 FragPos;
layout (location = 1) out vec3 Normal;
layout (location = 2) out vec2 TexCoords;
layout (location = 3) out mat3 TBN;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoords = aTexCoords;
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoords = aTexCoords;

gl_Position = projection * view * vec4(FragPos, 1.0);
//gl_Position = projection * view * model * vec4(aPos, 1.0);
vec3 T = normalize(vec3(model * vec4(aTangent, 0.0)));
vec3 B = normalize(vec3(model * vec4(aBitangent, 0.0)));
vec3 N = normalize(vec3(model * vec4(aNormal, 0.0)));
TBN = mat3(T, B, N);

gl_Position = projection * view * vec4(FragPos, 1.0);
//gl_Position = projection * view * model * vec4(aPos, 1.0);
}
3 changes: 1 addition & 2 deletions src/Engine/Common/Models/Loaders/ObjLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace owds {
std::unique_ptr<owds::Model> ObjLoader::read(const std::string& path)
{
std::string mtl_path;
size_t pos = path.find_last_of("/\\");
auto pos = path.find_last_of("/\\");
if(pos != std::string::npos)
mtl_path = path.substr(0, pos);

Expand Down Expand Up @@ -80,7 +80,6 @@ namespace owds {
std::vector<tinyobj::Mesh_t>& meshes,
std::vector<tinyobj::Material_t>& materials)
{
(void)materials; // TODO
auto model = std::make_unique<Model>(Model::create());

for(const auto& tiny_mesh : meshes)
Expand Down
46 changes: 33 additions & 13 deletions src/Engine/Common/Models/Loaders/TinyObjReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,12 @@ namespace tinyobj {
token += 7;
parseTextureName(material.ambient_texname, token);
if(material.ambient_texname.find('/') == std::string::npos)
material.ambient_texname = texture_path + "/" + material.ambient_texname;
{
if(texture_path.back() != '/')
material.ambient_texname = texture_path + "/" + material.ambient_texname;
else
material.ambient_texname = texture_path + material.ambient_texname;
}
continue;
}

Expand All @@ -994,7 +999,12 @@ namespace tinyobj {
token += 7;
parseTextureName(material.diffuse_texname, token);
if(material.diffuse_texname.find('/') == std::string::npos)
material.diffuse_texname = texture_path + "/" + material.diffuse_texname;
{
if(texture_path.back() != '/')
material.diffuse_texname = texture_path + "/" + material.diffuse_texname;
else
material.diffuse_texname = texture_path + material.diffuse_texname;
}

// Set a decent diffuse default value if a diffuse texture is specified
// without a matching Kd value.
Expand All @@ -1014,7 +1024,12 @@ namespace tinyobj {
token += 7;
parseTextureName(material.specular_texname, token);
if(material.specular_texname.find('/') == std::string::npos)
material.specular_texname = texture_path + "/" + material.specular_texname;
{
if(texture_path.back() != '/')
material.specular_texname = texture_path + "/" + material.specular_texname;
else
material.specular_texname = texture_path + material.specular_texname;
}
continue;
}

Expand All @@ -1023,8 +1038,19 @@ namespace tinyobj {
// continue;

// bump texture
// if((0 == strncmp(token, "map_bump", 8)) && IS_SPACE(token[8]))
// continue;
if(((0 == strncmp(token, "map_Bump", 8)) || (0 == strncmp(token, "map_bump", 8))) && IS_SPACE(token[8]))
{
token += 9;
parseTextureName(material.normal_texname, token);
if(material.normal_texname.find('/') == std::string::npos)
{
if(texture_path.back() != '/')
material.normal_texname = texture_path + "/" + material.normal_texname;
else
material.normal_texname = texture_path + material.normal_texname;
}
continue;
}

// bump texture
// if((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4]))
Expand Down Expand Up @@ -1063,14 +1089,8 @@ namespace tinyobj {
// continue;

// PBR: normal map texture
if((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4]))
{
token += 5;
parseTextureName(material.normal_texname, token);
if(material.normal_texname.find('/') == std::string::npos)
material.normal_texname = texture_path + "/" + material.normal_texname;
continue;
}
// if((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4]))
// continue
}
// flush last material.
material_map->insert(std::pair<std::string, int>(material.name, static_cast<int>(materials->size())));
Expand Down
53 changes: 53 additions & 0 deletions src/Engine/Graphics/Assimp/ModelLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
#include <assimp/scene.h>
#include <filesystem>
#include <fstream>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <iostream>

#include "overworld/Engine/Common/Models/Loaders/ColladaLoader.h"
#include "overworld/Engine/Common/Models/Loaders/ObjLoader.h"
#include "overworld/Engine/Common/Models/Loaders/StlLoader.h"
#include "overworld/Engine/Common/Models/Mesh.h"
#include "overworld/Engine/Common/Models/Model.h"

namespace owds::assimp {
Expand Down Expand Up @@ -121,4 +124,54 @@ namespace owds::assimp {

return model;
}

void ModelLoader::computeTangentSpace(std::unique_ptr<owds::Model> model)
{
for(auto& mesh : model->meshes_)
computeTangentSpace(mesh);
}

void ModelLoader::computeTangentSpace(Mesh& mesh)
{
for(unsigned int i = 0; i < mesh.indices_.size(); i = i + 3)
{
glm::vec3& vertex0 = mesh.vertices_.at(mesh.indices_.at(i)).position_;
glm::vec3& vertex1 = mesh.vertices_.at(mesh.indices_.at(i + 1)).position_;
glm::vec3& vertex2 = mesh.vertices_.at(mesh.indices_.at(i + 3)).position_;

glm::vec3 normal = glm::cross((vertex1 - vertex0), (vertex2 - vertex0));

glm::vec3 delta_pos;
if(vertex0 == vertex1)
delta_pos = vertex2 - vertex0;
else
delta_pos = vertex1 - vertex0;

glm::vec2& uv0 = mesh.vertices_.at(mesh.indices_.at(i)).uv_;
glm::vec2& uv1 = mesh.vertices_.at(mesh.indices_.at(i + 1)).uv_;
// lm::vec2& uv2 = mesh.vertices_.at(mesh.indices_.at(i + 2)).uv_;

glm::vec2 delta_uv1 = uv1 - uv0;

glm::vec3 tan;
// avoid divion with 0
if(delta_uv1.s != 0)
tan = delta_pos / delta_uv1.s;
else
tan = delta_pos / 1.0f;

tan = glm::normalize(tan - glm::dot(normal, tan) * normal);

glm::vec3 bin = glm::normalize(glm::cross(tan, normal));

// write into array - for each vertex of the face the same value
mesh.vertices_[mesh.indices_.at(i)].tangent_ = tan;
mesh.vertices_[mesh.indices_.at(i + 1)].tangent_ = tan;
mesh.vertices_[mesh.indices_.at(i + 2)].tangent_ = tan;

mesh.vertices_[mesh.indices_.at(i)].bitangent_ = bin;
mesh.vertices_[mesh.indices_.at(i + 1)].bitangent_ = bin;
mesh.vertices_[mesh.indices_.at(i + 2)].bitangent_ = bin;
}
}
} // namespace owds::assimp
2 changes: 1 addition & 1 deletion src/Engine/Graphics/OpenGL/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ namespace owds {
if(render_camera_.aa_setting_ != ViewAntiAliasing_e::off)
setAntiAliasing(render_camera_.aa_setting_);

Shader::shaders_directory = "/home/gsarthou/Robots/Dacobot2/ros2_ws/src/overworld/shaders/";
Shader::shaders_directory = "/home/gsarthou/Robots/Dacobot2/ros2_ws/src/overworld/shaders/"; // TODO not hard coded
shaders_.insert({
"default", {"light_shader.vs", "light_shader.fs"}
});
Expand Down

0 comments on commit 8bc8033

Please sign in to comment.