diff --git a/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli b/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli index 63e3cf8ec4..375238aec7 100644 --- a/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli +++ b/features/Extended Materials/Shaders/ExtendedMaterials/ExtendedMaterials.hlsli @@ -35,7 +35,7 @@ namespace ExtendedMaterials return float4(AdjustDisplacementNormalized(displacement.x, params), AdjustDisplacementNormalized(displacement.y, params), AdjustDisplacementNormalized(displacement.z, params), AdjustDisplacementNormalized(displacement.w, params)); } - float GetMipLevel(float2 coords, Texture2D tex) + float GetMipLevel(float2 coords, Texture2D tex, float screenNoise) { // Compute the current gradients: float2 textureDims; @@ -72,6 +72,9 @@ namespace ExtendedMaterials mipLevel++; #endif + // Stochastic mip selection: use screen noise to select between adjacent mip levels + mipLevel = floor(mipLevel) + (screenNoise < frac(mipLevel) ? 1.0 : 0.0); + return mipLevel; } @@ -349,8 +352,6 @@ namespace ExtendedMaterials #if defined(LANDSCAPE) if (nearBlendToFar < 1.0) { - 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) if ((PBRFlags & PBR::Flags::InterlayerParallax) != 0 || nearBlendToFar < 1.0) @@ -358,12 +359,12 @@ namespace ExtendedMaterials if (nearBlendToFar < 1.0) # endif { +#endif float maxSteps = SharedData::InInterior ? 8 : 16; uint numSteps = uint((maxSteps * (1.0 - nearBlendToFar)) + 0.5); - numSteps = clamp((numSteps + 3) & ~0x03, 4, max(6, scale * maxSteps)); -#endif + numSteps = clamp(numSteps, 1, max(6, scale * maxSteps)); + float stepSize = rcp(numSteps); - stepSize += (noise * 2.0 - 1.0) * stepSize * stepSize; float2 offsetPerStep = viewDirTS.xy * float2(maxHeight, maxHeight) * stepSize.xx; float2 prevOffset = viewDirTS.xy * float2(minHeight, minHeight) + coords.xy; diff --git a/features/Extended Materials/Shaders/Features/ExtendedMaterials.ini b/features/Extended Materials/Shaders/Features/ExtendedMaterials.ini index 312d7ff985..de2206be54 100644 --- a/features/Extended Materials/Shaders/Features/ExtendedMaterials.ini +++ b/features/Extended Materials/Shaders/Features/ExtendedMaterials.ini @@ -1,2 +1,2 @@ [Info] -Version = 1-1-0 \ No newline at end of file +Version = 1-1-1 \ No newline at end of file diff --git a/features/Water Effects/Shaders/WaterEffects/WaterParallax.hlsli b/features/Water Effects/Shaders/WaterEffects/WaterParallax.hlsli index 36023b743f..8957cd3dcd 100644 --- a/features/Water Effects/Shaders/WaterEffects/WaterParallax.hlsli +++ b/features/Water Effects/Shaders/WaterEffects/WaterParallax.hlsli @@ -7,7 +7,7 @@ namespace WaterEffects // http://www.diva-portal.org/smash/get/diva2:831762/FULLTEXT01.pdf // https://bartwronski.files.wordpress.com/2014/03/ac4_gdc.pdf - float GetMipLevel(float2 coords, Texture2D tex) + float GetMipLevel(float2 coords, Texture2D tex, float screenNoise) { // Compute the current gradients: float2 textureDims; @@ -33,6 +33,9 @@ namespace WaterEffects // Compute the current mip level (* 0.5 is effectively computing a square root before ) float mipLevel = max(0.5 * log2(minTexCoordDelta), 0); + // Stochastic mip selection: use screen noise to select between adjacent mip levels + mipLevel = floor(mipLevel) + (screenNoise < frac(mipLevel) ? 1.0 : 0.0); + return mipLevel; } @@ -54,10 +57,12 @@ namespace WaterEffects // Parallax scale is also multiplied by normalScalesRcp parallaxOffsetTS *= 20.0; + float screenNoise = Random::InterleavedGradientNoise(input.HPosition.xy, SharedData::FrameCount); + float3 mipLevels; - mipLevels.x = GetMipLevel(input.TexCoord1.xy, Normals01Tex); - mipLevels.y = GetMipLevel(input.TexCoord1.zw, Normals02Tex); - mipLevels.z = GetMipLevel(input.TexCoord2.xy, Normals03Tex); + mipLevels.x = GetMipLevel(input.TexCoord1.xy, Normals01Tex, screenNoise); + mipLevels.y = GetMipLevel(input.TexCoord1.zw, Normals02Tex, screenNoise); + mipLevels.z = GetMipLevel(input.TexCoord2.xy, Normals03Tex, screenNoise); #if defined(VR) mipLevels = mipLevels + 4; diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index c797a78c1c..c319e47332 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -1072,7 +1072,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # if defined(EMAT) # if defined(PARALLAX) if (SharedData::extendedMaterialSettings.EnableParallax) { - mipLevel = ExtendedMaterials::GetMipLevel(uv, TexParallaxSampler); + mipLevel = ExtendedMaterials::GetMipLevel(uv, TexParallaxSampler, screenNoise); uv = ExtendedMaterials::GetParallaxCoords(viewPosition.z, uv, mipLevel, viewDirection, tbnTr, screenNoise, TexParallaxSampler, SampParallaxSampler, 0, displacementParams, pixelOffset); if (SharedData::extendedMaterialSettings.EnableShadows && (parallaxShadowQuality > 0.0f || SharedData::extendedMaterialSettings.ExtendShadows)) sh0 = TexParallaxSampler.SampleLevel(SampParallaxSampler, uv, mipLevel).x; @@ -1092,7 +1092,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) if (complexMaterial) { if (envMaskTest > (4.0 / 255.0)) { complexMaterialParallax = true; - mipLevel = ExtendedMaterials::GetMipLevel(uv, TexEnvMaskSampler); + mipLevel = ExtendedMaterials::GetMipLevel(uv, TexEnvMaskSampler, screenNoise); uv = ExtendedMaterials::GetParallaxCoords(viewPosition.z, uv, mipLevel, viewDirection, tbnTr, screenNoise, TexEnvMaskSampler, SampTerrainParallaxSampler, 3, displacementParams, pixelOffset); if (SharedData::extendedMaterialSettings.EnableShadows && (parallaxShadowQuality > 0.0f || SharedData::extendedMaterialSettings.ExtendShadows)) sh0 = TexEnvMaskSampler.SampleLevel(SampEnvMaskSampler, uv, mipLevel).w; @@ -1137,7 +1137,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) { displacementParams.HeightScale *= PBRParams1.y; } - mipLevel = ExtendedMaterials::GetMipLevel(uv, TexParallaxSampler); + mipLevel = ExtendedMaterials::GetMipLevel(uv, TexParallaxSampler, screenNoise); 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)) sh0 = TexParallaxSampler.SampleLevel(SampParallaxSampler, uv, mipLevel).x; @@ -1205,12 +1205,12 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # else if (SharedData::extendedMaterialSettings.EnableTerrainParallax || (SharedData::extendedMaterialSettings.EnableParallax && Permutation::ExtraFeatureDescriptor & Permutation::ExtraFeatureFlags::THLandHasDisplacement)) { # endif - mipLevels[0] = ExtendedMaterials::GetMipLevel(uv, TexColorSampler); - mipLevels[1] = ExtendedMaterials::GetMipLevel(uv, TexLandColor2Sampler); - mipLevels[2] = ExtendedMaterials::GetMipLevel(uv, TexLandColor3Sampler); - mipLevels[3] = ExtendedMaterials::GetMipLevel(uv, TexLandColor4Sampler); - mipLevels[4] = ExtendedMaterials::GetMipLevel(uv, TexLandColor5Sampler); - mipLevels[5] = ExtendedMaterials::GetMipLevel(uv, TexLandColor6Sampler); + mipLevels[0] = ExtendedMaterials::GetMipLevel(uv, TexColorSampler, screenNoise); + mipLevels[1] = ExtendedMaterials::GetMipLevel(uv, TexLandColor2Sampler, screenNoise); + mipLevels[2] = ExtendedMaterials::GetMipLevel(uv, TexLandColor3Sampler, screenNoise); + mipLevels[3] = ExtendedMaterials::GetMipLevel(uv, TexLandColor4Sampler, screenNoise); + mipLevels[4] = ExtendedMaterials::GetMipLevel(uv, TexLandColor5Sampler, screenNoise); + mipLevels[5] = ExtendedMaterials::GetMipLevel(uv, TexLandColor6Sampler, screenNoise); displacementParams[1] = displacementParams[0]; displacementParams[2] = displacementParams[0]; @@ -1255,12 +1255,12 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # if defined(TERRAIN_VARIATION) else if (useTerrainVariation) { // Calculate proper mip levels for terrain variation when parallax is disabled but EMAT is available - mipLevels[0] = ExtendedMaterials::GetMipLevel(uv, TexColorSampler); - mipLevels[1] = ExtendedMaterials::GetMipLevel(uv, TexLandColor2Sampler); - mipLevels[2] = ExtendedMaterials::GetMipLevel(uv, TexLandColor3Sampler); - mipLevels[3] = ExtendedMaterials::GetMipLevel(uv, TexLandColor4Sampler); - mipLevels[4] = ExtendedMaterials::GetMipLevel(uv, TexLandColor5Sampler); - mipLevels[5] = ExtendedMaterials::GetMipLevel(uv, TexLandColor6Sampler); + mipLevels[0] = ExtendedMaterials::GetMipLevel(uv, TexColorSampler, screenNoise); + mipLevels[1] = ExtendedMaterials::GetMipLevel(uv, TexLandColor2Sampler, screenNoise); + mipLevels[2] = ExtendedMaterials::GetMipLevel(uv, TexLandColor3Sampler, screenNoise); + mipLevels[3] = ExtendedMaterials::GetMipLevel(uv, TexLandColor4Sampler, screenNoise); + mipLevels[4] = ExtendedMaterials::GetMipLevel(uv, TexLandColor5Sampler, screenNoise); + mipLevels[5] = ExtendedMaterials::GetMipLevel(uv, TexLandColor6Sampler, screenNoise); } # endif # else