From d13e36b090ef74739d5504eb0d08b81a56375b79 Mon Sep 17 00:00:00 2001
From: Alexander Gauggel <agauggel@uni-koblenz.de>
Date: Sun, 20 Jun 2021 12:36:32 +0200
Subject: [PATCH] [#82] Add normal mapping

---
 .../resources/shaders/shader.frag             | 19 ++++++++++++++++---
 .../resources/shaders/shader.vert             |  3 +++
 projects/voxelization/src/main.cpp            |  4 ++--
 src/vkcv/ImageManager.cpp                     |  4 +++-
 4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/projects/voxelization/resources/shaders/shader.frag b/projects/voxelization/resources/shaders/shader.frag
index 8653ae59..24f4673b 100644
--- a/projects/voxelization/resources/shaders/shader.frag
+++ b/projects/voxelization/resources/shaders/shader.frag
@@ -9,6 +9,7 @@
 layout(location = 0) in vec3 passNormal;
 layout(location = 1) in vec2 passUV;
 layout(location = 2) in vec3 passPos;
+layout(location = 3) in vec4 passTangent;
 
 layout(location = 0) out vec3 outColor;
 
@@ -19,10 +20,22 @@ layout(set=0, binding=1) uniform texture2D  shadowMap;
 layout(set=0, binding=2) uniform sampler    shadowMapSampler;
 
 void main()	{
-    vec3 N          = normalize(passNormal);
+
+    vec3 albedoTexel    = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb;
+    vec3 normalTexel    = texture(sampler2D(normalTexture, textureSampler), passUV).rgb;
+    vec3 specularTexel  = texture(sampler2D(specularTexture, textureSampler), passUV).rgb;
+    
+    vec3 albedo = albedoTexel;
+    
+    vec3 T      = normalize(passTangent.xyz);
+    vec3 N_geo  = normalize(passNormal);
+    vec3 B      = cross(N_geo, T) * passTangent.w;
+    mat3 TBN    = mat3(T, B, N_geo);
+    normalTexel = normalTexel * 2 - 1;
+    
+    vec3 N          = TBN * normalTexel;
     vec3 sun        = lightInfo.sunStrength * lightInfo.sunColor * clamp(dot(N, lightInfo.L), 0, 1);
     sun             *= shadowTest(passPos, lightInfo, shadowMap, shadowMapSampler);
     vec3 ambient    = vec3(0.05);
-    vec3 albedo     = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb;
-	outColor        = albedo * (sun + ambient);
+	outColor        = albedo * (sun + ambient); 
 }
\ No newline at end of file
diff --git a/projects/voxelization/resources/shaders/shader.vert b/projects/voxelization/resources/shaders/shader.vert
index 926f86af..e3873f98 100644
--- a/projects/voxelization/resources/shaders/shader.vert
+++ b/projects/voxelization/resources/shaders/shader.vert
@@ -4,10 +4,12 @@
 layout(location = 0) in vec3 inPosition;
 layout(location = 1) in vec3 inNormal;
 layout(location = 2) in vec2 inUV;
+layout(location = 3) in vec4 inTangent;
 
 layout(location = 0) out vec3 passNormal;
 layout(location = 1) out vec2 passUV;
 layout(location = 2) out vec3 passPos;
+layout(location = 3) out vec4 passTangent;
 
 layout( push_constant ) uniform constants{
     mat4 mvp;
@@ -19,4 +21,5 @@ void main()	{
 	passNormal  = mat3(model) * inNormal;    // assuming no weird stuff like shearing or non-uniform scaling
     passUV      = inUV;
     passPos     = (model * vec4(inPosition, 1)).xyz;
+    passTangent = vec4(mat3(model) * inTangent.xyz, inTangent.w);
 }
\ No newline at end of file
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index f679a345..33b6cc20 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -217,14 +217,14 @@ int main(int argc, const char** argv) {
 		const vkcv::ImageHandle albedoHandle = sceneImages.back().getHandle();
 
 		// normal texture
-		sceneImages.push_back(core.createImage(vk::Format::eR8G8B8A8Srgb, normalTexture.w, normalTexture.h, 1, true));
+		sceneImages.push_back(core.createImage(vk::Format::eR8G8B8A8Unorm, normalTexture.w, normalTexture.h, 1, true));
 		sceneImages.back().fill(normalTexture.data.data());
 		sceneImages.back().generateMipChainImmediate();
 		sceneImages.back().switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal);
 		const vkcv::ImageHandle normalHandle = sceneImages.back().getHandle();
 
 		// specular texture
-		sceneImages.push_back(core.createImage(vk::Format::eR8G8B8A8Srgb, specularTexture.w, specularTexture.h, 1, true));
+		sceneImages.push_back(core.createImage(vk::Format::eR8G8B8A8Unorm, specularTexture.w, specularTexture.h, 1, true));
 		sceneImages.back().fill(specularTexture.data.data());
 		sceneImages.back().generateMipChainImmediate();
 		sceneImages.back().switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal);
diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp
index a3364ce0..98a8dfcf 100644
--- a/src/vkcv/ImageManager.cpp
+++ b/src/vkcv/ImageManager.cpp
@@ -352,8 +352,10 @@ namespace vkcv {
 				return 1;
 			case vk::Format::eR8G8B8A8Srgb:
 				return 4;
+			case vk::Format::eR8G8B8A8Unorm:
+				return 4;
 			default:
-				std::cerr << "Check format instead of guessing, please!" << std::endl;
+				std::cerr << "Unknown image format" << std::endl;
 				return 4;
 		}
 	}
-- 
GitLab