Add normalmap support

Tangents are not yet used, so the normals are currently only correct for the ground.
This commit is contained in:
karl 2020-11-16 13:11:07 +01:00
parent 4073897f74
commit 4951ad3b04
6 changed files with 51 additions and 24 deletions

View File

@ -8,16 +8,22 @@
#include "../../Util/stb_image.h"
struct Texture {
uint id;
uint normal_id;
bool render_transparent = false;
struct Settings {
Settings(bool mipmaps, bool transparent) : mipmaps(mipmaps), transparent(transparent) {}
Settings(bool mipmaps) : mipmaps(mipmaps) {}
bool mipmaps = true;
bool transparent = false;
};
explicit Texture(const std::string& path, Settings settings) {
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
// Bind a texture from the given path and return its ID
uint loadTexture(const std::string& path, Settings settings) {
uint gl_id;
glGenTextures(1, &gl_id);
glBindTexture(GL_TEXTURE_2D, gl_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@ -50,11 +56,17 @@ struct Texture {
stbi_image_free(data);
render_transparent = settings.transparent;
return gl_id;
}
unsigned int id;
bool render_transparent = false;
explicit Texture(const std::string& path, Settings settings, bool transparent) : id(loadTexture(path, settings)), render_transparent(transparent) {}
void addNormalmap(const std::string& path, Settings settings) {
normal_id = loadTexture(path, settings);
}
};
#endif //ECSGAME_TEXTURE_H

View File

@ -51,10 +51,11 @@ void renderQuad()
class RenderSystem : public EntitySystem {
public:
struct RenderObject {
RenderObject(const glm::mat4 &matrix, const glm::vec3 &origin, unsigned int textureId, const Mesh &mesh, float distance, const Material &material)
RenderObject(const glm::mat4 &matrix, const glm::vec3 &origin, unsigned int textureId, unsigned int normalId, const Mesh &mesh, float distance, const Material &material)
: matrix(matrix),
origin(origin),
texture_id(textureId),
normal_id(normalId),
mesh(mesh),
distance(distance),
material(material) {}
@ -69,6 +70,10 @@ public:
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture_id);
}
if (normal_id != 0) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, normal_id);
}
// TODO: Not always required (not when rendering shadows) - make functions separate?
shader.setFloat("diffuseStrength", material.diffuse);
@ -80,6 +85,7 @@ public:
glm::mat4 matrix;
glm::vec3 origin;
unsigned int texture_id;
unsigned int normal_id;
Mesh mesh;
float distance;
Material material;
@ -116,12 +122,13 @@ public:
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
unsigned int normalID = textureComponent.isValid() ? textureComponent->normal_id : 0;
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
if (textureComponent.isValid() && textureComponent->render_transparent) {
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material));
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, normalID, mesh.get(), distance, material));
} else {
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material));
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, normalID, mesh.get(), distance, material));
}
}
});
@ -138,12 +145,13 @@ public:
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
unsigned int normalID = textureComponent.isValid() ? textureComponent->normal_id : 0;
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
if (textureComponent.isValid() && textureComponent->render_transparent) {
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material));
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, normalID, mesh, distance, material));
} else {
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material));
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, normalID, mesh, distance, material));
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

After

Width:  |  Height:  |  Size: 31 MiB

BIN
Resources/Grass_Normal.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 MiB

View File

@ -8,6 +8,7 @@ in mediump vec4 FragPosLightSpace;
layout(binding=0) uniform sampler2D shadowMap;
layout(binding=1) uniform sampler2D tex;
layout(binding=2) uniform sampler2D normalmap;
uniform mediump vec3 lightDirection;
uniform mediump vec3 cameraPosition;
@ -43,20 +44,25 @@ void main()
{
mediump vec4 texColor = texture(tex, TexCoord);
// Get normal from normal map in the range [-1,1]
mediump vec3 map_normal = normalize(texture(normalmap, TexCoord).rgb * 2.0 - 1.0);
mediump vec3 final_normal = map_normal;
// Alpha Scissors
if(texColor.a < 0.1)
discard;
// Lighting
// Diffuse
mediump float diff = max(dot(Normal, lightDirection), 0.0);
mediump float diff = max(dot(final_normal, lightDirection), 0.0);
// Ambient
mediump float ambient = 0.2;
// Specular
mediump vec3 viewDir = normalize(cameraPosition - FragPos);
mediump vec3 reflectDir = reflect(-lightDirection, Normal);
mediump vec3 reflectDir = reflect(-lightDirection, final_normal);
mediump float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);

View File

@ -118,7 +118,7 @@ int main() {
monkey->assign<Transform>();
monkey->assign<LODObjMesh>(std::vector<ObjMesh>{ObjMesh("Resources/Monkey.obj",ObjMesh::Settings(0.0, 8.0, 0.4, 0.6)),
ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0, 0.4, 0.6))});
monkey->assign<Texture>("Resources/Marble.jpg", Texture::Settings(true, false));
monkey->assign<Texture>("Resources/Marble.jpg", Texture::Settings(true), false);
monkey->assign<SineAnimation>(glm::vec3(0.0, 0.3, 0.0), 0.5);
monkey->assign<Material>(0.6, 0.6);
monkey->get<Transform>()->set_origin(glm::vec3(0.0f, 2.0f, -6.0f));
@ -127,7 +127,7 @@ int main() {
monkey2->assign<Transform>();
monkey2->assign<LODObjMesh>(std::vector<ObjMesh>{ObjMesh("Resources/Monkey.obj",ObjMesh::Settings(0.0, 8.0, 0.4, 0.6)),
ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0, 0.4, 0.6))});
monkey2->assign<Texture>("Resources/Marble.jpg", Texture::Settings(true, false));
monkey2->assign<Texture>("Resources/Marble.jpg", Texture::Settings(true), false);
monkey2->assign<SineAnimation>(glm::vec3(0.0, 0.3, 0.0), 0.5);
monkey2->assign<Material>(0.6, 0.6);
monkey2->get<Transform>()->set_origin(glm::vec3(-5.0f, 2.0f, -20.0f));
@ -135,21 +135,21 @@ int main() {
Entity *wall1 = world->create();
wall1->assign<Transform>();
wall1->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
wall1->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
wall1->assign<Texture>("Resources/Glass.png", Texture::Settings(true), true);
wall1->assign<Material>(0.2, 0.8);
wall1->get<Transform>()->set_origin(glm::vec3(0.0f, 0.0f, -2.0f));
Entity *wall2 = world->create();
wall2->assign<Transform>();
wall2->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
wall2->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
wall2->assign<Texture>("Resources/Glass.png", Texture::Settings(true), true);
wall2->assign<Material>(0.2, 0.8);
wall2->get<Transform>()->set_origin(glm::vec3(0.0f, 0.0f, -10.0f));
Entity *wall3 = world->create();
wall3->assign<Transform>();
wall3->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
wall3->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
wall3->assign<Texture>("Resources/Glass.png", Texture::Settings(true), true);
wall3->assign<Material>(0.2, 0.8);
wall3->get<Transform>()->set_origin(glm::vec3(4.0f, 0.0f, -6.0f));
wall3->get<Transform>()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0));
@ -157,7 +157,7 @@ int main() {
Entity *wall4 = world->create();
wall4->assign<Transform>();
wall4->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
wall4->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
wall4->assign<Texture>("Resources/Glass.png", Texture::Settings(true), true);
wall4->assign<Material>(0.2, 0.8);
wall4->get<Transform>()->set_origin(glm::vec3(-4.0f, 0.0f, -6.0f));
wall4->get<Transform>()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0));
@ -165,14 +165,15 @@ int main() {
Entity *ground = world->create();
ground->assign<Transform>();
ground->assign<ObjMesh>(ObjMesh("Resources/Ground.obj", ObjMesh::Settings()));
ground->assign<Texture>("Resources/Grass.jpg", Texture::Settings(true, false));
ground->assign<Texture>("Resources/Grass.jpg", Texture::Settings(true), false);
ground->get<Texture>()->addNormalmap("Resources/Grass_Normal.jpg", Texture::Settings(true));
ground->assign<Material>(1.0, 0.0);
ground->get<Transform>()->set_origin(glm::vec3(0.0f, 0.0f, 0.0f));
Entity *bench = world->create();
bench->assign<Transform>();
bench->assign<ObjMesh>(ObjMesh("Resources/bench.obj", ObjMesh::Settings()));
bench->assign<Texture>("Resources/Wood.jpg", Texture::Settings(true, false));
bench->assign<Texture>("Resources/Wood.jpg", Texture::Settings(true), false);
bench->assign<Material>(0.8, 0.2);
bench->get<Transform>()->set_origin(glm::vec3(8.0f, 0.0f, 0.0f));
bench->get<Transform>()->rotate(-90.0, glm::vec3(0.0, 1.0, 0.0));
@ -180,7 +181,7 @@ int main() {
Entity *ring = world->create();
ring->assign<Transform>();
ring->assign<ObjMesh>(ObjMesh("Resources/ring.obj", ObjMesh::Settings()));
ring->assign<Texture>("Resources/Gold.jpg", Texture::Settings(true, false));
ring->assign<Texture>("Resources/Gold.jpg", Texture::Settings(true), false);
ring->assign<Material>(0.1, 0.9);
ring->get<Transform>()->set_origin(glm::vec3(-5.0f, 2.0f, 0.0f));