Skip to content

Commit

Permalink
cBloom: Fixed missing LogLuminance
Browse files Browse the repository at this point in the history
  • Loading branch information
papadanku committed Jul 6, 2024
1 parent 9f04d86 commit 4eac57e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 29 deletions.
3 changes: 2 additions & 1 deletion shaders/cAutoExposure.fx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ float4 PS_Blit(VS2PS_Quad Input) : SV_TARGET0
}

float4 Color = tex2D(CShade_SampleColorTex, Tex);
return CreateExposureTex(Color.rgb, _Frametime);
float LogLuminance = GetLogLuminance(Color.rgb);
return CreateExposureTex(LogLuminance, _Frametime);
}

float3 PS_Exposure(VS2PS_Quad Input) : SV_TARGET0
Expand Down
46 changes: 22 additions & 24 deletions shaders/cBloom.fx
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,6 @@ uniform float _Smooth <
ui_max = 1.0;
> = 0.5;

uniform float _Saturation <
ui_category = "Bloom: Input";
ui_label = "Saturation";
ui_type = "slider";
ui_min = 0.0;
ui_max = 8.0;
> = 1.0;

uniform float3 _ColorShift <
ui_category = "Bloom: Input";
ui_label = "Color Shift (RGB)";
Expand Down Expand Up @@ -161,7 +153,7 @@ CREATE_SAMPLER(SampleTempTex8, TempTex8_RGBA16F, LINEAR, CLAMP)

struct Sample
{
float3 Color;
float4 Color;
float Weight;
};

Expand All @@ -175,23 +167,27 @@ float4 PS_Prefilter(VS2PS_Quad Input) : SV_TARGET0
const float Knee = mad(_Threshold, _Smooth, 1e-5);
const float3 Curve = float3(_Threshold - Knee, Knee * 2.0, 0.25 / Knee);

float4 Color = tex2D(CShade_SampleColorTex, Input.Tex0);
float4 ColorTex = tex2D(CShade_SampleColorTex, Input.Tex0);
float4 Color = ColorTex;

#if USE_AUTOEXPOSURE
// Apply auto-exposure here
float Luma = tex2D(SampleExposureTex, Input.Tex0).r;
Color = ApplyAutoExposure(Color.rgb, Luma);
#endif

// Store log luminance in alpha channel
float LogLuminance = GetLogLuminance(ColorTex.rgb);

// Under-threshold
float Brightness = Med3(Color.r, Color.g, Color.b);
float Response_Curve = clamp(Brightness - Curve.x, 0.0, Curve.y);
Response_Curve = Curve.z * Response_Curve * Response_Curve;

// Combine and apply the brightness response curve
Color = Color * max(Response_Curve, Brightness - _Threshold) / max(Brightness, 1e-10);
Brightness = Med3(Color.r, Color.g, Color.b);
return float4(lerp(Brightness, Color.rgb, _Saturation) * _ColorShift, 1.0);

return float4(Color.rgb * _ColorShift, LogLuminance);
}

float GetKarisWeight(float3 c)
Expand All @@ -203,14 +199,14 @@ float GetKarisWeight(float3 c)
Sample GetKarisSample(sampler2D SamplerSource, float2 Tex)
{
Sample Output;
Output.Color = tex2D(SamplerSource, Tex).rgb;
Output.Weight = GetKarisWeight(Output.Color);
Output.Color = tex2D(SamplerSource, Tex);
Output.Weight = GetKarisWeight(Output.Color.rgb);
return Output;
}

float3 GetKarisAverage(Sample Group[4])
float4 GetKarisAverage(Sample Group[4])
{
float3 OutputColor = 0.0;
float4 OutputColor = 0.0;
float WeightSum = 0.0;

for (int i = 0; i < 4; i++)
Expand All @@ -219,7 +215,9 @@ float3 GetKarisAverage(Sample Group[4])
WeightSum += Group[i].Weight;
}

return OutputColor / WeightSum;
OutputColor.rgb /= WeightSum;

return OutputColor;
}

// 13-tap downsampling with Karis luma filtering
Expand Down Expand Up @@ -263,11 +261,11 @@ float4 GetPixelDownscale(VS2PS_Quad Input, sampler2D SampleSource, bool PartialK
Sample GroupD[4] = { A1, B1, A2, B2 };
Sample GroupE[4] = { B1, C1, B2, C2 };

OutputColor0 += (GetKarisAverage(GroupA) * 0.500);
OutputColor0 += (GetKarisAverage(GroupB) * 0.125);
OutputColor0 += (GetKarisAverage(GroupC) * 0.125);
OutputColor0 += (GetKarisAverage(GroupD) * 0.125);
OutputColor0 += (GetKarisAverage(GroupE) * 0.125);
OutputColor0 += (GetKarisAverage(GroupA) * (0.500 / 4.0));
OutputColor0 += (GetKarisAverage(GroupB) * (0.125 / 4.0));
OutputColor0 += (GetKarisAverage(GroupC) * (0.125 / 4.0));
OutputColor0 += (GetKarisAverage(GroupD) * (0.125 / 4.0));
OutputColor0 += (GetKarisAverage(GroupE) * (0.125 / 4.0));
}
else
{
Expand Down Expand Up @@ -321,8 +319,8 @@ CREATE_PS_DOWNSCALE(PS_Downscale8, SampleTempTex7, false)

float4 PS_GetExposure(VS2PS_Quad Input) : SV_TARGET0
{
float4 Color = tex2D(SampleTempTex8, Input.Tex0);
return CreateExposureTex(Color.rgb, _Frametime);
float LogLuminance = tex2D(SampleTempTex8, Input.Tex0).a;
return CreateExposureTex(LogLuminance, _Frametime);
}

float4 GetPixelUpscale(VS2PS_Quad Input, sampler2D SampleSource)
Expand Down
12 changes: 8 additions & 4 deletions shaders/shared/cCamera.fxh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

// AutoExposure(): https://john-chapman.github.io/2017/08/23/dynamic-local-exposure.html

float GetLogLuminance(float3 Color)
{
float Luminance = max(max(Color.r, Color.g), Color.b);
return log(max(Luminance, 1e-2));
}

#if defined(INCLUDE_CCAMERA_INPUT)
uniform float _CShadeExposureSmoothingSpeed <
ui_category = "Output: AutoExposure";
Expand All @@ -13,14 +19,12 @@
ui_max = 1.0;
> = 0.1;

float4 CreateExposureTex(float3 Color, float FrameTime)
float4 CreateExposureTex(float Luminance, float FrameTime)
{
float3 Luma = max(Color.r, max(Color.g, Color.b));

// .rgb = Output the highest brightness out of red/green/blue component
// .a = Output the weight for temporal blending
float Delay = 1e-3 * FrameTime;
return float4(log(max(Luma, 1e-2)), saturate(Delay * _CShadeExposureSmoothingSpeed));
return float4((float3)Luminance, saturate(Delay * _CShadeExposureSmoothingSpeed));
}
#endif

Expand Down

0 comments on commit 4eac57e

Please sign in to comment.