diff --git a/Content/Editor/MaterialTemplates/Terrain.shader b/Content/Editor/MaterialTemplates/Terrain.shader index b1c3a2910..a7172e381 100644 --- a/Content/Editor/MaterialTemplates/Terrain.shader +++ b/Content/Editor/MaterialTemplates/Terrain.shader @@ -112,7 +112,7 @@ MaterialInput GetGeometryMaterialInput(GeometryData geometry) #if USE_LIGHTMAP output.LightmapUV = geometry.LightmapUV; #endif - output.TBN = CalcTangentBasisFromWorldNormal(geometry.WorldNormal); + output.TBN = CalcTangentBasis(geometry.WorldNormal, geometry.WorldPosition, geometry.TexCoord); output.HolesMask = geometry.HolesMask; #if USE_TERRAIN_LAYERS output.Layers = geometry.Layers; @@ -415,7 +415,7 @@ VertexOutput VS(TerrainVertexInput input) #if USE_LIGHTMAP materialInput.LightmapUV = output.Geometry.LightmapUV; #endif - materialInput.TBN = CalcTangentBasisFromWorldNormal(output.Geometry.WorldNormal); + materialInput.TBN = tangentToWorld; materialInput.TwoSidedSign = WorldDeterminantSign; materialInput.SvPosition = output.Position; materialInput.PreSkinnedPosition = position; diff --git a/Source/Engine/Graphics/Materials/MaterialShader.h b/Source/Engine/Graphics/Materials/MaterialShader.h index 3eb6a45f8..270c60548 100644 --- a/Source/Engine/Graphics/Materials/MaterialShader.h +++ b/Source/Engine/Graphics/Materials/MaterialShader.h @@ -10,7 +10,7 @@ /// /// Current materials shader version. /// -#define MATERIAL_GRAPH_VERSION 148 +#define MATERIAL_GRAPH_VERSION 149 class Material; class GPUShader; diff --git a/Source/Shaders/MaterialCommon.hlsl b/Source/Shaders/MaterialCommon.hlsl index 8fc981cd7..bc8aa66ac 100644 --- a/Source/Shaders/MaterialCommon.hlsl +++ b/Source/Shaders/MaterialCommon.hlsl @@ -154,6 +154,22 @@ struct GBufferOutput float4 RT3 : SV_Target4; }; +float3x3 CalcTangentBasis(float3 normal, float3 pos, float2 uv) +{ + // References: + // http://www.thetenthplanet.de/archives/1180 + // https://zhangdoa.com/posts/normal-and-normal-mapping + float3 dp1 = ddx(pos); + float3 dp2 = ddy(pos); + float2 duv1 = ddx(uv); + float2 duv2 = ddy(uv); + float3 dp2perp = cross(dp2, normal); + float3 dp1perp = cross(normal, dp1); + float3 tangent = normalize(dp2perp * duv1.x + dp1perp * duv2.x); + float3 bitangent = normalize(dp2perp * duv1.y + dp1perp * duv2.y); + return float3x3(tangent, bitangent, normal); +} + float3x3 CalcTangentBasisFromWorldNormal(float3 normal) { float3 tangent = cross(normal, float3(1, 0, 0));