diff --git a/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli b/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli index 86e20dac97..91963fc3cc 100644 --- a/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli +++ b/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli @@ -10,6 +10,7 @@ struct DisplacementParams float DisplacementScale; float DisplacementOffset; float HeightScale; + float FlattenAmount; }; namespace ExtendedMaterials @@ -181,7 +182,11 @@ namespace ExtendedMaterials #endif { float3 viewDirTS = normalize(mul(tbn, viewDir)); - viewDirTS.xy /= viewDirTS.z * 0.7 + 0.3; // Fix for objects at extreme viewing angles +#if defined(LANDSCAPE) + viewDirTS.xy /= viewDirTS.z * 0.7 + 0.3 + params[0].FlattenAmount; // Fix for objects at extreme viewing angles +#else + viewDirTS.xy /= viewDirTS.z * 0.7 + 0.3 + params.FlattenAmount; // Fix for objects at extreme viewing angles +#endif float nearBlendToFar = saturate(distance / 2048.0); #if defined(LANDSCAPE) diff --git a/package/Shaders/Common/SharedData.hlsli b/package/Shaders/Common/SharedData.hlsli index 272ed8f6c8..c1e791b787 100644 --- a/package/Shaders/Common/SharedData.hlsli +++ b/package/Shaders/Common/SharedData.hlsli @@ -42,7 +42,8 @@ namespace SharedData bool EnableHeightBlending; bool EnableShadows; bool ExtendShadows; - float2 pad0; + bool EnableParallaxWarpingFix; + float1 pad0; }; struct CubemapCreatorSettings diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index b01a00dc29..504214f588 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -1074,14 +1074,49 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace DisplacementParams displacementParams[6]; displacementParams[0].DisplacementScale = 1.f; displacementParams[0].DisplacementOffset = 0.f; - displacementParams[0].HeightScale = 1.f; + displacementParams[0].HeightScale = 1; + displacementParams[0].FlattenAmount = 0; # else DisplacementParams displacementParams; displacementParams.DisplacementScale = 1.f; displacementParams.DisplacementOffset = 0.f; - displacementParams.HeightScale = 1.f; + displacementParams.HeightScale = 1; + displacementParams.FlattenAmount = 0; # endif +# endif + + float curvature = 0; + float normalSmoothness = 0; + +# if !defined(MODELSPACENORMALS) + float3 vertexNormal = tbnTr[2]; + float3 worldSpaceVertexNormal = vertexNormal; + +# if !defined(DRAW_IN_WORLDSPACE) + [flatten] if (!input.WorldSpace) + worldSpaceVertexNormal = normalize(mul(input.World[eyeIndex], float4(worldSpaceVertexNormal, 0))); +# endif +# if defined(EMAT) + + if (SharedData::extendedMaterialSettings.EnableParallaxWarpingFix) { + float3 ndx = ddx(worldSpaceVertexNormal); + float3 ndy = ddy(worldSpaceVertexNormal); + float3 fdx = ddx(input.WorldPosition.xyz); + float3 fdy = ddy(input.WorldPosition.xyz); + float fragSize = rcp(length(max(abs(fdx), abs(fdy)))); + curvature = pow(length(max(abs(ndx), abs(ndy))) * fragSize, 0.5); + float3 flatWorldNormal = normalize(-cross(ddx(input.WorldPosition.xyz), ddy(input.WorldPosition.xyz))); + normalSmoothness = (1 - dot(worldSpaceVertexNormal, flatWorldNormal)); +# if defined(LANDSCAPE) + displacementParams[0].HeightScale = saturate(1 - curvature); + displacementParams[0].FlattenAmount = (normalSmoothness + curvature); +# else + displacementParams.HeightScale = saturate(1 - curvature); + displacementParams.FlattenAmount = (normalSmoothness + curvature); +# endif + } +# endif # endif float3 entryNormal = 0; @@ -1129,9 +1164,9 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace [branch] if (SharedData::extendedMaterialSettings.EnableParallax && (PBRFlags & PBR::Flags::HasDisplacement) != 0) { PBRParallax = true; - displacementParams.HeightScale = PBRParams1.y; [branch] if ((PBRFlags & PBR::Flags::InterlayerParallax) != 0) { + displacementParams.HeightScale = PBRParams1.y; displacementParams.DisplacementScale = 0.5; displacementParams.DisplacementOffset = -0.25; eta = (1 - sqrt(MultiLayerParallaxData.y)) / (1 + sqrt(MultiLayerParallaxData.y)); @@ -1147,6 +1182,10 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace refractedViewDirection = -refract(-viewDirection, entryNormal, eta); refractedViewDirectionWS = normalize(mul(input.World[eyeIndex], float4(refractedViewDirection, 0))); } + else + { + displacementParams.HeightScale *= PBRParams1.y; + } mipLevel = ExtendedMaterials::GetMipLevel(uv, TexParallaxSampler); uv = ExtendedMaterials::GetParallaxCoords(viewPosition.z, uv, mipLevel, refractedViewDirection, tbnTr, screenNoise, TexParallaxSampler, SampParallaxSampler, 0, displacementParams, pixelOffset); if (SharedData::extendedMaterialSettings.EnableShadows && (parallaxShadowQuality > 0.0f || SharedData::extendedMaterialSettings.ExtendShadows)) @@ -1203,12 +1242,12 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace displacementParams[4] = displacementParams[0]; displacementParams[5] = displacementParams[0]; # if defined(TRUE_PBR) - displacementParams[0].HeightScale = PBRParams1.y; - displacementParams[1].HeightScale = LandscapeTexture2PBRParams.y; - displacementParams[2].HeightScale = LandscapeTexture3PBRParams.y; - displacementParams[3].HeightScale = LandscapeTexture4PBRParams.y; - displacementParams[4].HeightScale = LandscapeTexture5PBRParams.y; - displacementParams[5].HeightScale = LandscapeTexture6PBRParams.y; + displacementParams[0].HeightScale *= PBRParams1.y; + displacementParams[1].HeightScale *= LandscapeTexture2PBRParams.y; + displacementParams[2].HeightScale *= LandscapeTexture3PBRParams.y; + displacementParams[3].HeightScale *= LandscapeTexture4PBRParams.y; + displacementParams[4].HeightScale *= LandscapeTexture5PBRParams.y; + displacementParams[5].HeightScale *= LandscapeTexture6PBRParams.y; # endif float weights[6]; @@ -1628,6 +1667,10 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace worldSpaceNormal = normalize(mul(input.World[eyeIndex], float4(worldSpaceNormal, 0))); # endif +# if defined(MODELSPACENORMALS) + float3 worldSpaceVertexNormal = worldSpaceNormal; +# endif + float3 screenSpaceNormal = normalize(FrameBuffer::WorldToView(worldSpaceNormal, false, eyeIndex)); # if defined(TRUE_PBR) @@ -1726,18 +1769,6 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace float pbrGlossiness = 1 - pbrSurfaceProperties.Roughness; # endif // TRUE_PBR -# if !defined(MODELSPACENORMALS) - float3 vertexNormal = tbnTr[2]; - float3 worldSpaceVertexNormal = vertexNormal; - -# if !defined(DRAW_IN_WORLDSPACE) - [flatten] if (!input.WorldSpace) - worldSpaceVertexNormal = normalize(mul(input.World[eyeIndex], float4(worldSpaceVertexNormal, 0))); -# endif -# else - float3 worldSpaceVertexNormal = worldSpaceNormal; -# endif - float porosity = 1.0; # if defined(SKYLIGHTING) diff --git a/src/Features/ExtendedMaterials.cpp b/src/Features/ExtendedMaterials.cpp index 0045b0f3b2..c3610c3e78 100644 --- a/src/Features/ExtendedMaterials.cpp +++ b/src/Features/ExtendedMaterials.cpp @@ -9,7 +9,8 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT( EnableTerrain, EnableHeightBlending, EnableShadows, - ExtendShadows) + ExtendShadows, + EnableParallaxWarpingFix) void ExtendedMaterials::DataLoaded() { @@ -59,6 +60,10 @@ void ExtendedMaterials::DrawSettings() if (auto _tt = Util::HoverTooltipWrapper()) { ImGui::Text("Enables landscape texture blending based on parallax. "); } + ImGui::Checkbox("Enable Parallax Warping Fix", (bool*)&settings.EnableParallaxWarpingFix); + if (auto _tt = Util::HoverTooltipWrapper()) { + ImGui::Text("Enables a fix reducing parallax scale on curved and smooth normal triangles."); + } ImGui::Spacing(); ImGui::Spacing(); diff --git a/src/Features/ExtendedMaterials.h b/src/Features/ExtendedMaterials.h index ffc7f4898a..1bd4649467 100644 --- a/src/Features/ExtendedMaterials.h +++ b/src/Features/ExtendedMaterials.h @@ -26,8 +26,9 @@ struct ExtendedMaterials : Feature uint EnableShadows = 1; uint ExtendShadows = 0; + uint EnableParallaxWarpingFix = 1; - float pad[2]; + float pad[1]; }; Settings settings;