diff --git a/Helpers.hlsli b/Helpers.hlsli index ff263fa..6c65d04 100644 --- a/Helpers.hlsli +++ b/Helpers.hlsli @@ -60,4 +60,14 @@ float getFresnel(float3 normal, float3 view, float specularValue) return specularValue + (1 - specularValue) * pow(1 - saturate(dot(normal, view)), 5); } +// gets normal: n*TBN, where n = sampled normal map, N = normal vector, T = processed tangent vector (t*N-dot(t,N), B = processed bitangent vector (cross(T,N)) +float3 getNormal(SamplerState normalSampler, Texture2D map, float2 uv, float3 normal, float3 tangent, float intensity) +{ + float3 n = map.Sample(normalSampler, uv).rgb * 2 - 1; + float3 T = normalize(tangent - normal * dot(tangent, normal)) * intensity; + float3 B = cross(T, normal); + float3x3 TBN = float3x3(T, B, normal); + return mul(n, TBN); +} + #endif diff --git a/SimplePixelPBR.hlsl b/SimplePixelPBR.hlsl index 9115942..29a8a25 100644 --- a/SimplePixelPBR.hlsl +++ b/SimplePixelPBR.hlsl @@ -35,11 +35,7 @@ float4 main(VertexToPixel input) : SV_TARGET float4 albedo = pow(Albedo.Sample(Sampler, input.uv), 2.2f); - float3 N = Normal.Sample(Sampler, input.uv).rgb * 2 - 1; - float3 T = normalize(input.tangent - input.normal * dot(input.tangent, input.normal)) * normalIntensity; - float3 B = cross(T, input.normal); - float3x3 TBN = float3x3(T, B, input.normal); - input.normal = mul(N, TBN); + float3 normal = getNormal(Sampler, Normal, input.uv, input.normal, input.tangent, normalIntensity); float roughness = Roughness.Sample(Sampler, input.uv).r; float metalness = Metalness.Sample(Sampler, input.uv).r; @@ -51,10 +47,10 @@ float4 main(VertexToPixel input) : SV_TARGET switch (lights[i].Type) { case LIGHT_TYPE_DIRECTIONAL: - light += directionalLightPBR(lights[i], input.normal, view, roughness, metalness, albedo, specular); + light += directionalLightPBR(lights[i], normal, view, roughness, metalness, albedo, specular); break; case LIGHT_TYPE_POINT: - light += pointLightPBR(lights[i], input.normal, view, roughness, metalness, albedo, specular, input.worldPosition); + light += pointLightPBR(lights[i], normal, view, roughness, metalness, albedo, specular, input.worldPosition); break; } } diff --git a/SimplePixelShader.hlsl b/SimplePixelShader.hlsl index 529baec..6bad9a4 100644 --- a/SimplePixelShader.hlsl +++ b/SimplePixelShader.hlsl @@ -45,6 +45,7 @@ float4 main(VertexToPixel input) : SV_TARGET // ensure input normals are normalized input.normal = normalize(input.normal); input.tangent = normalize(input.tangent); + float3 normal = input.normal; float3 surface = tint; float alphaValue = alpha; @@ -59,11 +60,7 @@ float4 main(VertexToPixel input) : SV_TARGET if (hasNormalMap > 0) { - float3 unpackedNormal = Normal.Sample(BasicSampler, input.uv).rgb * 2 - 1; - float3 T = normalize(input.tangent - input.normal * dot(input.tangent, input.normal)) * normalIntensity; - float3 B = cross(T, input.normal); - float3x3 TBN = float3x3(T, B, input.normal); - input.normal = mul(unpackedNormal, TBN); + normal = getNormal(BasicSampler, Normal, input.uv, input.normal, input.tangent, normalIntensity); } input.uv = input.uv * scale + offset; @@ -82,10 +79,10 @@ float4 main(VertexToPixel input) : SV_TARGET switch (lights[i].Type) { case LIGHT_TYPE_DIRECTIONAL: - light += calculateDirectionalLight(lights[i], -input.normal, view, roughness, surface, specular); + light += calculateDirectionalLight(lights[i], -normal, view, roughness, surface, specular); break; case LIGHT_TYPE_POINT: - light += calculatePointLight(lights[i], input.normal, view, input.worldPosition, roughness, surface, specular); + light += calculatePointLight(lights[i], normal, view, input.worldPosition, roughness, surface, specular); break; } } @@ -94,9 +91,9 @@ float4 main(VertexToPixel input) : SV_TARGET if (hasReflectionMap > 0) { - float3 reflVec = getReflection(view, input.normal); + float3 reflVec = getReflection(view, normal); float3 reflCol = Reflection.Sample(BasicSampler, reflVec).rgba; - final = lerp(final, reflCol, getFresnel(input.normal, view, F0_NON_METAL)); + final = lerp(final, reflCol, getFresnel(normal, view, F0_NON_METAL)); } return float4(pow(final, 1.0f/2.2f), alphaValue); diff --git a/ToonShader.hlsl b/ToonShader.hlsl index 9390cd9..c162b38 100644 --- a/ToonShader.hlsl +++ b/ToonShader.hlsl @@ -85,11 +85,7 @@ float4 main(VertexToPixel input) : SV_TARGET if (hasNormalMap > 0) { - float3 unpackedNormal = Normal.Sample(BasicSampler, input.uv).rgb * 2 - 1; - float3 T = normalize(input.tangent - input.normal * dot(input.tangent, input.normal)) * normalIntensity; - float3 B = cross(T, input.normal); - float3x3 TBN = float3x3(T, B, input.normal); - normal = mul(unpackedNormal, TBN); + normal = getNormal(BasicSampler, Normal, input.uv, input.normal, input.tangent, normalIntensity); } float specularValue = 1;