From f962f3d8164e522c94756f22b6c667d214a724f9 Mon Sep 17 00:00:00 2001 From: hershey5045 <43485729+hershey5045@users.noreply.github.com> Date: Fri, 22 Oct 2021 09:53:48 -0700 Subject: [PATCH] White Balance Updates (#4887) * Implement simple tint for white balance color grading. Adjust temperature slider to feel linear. Signed-off-by: rbarrand * Change white balance luminance preservation equation and remove unused code. Signed-off-by: rbarrand Co-authored-by: rbarrand --- .../Features/PostProcessing/KelvinToRgb.azsli | 33 ------------------- .../PostProcessing/HDRColorGradingCommon.azsl | 21 +++++++++--- .../Shaders/ColorGrading/LutGeneration.azsl | 1 + .../PostProcessing/HDRColorGrading.azsl | 1 + .../ColorGrading/HDRColorGradingParams.inl | 1 + .../PostProcessing/HDRColorGradingPass.cpp | 3 +- .../PostProcessing/HDRColorGradingPass.h | 1 + .../EditorHDRColorGradingComponent.cpp | 4 +++ 8 files changed, 27 insertions(+), 38 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/3rdParty/Features/PostProcessing/KelvinToRgb.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/3rdParty/Features/PostProcessing/KelvinToRgb.azsli index aa57f0f4a1..1c8b77df45 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/3rdParty/Features/PostProcessing/KelvinToRgb.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/3rdParty/Features/PostProcessing/KelvinToRgb.azsli @@ -16,39 +16,6 @@ // licensed and released under Creative Commons 3.0 Attribution // https://creativecommons.org/licenses/by/3.0/ -float3 HueToRgb(float hue) -{ - return saturate(float3(abs(hue * 6.0f - 3.0f) - 1.0f, - 2.0f - abs(hue * 6.0f - 2.0f), - 2.0f - abs(hue * 6.0f - 4.0f))); -} - -float3 RgbToHcv(float3 rgb) -{ - // Based on work by Sam Hocevar and Emil Persson - const float4 p = (rgb.g < rgb.b) ? float4(rgb.bg, -1.0f, 2.0f/3.0f) : float4(rgb.gb, 0.0f, -1.0f/3.0f); - const float4 q1 = (rgb.r < p.x) ? float4(p.xyw, rgb.r) : float4(rgb.r, p.yzx); - const float c = q1.x - min(q1.w, q1.y); - const float h = abs((q1.w - q1.y) / (6.0f * c + 0.000001f ) + q1.z); - return float3(h, c, q1.x); -} - -float3 RgbToHsl(float3 rgb) -{ - rgb.xyz = max(rgb.xyz, 0.000001f); - const float3 hcv = RgbToHcv(rgb); - const float L = hcv.z - hcv.y * 0.5f; - const float S = hcv.y / (1.0f - abs(L * 2.0f - 1.0f) + 0.000001f); - return float3(hcv.x, S, L); -} - -float3 HslToRgb(float3 hsl) -{ - const float3 rgb = HueToRgb(hsl.x); - const float c = (1.0f - abs(2.0f * hsl.z - 1.0f)) * hsl.y; - return (rgb - 0.5f) * c + hsl.z; -} - // Color temperature float3 KelvinToRgb(float kelvin) { diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PostProcessing/HDRColorGradingCommon.azsl b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PostProcessing/HDRColorGradingCommon.azsl index a380a0a547..423d447f7b 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PostProcessing/HDRColorGradingCommon.azsl +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PostProcessing/HDRColorGradingCommon.azsl @@ -66,12 +66,21 @@ float3 ColorGradeSaturation (float3 frameColor, float control) return (frameColor - vLuminance) * control + vLuminance; } -float3 ColorGradeKelvinColorTemp(float3 frameColor, float kelvin) +float3 ColorGradeWhiteBalance(float3 frameColor, float kelvin, float tint, float luminancePreservation) { const float3 kColor = TransformColor(KelvinToRgb(kelvin), ColorSpaceId::LinearSRGB, ColorSpaceId::ACEScg); const float luminance = CalculateLuminance(frameColor, ColorSpaceId::ACEScg); - const float3 resHsl = RgbToHsl(frameColor.rgb * kColor.rgb); // Apply Kelvin color and convert to HSL - return HslToRgb(float3(resHsl.xy, luminance)); // Preserve luminance + + // Apply Kelvin color and tint and calculate the new luminance + float3 adjustedColor = frameColor.rgb * kColor.rgb; + adjustedColor.g = max(0.0, adjustedColor.g + tint * 0.001); + const float adjustedLuminance = CalculateLuminance(adjustedColor, ColorSpaceId::ACEScg); + + // Adjust the color based on the difference in luminance. + const float luminanceDifferenceRatio = luminance / adjustedLuminance; + const float3 adjustedColorLumPreserved = adjustedColor * luminanceDifferenceRatio; + + return lerp(adjustedColor, adjustedColorLumPreserved, luminancePreservation); } // pow(f, e) won't work if f is negative, or may cause inf/NAN. @@ -132,7 +141,11 @@ float3 ColorGradeShadowsMidtonesHighlights (float3 frameColor, float shadowsStar float3 ColorGrade(float3 frameColor) { frameColor = lerp(frameColor, ColorGradePostExposure(frameColor, PassSrg::m_colorGradingExposure), PassSrg::m_colorAdjustmentWeight); - frameColor = lerp(frameColor, ColorGradeKelvinColorTemp(frameColor, PassSrg::m_whiteBalanceKelvin), PassSrg::m_whiteBalanceWeight); + frameColor = lerp(frameColor, ColorGradeWhiteBalance( + frameColor, PassSrg::m_whiteBalanceKelvin, + PassSrg::m_whiteBalanceTint, + PassSrg::m_whiteBalanceLuminancePreservation), + PassSrg::m_whiteBalanceWeight); frameColor = lerp(frameColor, ColorGradingContrast(frameColor, AcesCcMidGrey, PassSrg::m_colorGradingContrast), PassSrg::m_colorAdjustmentWeight); frameColor = lerp(frameColor, ColorGradeColorFilter(frameColor, PassSrg::m_colorFilterSwatch.rgb, PassSrg::m_colorFilterMultiply, PassSrg::m_colorFilterIntensity), PassSrg::m_colorAdjustmentWeight); diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/ColorGrading/LutGeneration.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/ColorGrading/LutGeneration.azsl index 6a76f58519..89655a0e91 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/ColorGrading/LutGeneration.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/ColorGrading/LutGeneration.azsl @@ -57,6 +57,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback float m_whiteBalanceWeight; float m_whiteBalanceKelvin; float m_whiteBalanceTint; + float m_whiteBalanceLuminancePreservation; float m_splitToneBalance; float m_splitToneWeight; diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/HDRColorGrading.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/HDRColorGrading.azsl index bc33a7e920..3167b214dc 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/HDRColorGrading.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/HDRColorGrading.azsl @@ -40,6 +40,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback float m_whiteBalanceWeight; float m_whiteBalanceKelvin; float m_whiteBalanceTint; + float m_whiteBalanceLuminancePreservation; float m_splitToneBalance; float m_splitToneWeight; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingParams.inl b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingParams.inl index c5865b0cfe..f41994fa77 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingParams.inl +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/PostProcess/ColorGrading/HDRColorGradingParams.inl @@ -22,6 +22,7 @@ AZ_GFX_VEC3_PARAM(ColorFilterSwatch, m_colorFilterSwatch, AZ::Vector3(1.0f, 0.5f AZ_GFX_FLOAT_PARAM(WhiteBalanceWeight, m_whiteBalanceWeight, 0.0) AZ_GFX_FLOAT_PARAM(WhiteBalanceKelvin, m_whiteBalanceKelvin, 6600.0) AZ_GFX_FLOAT_PARAM(WhiteBalanceTint, m_whiteBalanceTint, 0.0) +AZ_GFX_FLOAT_PARAM(WhiteBalanceLuminancePreservation, m_whiteBalanceLuminancePreservation, 1.0) AZ_GFX_FLOAT_PARAM(SplitToneWeight, m_splitToneWeight, 0.0) AZ_GFX_FLOAT_PARAM(SplitToneBalance, m_splitToneBalance, 0.0) diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.cpp index 88266ba789..a3347d0d84 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.cpp @@ -43,6 +43,7 @@ m_whiteBalanceWeightIndex.Reset(); m_whiteBalanceKelvinIndex.Reset(); m_whiteBalanceTintIndex.Reset(); + m_whiteBalanceLuminancePreservationIndex.Reset(); m_splitToneBalanceIndex.Reset(); m_splitToneWeightIndex.Reset(); @@ -96,7 +97,7 @@ m_shaderResourceGroup->SetConstant(m_whiteBalanceWeightIndex, settings->GetWhiteBalanceWeight()); m_shaderResourceGroup->SetConstant(m_whiteBalanceKelvinIndex, settings->GetWhiteBalanceKelvin()); m_shaderResourceGroup->SetConstant(m_whiteBalanceTintIndex, settings->GetWhiteBalanceTint()); - + m_shaderResourceGroup->SetConstant(m_whiteBalanceLuminancePreservationIndex, settings->GetWhiteBalanceLuminancePreservation()); m_shaderResourceGroup->SetConstant(m_splitToneBalanceIndex, settings->GetSplitToneBalance()); m_shaderResourceGroup->SetConstant(m_splitToneWeightIndex, settings->GetSplitToneWeight()); m_shaderResourceGroup->SetConstant(m_splitToneShadowsColorIndex, AZ::Vector4(settings->GetSplitToneShadowsColor())); diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.h b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.h index dc706b8501..b89fa04531 100644 --- a/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/PostProcessing/HDRColorGradingPass.h @@ -55,6 +55,7 @@ namespace AZ RHI::ShaderInputNameIndex m_whiteBalanceWeightIndex = "m_whiteBalanceWeight"; RHI::ShaderInputNameIndex m_whiteBalanceKelvinIndex = "m_whiteBalanceKelvin"; RHI::ShaderInputNameIndex m_whiteBalanceTintIndex = "m_whiteBalanceTint"; + RHI::ShaderInputNameIndex m_whiteBalanceLuminancePreservationIndex = "m_whiteBalanceLuminancePreservation"; RHI::ShaderInputNameIndex m_splitToneBalanceIndex = "m_splitToneBalance"; RHI::ShaderInputNameIndex m_splitToneWeightIndex = "m_splitToneWeight"; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.cpp index e32b26f0c5..3cc9535d7a 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ColorGrading/EditorHDRColorGradingComponent.cpp @@ -100,9 +100,13 @@ namespace AZ ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_whiteBalanceKelvin, "Temperature", "Temperature in Kelvin") ->Attribute(Edit::Attributes::Min, 1000.0f) ->Attribute(Edit::Attributes::Max, 40000.0f) + ->Attribute(AZ::Edit::Attributes::SliderCurveMidpoint, 0.165f) ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_whiteBalanceTint, "Tint", "Tint Value") ->Attribute(Edit::Attributes::Min, -100.0f) ->Attribute(Edit::Attributes::Max, 100.0f) + ->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_whiteBalanceLuminancePreservation, "Luminance Preservation", "Modulate the preservation of luminance") + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 1.0f) ->ClassElement(AZ::Edit::ClassElements::Group, "Split Toning") ->Attribute(AZ::Edit::Attributes::AutoExpand, true)