From 0b382245982c6430a6c6d891123986ce550d27ad Mon Sep 17 00:00:00 2001
From: Byurrer <byurrer@mail.ru>
Date: Mon, 15 Jun 2020 13:03:58 +0300
Subject: [PATCH] Fixed normal mapping

---
 build/engine/shaders/base/static.vs         | 46 ++++++++++++++++++++-
 build/engine/shaders/default/default.ps     | 11 +++--
 build/engine/shaders/default/terrain.ps     |  4 +-
 build/engine/shaders/default/transparent.ps |  9 ++--
 build/engine/shaders/mtrl.h                 |  8 +++-
 build/engine/shaders/struct.h               |  4 ++
 proj/SkyXEngine/vs2013/SkyXEngine.sln       |  3 ++
 proj/xSound/vs2013/xSound.vcxproj           |  6 +--
 source/render/RenderPipeline.cpp            |  2 +
 9 files changed, 75 insertions(+), 18 deletions(-)

diff --git a/build/engine/shaders/base/static.vs b/build/engine/shaders/base/static.vs
index 7b0432111..229480afa 100644
--- a/build/engine/shaders/base/static.vs
+++ b/build/engine/shaders/base/static.vs
@@ -9,13 +9,55 @@ mtrlgeom_base.vs
 
 //##########################################################################
 
-VSO_SceneCommon main(VSI_Geometry IN)
+float3 RotateVec(float4 q, float3 p)
+{
+	float xxzz = q.x*q.x - q.z*q.z;
+	float wwyy = q.w*q.w - q.y*q.y;
+	float xw2 = q.x*q.w*2.0;
+	float xy2 = q.x*q.y*2.0;
+	float xz2 = q.x*q.z*2.0;
+	float yw2 = q.y*q.w*2.0;
+	float yz2 = q.y*q.z*2.0;
+	float zw2 = q.z*q.w*2.0;
+	float3 oout = float3((xxzz + wwyy)*p.x		+ (xy2 + zw2)*p.y		+ (xz2 - yw2)*p.z,
+					(xy2 - zw2)*p.x			+ (q.y*q.y+q.w*q.w-q.x*q.x-q.z*q.z)*p.y	+ (yz2 + xw2)*p.z,
+					(xz2 + yw2)*p.x			+ (yz2 - xw2)*p.y		+ (wwyy - xxzz)*p.z);
+	return(oout);
+}
+
+//##########################################################################
+
+VSO_SceneCommon main(VSI_Geometry IN
+#ifdef USE_INSTANCING
+, uint uInstanceId: SV_InstanceId
+#endif
+)
 {
 	VSO_SceneCommon OUT = (VSO_SceneCommon)0;
 
+#ifdef USE_INSTANCING
+	
+	float4 vPosScale = g_instanceData[uInstanceId * 2];
+	float4 qRot = g_instanceData[uInstanceId * 2 + 1];
+	
+	OUT.vPosition = float4(RotateVec(qRot, IN.vPosition * vPosScale.w) + vPosScale.xyz, 1.0f);
+	// OUT.vPosition = float4(IN.vPosition + vPosScale.xyz, 1.0f);
+	// OUT.vPosition = float4(IN.vPosition, 1.0f);
+
+	OUT.vNormal = RotateVec(qRot, IN.vNormal);
+	OUT.vTangent  = RotateVec(qRot, IN.vTangent);
+  OUT.vBinormal = RotateVec(qRot, IN.vBinormal);
+	// OUT.vNormal = IN.vNormal;
+#else
 	OUT.vPosition = mul(float4(IN.vPosition, 1.0f), g_mW);
+	OUT.vNormal = normalize(mul(IN.vNormal, (float3x3)g_mW));
+  OUT.vTangent  = normalize(mul(IN.vTangent, (float3x3)g_mW));
+  OUT.vBinormal = normalize(mul(IN.vBinormal, (float3x3)g_mW));
+
+#endif
+
+	
 	OUT.vPosition = mul(OUT.vPosition, g_mVP);
-	OUT.vNormal = mul(IN.vNormal, (float3x3)g_mW);
 	OUT.vTexUV = IN.vTexUV;
 	OUT.vPos = OUT.vPosition;
 
diff --git a/build/engine/shaders/default/default.ps b/build/engine/shaders/default/default.ps
index 0d851c06e..1ea443127 100644
--- a/build/engine/shaders/default/default.ps
+++ b/build/engine/shaders/default/default.ps
@@ -26,9 +26,9 @@ XMaterial MainGBuffer(PSI_XMaterial IN)
 #endif
 
 #ifdef HAS_NORMALMAP
-	OUT.vNormal = MixNormalMicro(IN.vNormal, 
-		Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight
-	);
+	float3 vNormalMap = Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight;
+	OUT.vNormal = MixNormalMicro(vNormalMap, IN.vTangent, IN.vBinormal, IN.vNormal);
+	//OUT.vNormal = normalize((IN.vNormal + float3(vNormalMap.xy,IN.vNormal.z)));
 #else
 	OUT.vNormal = IN.vNormal;
 #endif
@@ -58,9 +58,8 @@ XMaterial MainIllimination(PSI_XMaterial IN)
 	OUT.vEmissiveColor = fColor.xyz * fColor.w * g_xMaterialConstants.em_multiplier;
 	
 #ifdef HAS_NORMALMAP
-	OUT.vNormal = MixNormalMicro(IN.vNormal, 
-		Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight
-	);
+	float3 vNormalMap = Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight;
+	OUT.vNormal = MixNormalMicro(vNormalMap, IN.vTangent, IN.vBinormal, IN.vNormal);
 #else
 	OUT.vNormal = IN.vNormal;
 #endif
diff --git a/build/engine/shaders/default/terrain.ps b/build/engine/shaders/default/terrain.ps
index 162b155bf..ae3138e70 100644
--- a/build/engine/shaders/default/terrain.ps
+++ b/build/engine/shaders/default/terrain.ps
@@ -84,7 +84,9 @@ XMaterial MainGBuffer(PSI_XMaterial IN)
 	OUT.fThickness = vParams.z;
 	OUT.fAO = vParams.w;
 	
-	OUT.vNormal = MixNormalMicro(IN.vNormal, vNormal);
+	//OUT.vNormal = MixNormalMicro(IN.vNormal, vNormal);
+	OUT.vNormal = MixNormalMicro(vNormal, IN.vTangent, IN.vBinormal, IN.vNormal);
+	//OUT.vNormal = normalize((IN.vNormal + float3(vNormal.xy,IN.vNormal.z)));
 	
 	OUT.f0 = 0.004;
 	
diff --git a/build/engine/shaders/default/transparent.ps b/build/engine/shaders/default/transparent.ps
index fd0112243..8bd5ee96a 100644
--- a/build/engine/shaders/default/transparent.ps
+++ b/build/engine/shaders/default/transparent.ps
@@ -13,9 +13,9 @@ XMaterial MainTransparency(PSI_XMaterial IN)
 #ifdef HAS_NORMALMAP
 	float3 vNormal = Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight;
 	
-	OUT.vNormal = MixNormalMicro(IN.vNormal, vNormal);
+	//OUT.vNormal = MixNormalMicro(IN.vNormal, vNormal);
 	// float2 vDuDv = vNormal.xy;
-	
+	OUT.vNormal = MixNormalMicro(vNormal, IN.vTangent, IN.vBinormal, IN.vNormal);
 	
 #ifdef HAS_REFRACTION
 	// float2 vDuDv = OUT.vNormal.xy;
@@ -84,9 +84,8 @@ XMaterial MainIllimination(PSI_XMaterial IN)
 	OUT.vEmissiveColor = fColor.xyz;
 	
 #ifdef HAS_NORMALMAP
-	OUT.vNormal = MixNormalMicro(IN.vNormal, 
-		Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight
-	);
+	float3 vNormalMap = Color2Normal(g_txNormals.Sample(g_sScene, IN.vTexUV).xyz) * g_xMaterialConstants.nm_weight;
+	OUT.vNormal = MixNormalMicro(vNormalMap, IN.vTangent, IN.vBinormal, IN.vNormal);
 #else
 	OUT.vNormal = IN.vNormal;
 #endif
diff --git a/build/engine/shaders/mtrl.h b/build/engine/shaders/mtrl.h
index a39b98a71..fc8d9108d 100644
--- a/build/engine/shaders/mtrl.h
+++ b/build/engine/shaders/mtrl.h
@@ -192,9 +192,15 @@ float GetLerpFactorDetail(float fDistance)
 }
 
 //! смешивание макронормали (модели) с микронормалью (из normal map)
-float3 MixNormalMicro(float3 vMacroNormal, float3 vMicroNormal)
+/*float3 MixNormalMicro(float3 vMacroNormal, float3 vMicroNormal)
 {
 	return normalize((vMacroNormal + float3(vMicroNormal.xy,vMacroNormal.z)));
+}*/
+
+float3 MixNormalMicro(float3 vNormalMap, float3 vTangent, float3 vBinormal, float3 vNormal)
+{
+	float3x3 mTBN = float3x3(vTangent, vBinormal, vNormal);
+	return normalize(mul(vNormalMap, mTBN));
 }
 
 //! смешивание 2 детальных текстур по маске, где r канал маски для первой детальной текстуры, а g для второй
diff --git a/build/engine/shaders/struct.h b/build/engine/shaders/struct.h
index 1fd16acee..586f6c2e8 100644
--- a/build/engine/shaders/struct.h
+++ b/build/engine/shaders/struct.h
@@ -68,6 +68,8 @@ struct VSI_Geometry
 	float3 vPosition	:POSITION0;
 	float2 vTexUV	:TEXCOORD0;
 	float3 vNormal	:NORMAL0;
+	float3 vTangent	: TANGENT0;
+	float3 vBinormal	: BINORMAL0;
 };
 
 
@@ -112,6 +114,8 @@ struct VSO_SceneCommon
 	float2 vTexUV	:TEXCOORD0;
 	float3 vNormal	:TEXCOORD1;
 	float4 vPos		:TEXCOORD2;
+	float3 vTangent	:TEXCOORD3;
+	float3 vBinormal	:TEXCOORD4;
 };
 
 struct GSO_SceneShadows
diff --git a/proj/SkyXEngine/vs2013/SkyXEngine.sln b/proj/SkyXEngine/vs2013/SkyXEngine.sln
index c7c5af055..78df0cfb6 100644
--- a/proj/SkyXEngine/vs2013/SkyXEngine.sln
+++ b/proj/SkyXEngine/vs2013/SkyXEngine.sln
@@ -366,6 +366,7 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xSound", "..\..\xSound\vs2013\xSound.vcxproj", "{4A77FC81-98F6-4ABF-A489-B6F427354E5B}"
 	ProjectSection(ProjectDependencies) = postProject
 		{3DB7AC42-6141-417D-B2E6-7D62F08A2246} = {3DB7AC42-6141-417D-B2E6-7D62F08A2246}
+		{C1C1F046-C839-4602-AF70-923CDD237C1B} = {C1C1F046-C839-4602-AF70-923CDD237C1B}
 		{8D0540EE-F8A5-44AB-8023-AD75251167E4} = {8D0540EE-F8A5-44AB-8023-AD75251167E4}
 		{F926F7FA-099E-499C-ABC9-743BCAB919C4} = {F926F7FA-099E-499C-ABC9-743BCAB919C4}
 	EndProjectSection
@@ -912,6 +913,7 @@ Global
 		{3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|Win32.ActiveCfg = Release|Win32
 		{3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|Win32.Build.0 = Release|Win32
 		{3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|x64.ActiveCfg = Release|x64
+		{3DB7AC42-6141-417D-B2E6-7D62F08A2246}.Release|x64.Build.0 = Release|x64
 		{4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
 		{4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Debug|Mixed Platforms.Build.0 = Debug|Win32
 		{4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -923,6 +925,7 @@ Global
 		{4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|Win32.ActiveCfg = Release|Win32
 		{4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|Win32.Build.0 = Release|Win32
 		{4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|x64.ActiveCfg = Release|x64
+		{4A77FC81-98F6-4ABF-A489-B6F427354E5B}.Release|x64.Build.0 = Release|x64
 		{8D0540EE-F8A5-44AB-8023-AD75251167E4}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
 		{8D0540EE-F8A5-44AB-8023-AD75251167E4}.Debug|Mixed Platforms.Build.0 = Debug|Win32
 		{8D0540EE-F8A5-44AB-8023-AD75251167E4}.Debug|Win32.ActiveCfg = Debug|Win32
diff --git a/proj/xSound/vs2013/xSound.vcxproj b/proj/xSound/vs2013/xSound.vcxproj
index fc868bf74..2c2904870 100644
--- a/proj/xSound/vs2013/xSound.vcxproj
+++ b/proj/xSound/vs2013/xSound.vcxproj
@@ -68,7 +68,7 @@
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>false</LinkIncremental>
-    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../source;../../../sdks/mital/source/;</IncludePath>
+    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../sdks/;../../../source;../../../sdks/mital/source/;</IncludePath>
     <OutDir>../../../build/bin/plugins/</OutDir>
     <TargetName>$(ProjectName)_d</TargetName>
     <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);../../../libs;../../../sdks/mital/lib/;</LibraryPath>
@@ -83,11 +83,11 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
     <OutDir>../../../build/bin/plugins/</OutDir>
-    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../source;../../../sdks/mital/source/;</IncludePath>
+    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../sdks/;../../../source;../../../sdks/mital/source/;</IncludePath>
     <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);../../../libs;../../../sdks/mital/lib/;</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../source;../../../sdks/mital/source/;</IncludePath>
+    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../../../sdks/;../../../source;../../../sdks/mital/source/;</IncludePath>
     <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);../../../libs64;../../../sdks/mital/lib64/;</LibraryPath>
     <LinkIncremental>false</LinkIncremental>
     <OutDir>../../../build/bin64/plugins/</OutDir>
diff --git a/source/render/RenderPipeline.cpp b/source/render/RenderPipeline.cpp
index e6b8369b6..448f61391 100644
--- a/source/render/RenderPipeline.cpp
+++ b/source/render/RenderPipeline.cpp
@@ -33,6 +33,8 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice):
 		{"vTexUV", GXDECLTYPE_FLOAT2, GXDECLUSAGE_TEXCOORD},
 		{"vNormal", GXDECLTYPE_FLOAT3, GXDECLUSAGE_TEXCOORD1},
 		{"vPos", GXDECLTYPE_FLOAT4, GXDECLUSAGE_TEXCOORD2},
+		{"vTangent", GXDECLTYPE_FLOAT3, GXDECLUSAGE_TEXCOORD3},
+		{"vBinormal", GXDECLTYPE_FLOAT3, GXDECLUSAGE_TEXCOORD4},
 		XVERTEX_OUTPUT_DECL_END()
 	};
 	XVertexFormatHandler *pVertexFormatSceneGeneric = m_pMaterialSystem->registerVertexFormat("xSceneGeneric", voelGeneric);
-- 
GitLab