White Balance Updates (#4887)

* Implement simple tint for white balance color grading. Adjust temperature slider to feel linear.

Signed-off-by: rbarrand <rbarrand@amazon.com>

* Change white balance luminance preservation equation and remove unused code.

Signed-off-by: rbarrand <rbarrand@amazon.com>

Co-authored-by: rbarrand <rbarrand@amazon.com>
This commit is contained in:
hershey5045
2021-10-22 09:53:48 -07:00
committed by GitHub
parent 8c6900eb06
commit f962f3d816
8 changed files with 27 additions and 38 deletions
@@ -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)
{
@@ -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);
@@ -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;
@@ -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;
@@ -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)
@@ -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()));
@@ -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";
@@ -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)