diff --git a/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli b/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli index df6570a88b..8c5fe21643 100644 --- a/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli +++ b/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli @@ -51,10 +51,10 @@ namespace ExtendedMaterials float2 dySize = ddy(texCoordsPerSize); // Find min of change in u and v across quad: compute du and dv magnitude across quad - float2 dTexCoords = dxSize * dxSize + dySize * dySize; + //float2 dTexCoords = dxSize * dxSize + dySize * dySize; // Standard mipmapping uses max here - float minTexCoordDelta = max(dTexCoords.x, dTexCoords.y); + float minTexCoordDelta = min(dot(dxSize, dxSize), dot(dySize, dySize)); // Compute the current mip level (* 0.5 is effectively computing a square root before ) float mipLevel = max(0.5 * log2(minTexCoordDelta), 0); @@ -72,8 +72,8 @@ namespace ExtendedMaterials #if defined(LANDSCAPE) # if defined(TRUE_PBR) -# define HEIGHT_POWER 20 -# define HEIGHT_MULT 2 +# define HEIGHT_POWER 2 +# define HEIGHT_MULT 8 float GetTerrainHeight(PS_INPUT input, float2 coords, float mipLevels[6], DisplacementParams params[6], float blendFactor, float4 w1, float2 w2, out float weights[6]) { float heightBlend = 1 + blendFactor * HEIGHT_POWER; @@ -120,6 +120,10 @@ namespace ExtendedMaterials total += h * weights[5]; weights[5] *= pow(heightBlend, HEIGHT_MULT * h); } + [unroll] for (int i = 0; i < 6; i++) + { + weights[i] = pow(weights[i], heightBlend); + } float wsum = 0; [unroll] for (int i = 0; i < 6; i++) { @@ -133,8 +137,8 @@ namespace ExtendedMaterials return total; } # else -# define HEIGHT_POWER 20 -# define HEIGHT_MULT 2 +# define HEIGHT_POWER 2 +# define HEIGHT_MULT 8 float GetTerrainHeight(PS_INPUT input, float2 coords, float mipLevels[6], DisplacementParams params[6], float blendFactor, float4 w1, float2 w2, out float weights[6]) { float heightBlend = 1 + blendFactor * HEIGHT_POWER; @@ -175,7 +179,10 @@ namespace ExtendedMaterials total += h * weights[5]; weights[5] *= pow(heightBlend, HEIGHT_MULT * h); } - + [unroll] for (int i = 0; i < 6; i++) + { + weights[i] = pow(weights[i], heightBlend); + } float wsum = 0; [unroll] for (int i = 0; i < 6; i++) { @@ -207,7 +214,6 @@ namespace ExtendedMaterials float nearBlendToFar = saturate(distance / 2048.0); #if defined(LANDSCAPE) -// When CPM flag is disabled, will use linear blending as before. # if defined(TRUE_PBR) float blendFactor = SharedData::extendedMaterialSettings.EnableHeightBlending ? sqrt(saturate(1 - nearBlendToFar)) : 0; float4 w1 = lerp(input.LandBlendWeights1, smoothstep(0, 1, input.LandBlendWeights1), blendFactor); @@ -230,7 +236,7 @@ namespace ExtendedMaterials #if defined(LANDSCAPE) if (nearBlendToFar < 1.0) { - uint numSteps = uint((max(4, scale * 8) * (1.0 - nearBlendToFar)) + 0.5); + uint numSteps = uint((max(6, scale * 8) * (1.0 - nearBlendToFar)) + 0.5); numSteps = clamp((numSteps + 3) & ~0x03, 4, max(8, scale * 8)); #else # if defined(TRUE_PBR) @@ -372,12 +378,6 @@ namespace ExtendedMaterials return coords; } -#if defined(TRUE_PBR) - static const float shadowIntensity = 2.0; -#else - static const float shadowIntensity = 2.0; -#endif - // https://advances.realtimerendering.com/s2006/Tatarchuk-POM.pdf // Cheap method of creating shadows using height for a given light source float GetParallaxSoftShadowMultiplier(float2 coords, float mipLevel, float3 L, float sh0, Texture2D tex, SamplerState texSampler, uint channel, float quality, float noise, DisplacementParams params) @@ -394,7 +394,7 @@ namespace ExtendedMaterials sh.z = AdjustDisplacementNormalized(tex.SampleLevel(texSampler, coords + rayDir * multipliers.z, mipLevel)[channel], params); if (quality > 0.75) sh.w = AdjustDisplacementNormalized(tex.SampleLevel(texSampler, coords + rayDir * multipliers.w, mipLevel)[channel], params); - return 1.0 - saturate(dot(max(0, sh - sh0), 1.0) * shadowIntensity) * quality; + return pow(1.0 - saturate(dot(max(0, sh - sh0), 1.0)) * quality, 2.0); } return 1.0; } @@ -403,13 +403,15 @@ namespace ExtendedMaterials float GetParallaxSoftShadowMultiplierTerrain(PS_INPUT input, float2 coords, float mipLevel[6], float3 L, float sh0, float quality, float noise, DisplacementParams params[6]) { if (quality > 0.0) { - float2 rayDir = L.xy * 0.1; float4 multipliers = rcp((float4(1, 2, 3, 4) + noise)); float4 sh; float heights[6] = { 0, 0, 0, 0, 0, 0 }; + float2 rayDir = L.xy * 0.1; # if defined(TRUE_PBR) float scale = max(params[0].HeightScale * input.LandBlendWeights1.x, max(params[1].HeightScale * input.LandBlendWeights1.y, max(params[2].HeightScale * input.LandBlendWeights1.z, max(params[3].HeightScale * input.LandBlendWeights1.w, max(params[4].HeightScale * input.LandBlendWeights2.x, params[5].HeightScale * input.LandBlendWeights2.y))))); + if (scale < 0.01) + return 1.0; rayDir *= scale; sh = GetTerrainHeight(input, coords + rayDir * multipliers.x, mipLevel, params, quality, input.LandBlendWeights1, input.LandBlendWeights2.xy, heights); if (quality > 0.25) @@ -418,7 +420,7 @@ namespace ExtendedMaterials sh.z = GetTerrainHeight(input, coords + rayDir * multipliers.z, mipLevel, params, quality, input.LandBlendWeights1, input.LandBlendWeights2.xy, heights); if (quality > 0.75) sh.w = GetTerrainHeight(input, coords + rayDir * multipliers.w, mipLevel, params, quality, input.LandBlendWeights1, input.LandBlendWeights2.xy, heights); - return 1.0 - saturate(dot(max(0, sh - sh0), 1.0) * shadowIntensity) * quality; + return pow(1.0 - saturate(dot(max(0, sh - sh0) / scale, 1.0)) * quality, 2.0); # else sh = GetTerrainHeight(input, coords + rayDir * multipliers.x, mipLevel, params, quality, input.LandBlendWeights1, input.LandBlendWeights2.xy, heights); if (quality > 0.25) @@ -427,7 +429,7 @@ namespace ExtendedMaterials sh.z = GetTerrainHeight(input, coords + rayDir * multipliers.z, mipLevel, params, quality, input.LandBlendWeights1, input.LandBlendWeights2.xy, heights); if (quality > 0.75) sh.w = GetTerrainHeight(input, coords + rayDir * multipliers.w, mipLevel, params, quality, input.LandBlendWeights1, input.LandBlendWeights2.xy, heights); - return 1.0 - saturate(dot(max(0, sh - sh0), 1.0) * shadowIntensity) * quality; + return pow(1.0 - saturate(dot(max(0, sh - sh0), 1.0)) * quality, 2.0); # endif } return 1.0;