Fix sky, skylight and reflections banding artifacts with a random noise

#3254 #3318
This commit is contained in:
Wojtek Figat
2026-01-13 13:12:19 +01:00
parent b4b13d8dd4
commit 14842183f2
7 changed files with 26 additions and 9 deletions

BIN
Content/Shaders/Lights.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/Reflections.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/Sky.flax (Stored with Git LFS)

Binary file not shown.

View File

@@ -24,7 +24,7 @@ GPU_CB_STRUCT(Data {
Matrix WorldViewProjection;
Matrix InvViewProjection;
Float3 ViewOffset;
float Padding;
float NoiseScale;
ShaderGBufferData GBuffer;
ShaderAtmosphericFogData Fog;
});
@@ -184,6 +184,7 @@ void Sky::ApplySky(GPUContext* context, RenderContext& renderContext, const Matr
Matrix::Transpose(renderContext.View.IVP, data.InvViewProjection);
GBufferPass::SetInputs(renderContext.View, data.GBuffer);
data.ViewOffset = renderContext.View.Origin + GetPosition();
data.NoiseScale = renderContext.View.IsSingleFrame ? 0.01f : 0.03f;
InitConfig(data.Fog);
//data.Fog.AtmosphericFogSunPower *= SunLight ? SunLight->Brightness : 1.0f;
if (EnumHasNoneFlags(renderContext.View.Flags, ViewFlags::SpecularLight))

View File

@@ -8,6 +8,7 @@
#include "./Flax/IESProfile.hlsl"
#include "./Flax/GBuffer.hlsl"
#include "./Flax/Lighting.hlsl"
#include "./Flax/Noise.hlsl"
// Per light data
META_CB_BEGIN(0, PerLight)
@@ -168,6 +169,9 @@ float4 PS_Sky(Model_VS2PS input) : SV_Target0
if (gBuffer.ShadingModel != SHADING_MODEL_UNLIT)
{
output = GetSkyLightLighting(Light, gBuffer, CubeImage);
// Apply dithering to hide banding artifacts
output.rgb += rand2dTo1d(uv) * 0.02f * Luminance(saturate(output.rgb));
}
return output;

View File

@@ -4,6 +4,7 @@
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/BRDF.hlsl"
#include "./Flax/Random.hlsl"
#include "./Flax/Noise.hlsl"
#include "./Flax/MonteCarlo.hlsl"
#include "./Flax/LightingCommon.hlsl"
#include "./Flax/GBuffer.hlsl"
@@ -55,7 +56,12 @@ float4 PS_EnvProbe(Model_VS2PS input) : SV_Target0
}
// Sample probe
return SampleReflectionProbe(gBufferData.ViewPos, Probe, PData, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness);
float4 color = SampleReflectionProbe(gBufferData.ViewPos, Probe, PData, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness);
// Apply dithering to hide banding artifacts
color.rgb += rand2dTo1d(uv) * 0.02f * Luminance(saturate(color.rgb));
return color;
}
// Pixel Shader for reflections combine pass (additive rendering to the light buffer)

View File

@@ -4,13 +4,14 @@
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/GBuffer.hlsl"
#include "./Flax/Common.hlsl"
#include "./Flax/Noise.hlsl"
#include "./Flax/AtmosphereFog.hlsl"
META_CB_BEGIN(0, Data)
float4x4 WorldViewProjection;
float4x4 InvViewProjection;
float3 ViewOffset;
float Padding;
float NoiseScale;
GBufferData GBuffer;
AtmosphericFogData AtmosphericFog;
META_CB_END
@@ -53,6 +54,11 @@ GBufferOutput PS_Sky(MaterialInput input)
// Sample atmosphere color
float4 color = GetAtmosphericFog(AtmosphericFog, gBufferData.ViewFar, gBufferData.ViewPos + ViewOffset, viewVector, gBufferData.ViewFar, float3(0, 0, 0));
// Apply dithering to hide banding artifacts
float2 uv = (input.ScreenPos.xy / input.ScreenPos.w) * float2(0.5, -0.5) + float2(0.5, 0.5);
float luminance = Luminance(saturate(color.rgb));
color.rgb += rand2dTo1d(uv) * luminance * NoiseScale;
// Pack GBuffer
output.Light = color;
output.RT0 = float4(0, 0, 0, 0);