Refactor and resolve PR comments.
Signed-off-by: rbarrand <rbarrand@amazon.com>
This commit is contained in:
@@ -40,158 +40,6 @@
|
||||
"$type": "FullscreenTrianglePassData",
|
||||
"ShaderAsset": {
|
||||
"FilePath": "Shaders/ColorGrading/LutGeneration.shader"
|
||||
},
|
||||
"ShaderDataMappings": {
|
||||
"FloatMappings": [
|
||||
{
|
||||
"Name": "m_colorGradingExposure",
|
||||
"Value": 0.0 // unconstrained, log2 stops
|
||||
},
|
||||
{
|
||||
"Name": "m_colorGradingContrast",
|
||||
"Value": 0.0 // -100 ... 100
|
||||
},
|
||||
{
|
||||
"Name": "m_colorGradingHueShift",
|
||||
"Value": 0.0 // 0 ... 1, can wrap
|
||||
},
|
||||
{
|
||||
"Name": "m_colorGradingPreSaturation",
|
||||
"Value": 1.0 // -100 ... 100
|
||||
},
|
||||
{
|
||||
"Name": "m_colorFilterIntensity",
|
||||
"Value": 1.0 // unconstrained, log2 stops
|
||||
},
|
||||
{
|
||||
"Name": "m_colorFilterMultiply",
|
||||
"Value": 0.0 // modulate, 0 ... 1
|
||||
},
|
||||
{
|
||||
"Name": "m_whiteBalanceKelvin",
|
||||
"Value": 6600.0 // 1000.0f ... 40000.0f kelvin
|
||||
},
|
||||
{
|
||||
"Name": "m_whiteBalanceTint",
|
||||
"Value": 0.0 // -100 ... 100
|
||||
},
|
||||
{
|
||||
"Name": "m_splitToneBalance",
|
||||
"Value": 0.0 // -1 ... 1
|
||||
},
|
||||
{
|
||||
"Name": "m_splitToneWeight",
|
||||
"Value": 0.0 // 0 ... 1
|
||||
},
|
||||
{
|
||||
"Name": "m_colorGradingPostSaturation",
|
||||
"Value": 1.0 // -100 ... 100
|
||||
},
|
||||
{
|
||||
"Name": "m_smhShadowsStart",
|
||||
"Value": 0.0 // 0 ... 1
|
||||
},
|
||||
{
|
||||
"Name": "m_smhShadowsEnd",
|
||||
"Value": 0.3 // 0 ... 1
|
||||
},
|
||||
{
|
||||
"Name": "m_smhHighlightsStart",
|
||||
"Value": 0.55 // 0 ... 1
|
||||
},
|
||||
{
|
||||
"Name": "m_smhHighlightsEnd",
|
||||
"Value": 1.0 // 0 ... 1
|
||||
},
|
||||
{
|
||||
"Name": "m_smhWeight",
|
||||
"Value": 0.0 // 0 ... 1
|
||||
}
|
||||
],
|
||||
// The colors defined here are expected to be in linear rgb color space.
|
||||
// These are converted to ACEScg color space within the HDRColorGrading.azsl shader
|
||||
"ColorMappings": [
|
||||
{
|
||||
"Name": "m_colorFilterSwatch",
|
||||
"Value": [
|
||||
1.0,
|
||||
0.5,
|
||||
0.5,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "m_splitToneShadowsColor",
|
||||
"Value": [
|
||||
1.0,
|
||||
0.1,
|
||||
0.1,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "m_splitToneHighlightsColor",
|
||||
"Value": [
|
||||
0.1,
|
||||
1.0,
|
||||
0.1,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "m_smhShadowsColor",
|
||||
"Value": [
|
||||
1.0,
|
||||
0.25,
|
||||
0.25,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "m_smhMidtonesColor",
|
||||
"Value": [
|
||||
0.1,
|
||||
0.1,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "m_smhHighlightsColor",
|
||||
"Value": [
|
||||
1.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
],
|
||||
"Float3Mappings": [
|
||||
{
|
||||
"Name": "m_channelMixingRed",
|
||||
"Value": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "m_channelMixingGreen",
|
||||
"Value": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "m_channelMixingBlue",
|
||||
"Value": [
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
@@ -127,3 +127,28 @@ float3 ColorGradeShadowsMidtonesHighlights (float3 frameColor, float shadowsStar
|
||||
frameColor * highlightsColorACEScg * highlightsWeight;
|
||||
return lerp(frameColor.rgb, frameSmh.rgb, weight);
|
||||
}
|
||||
|
||||
// perform color grading in ACEScg space
|
||||
float3 ColorGrade(float3 frameColor)
|
||||
{
|
||||
frameColor = ColorGradePostExposure(frameColor, PassSrg::m_colorGradingExposure);
|
||||
frameColor = ColorGradeKelvinColorTemp(frameColor, PassSrg::m_whiteBalanceKelvin);
|
||||
frameColor = ColorGradingContrast(frameColor, AcesCcMidGrey, PassSrg::m_colorGradingContrast);
|
||||
frameColor = ColorGradeColorFilter(frameColor, PassSrg::m_colorFilterSwatch.rgb,
|
||||
PassSrg::m_colorFilterMultiply, PassSrg::m_colorFilterIntensity);
|
||||
frameColor = max(frameColor, 0.0);
|
||||
frameColor = ColorGradeSaturation(frameColor, PassSrg::m_colorGradingPreSaturation);
|
||||
|
||||
frameColor = ColorGradeSplitTone(frameColor, PassSrg::m_splitToneBalance, PassSrg::m_splitToneWeight,
|
||||
PassSrg::m_splitToneShadowsColor, PassSrg::m_splitToneHighlightsColor);
|
||||
frameColor = ColorGradeChannelMixer(frameColor, PassSrg::m_channelMixingRed, PassSrg::m_channelMixingGreen, PassSrg::m_channelMixingBlue);
|
||||
frameColor = max(frameColor, 0.0);
|
||||
frameColor = ColorGradeShadowsMidtonesHighlights(frameColor, PassSrg::m_smhShadowsStart, PassSrg::m_smhShadowsEnd,
|
||||
PassSrg::m_smhHighlightsStart, PassSrg::m_smhHighlightsEnd, PassSrg::m_smhWeight,
|
||||
PassSrg::m_smhShadowsColor, PassSrg::m_smhMidtonesColor, PassSrg::m_smhHighlightsColor);
|
||||
|
||||
frameColor = ColorGradeSaturation(frameColor, PassSrg::m_colorGradingPostSaturation);
|
||||
|
||||
frameColor = ColorGradeHueShift(frameColor, PassSrg::m_colorGradingHueShift);
|
||||
return max(frameColor.rgb, 0.0);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <Atom/Features/PostProcessing/Aces.azsli>
|
||||
#include <Atom/Features/PostProcessing/Shapers.azsli>
|
||||
#include <Atom/Features/PostProcessing/HDRColorGradingCommon.azsl>
|
||||
|
||||
float3 convert2Dto3DLutCoords(float2 uv, float width, float height)
|
||||
{
|
||||
@@ -95,31 +94,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback
|
||||
float4 m_smhHighlightsColor;
|
||||
}
|
||||
|
||||
float3 ColorGrade(float3 linearColor)
|
||||
{
|
||||
float3 color = TransformColor(linearColor, ColorSpaceId::LinearSRGB, ColorSpaceId::ACEScg);
|
||||
color = ColorGradePostExposure(color, PassSrg::m_colorGradingExposure);
|
||||
//color = ColorGradeKelvinColorTemp(color, PassSrg::m_whiteBalanceKelvin);
|
||||
color = ColorGradingContrast(color, AcesCcMidGrey, PassSrg::m_colorGradingContrast);
|
||||
color = ColorGradeColorFilter(color, PassSrg::m_colorFilterSwatch.rgb,
|
||||
PassSrg::m_colorFilterMultiply, PassSrg::m_colorFilterIntensity);
|
||||
color = max(color, 0.0);
|
||||
color = ColorGradeSaturation(color, PassSrg::m_colorGradingPreSaturation);
|
||||
|
||||
color = ColorGradeSplitTone(color, PassSrg::m_splitToneBalance, PassSrg::m_splitToneWeight,
|
||||
PassSrg::m_splitToneShadowsColor, PassSrg::m_splitToneHighlightsColor);
|
||||
color = ColorGradeChannelMixer(color, PassSrg::m_channelMixingRed, PassSrg::m_channelMixingGreen, PassSrg::m_channelMixingBlue);
|
||||
color = max(color, 0.0);
|
||||
color = ColorGradeShadowsMidtonesHighlights(color, PassSrg::m_smhShadowsStart, PassSrg::m_smhShadowsEnd,
|
||||
PassSrg::m_smhHighlightsStart, PassSrg::m_smhHighlightsEnd, PassSrg::m_smhWeight,
|
||||
PassSrg::m_smhShadowsColor, PassSrg::m_smhMidtonesColor, PassSrg::m_smhHighlightsColor);
|
||||
|
||||
color = ColorGradeSaturation(color, PassSrg::m_colorGradingPostSaturation);
|
||||
|
||||
color = ColorGradeHueShift(color, PassSrg::m_colorGradingHueShift);
|
||||
color = TransformColor(color, ColorSpaceId::ACEScg, ColorSpaceId::LinearSRGB);
|
||||
return max(color.rgb, 0.0);
|
||||
}
|
||||
#include <Atom/Features/PostProcessing/HDRColorGradingCommon.azsl>
|
||||
|
||||
struct PSOutput
|
||||
{
|
||||
@@ -130,39 +105,43 @@ PSOutput MainPS(VSOutput IN)
|
||||
{
|
||||
ShaperType shaperType = (ShaperType)PassSrg::m_shaperType;
|
||||
|
||||
|
||||
PSOutput OUT;
|
||||
|
||||
// baseCoords are from 0-1
|
||||
float3 baseCoords = float3(0.0, 0.0, 0.0);
|
||||
float3 lutColor = float3(0.0, 0.0, 0.0);
|
||||
LutResolution lutRes = (LutResolution)PassSrg::m_lutResolution;
|
||||
switch(lutRes)
|
||||
{
|
||||
case LutResolution::Lut16x16x16:
|
||||
{
|
||||
baseCoords = convert2Dto3DLutCoords(IN.m_texCoord, 256, 16);
|
||||
lutColor = PassSrg::m_identityLut16x16x16.Sample(PassSrg::PointSampler, baseCoords, 0.0).rgb;
|
||||
baseCoords = PassSrg::m_identityLut16x16x16.Sample(PassSrg::PointSampler, baseCoords, 0.0).rgb;
|
||||
break;
|
||||
}
|
||||
case LutResolution::Lut32x32x32:
|
||||
{
|
||||
// This seems correct intuitively, but is turning grey into green!
|
||||
baseCoords = convert2Dto3DLutCoords(IN.m_texCoord, 1024, 32);
|
||||
lutColor = PassSrg::m_identityLut32x32x32.Sample(PassSrg::PointSampler, baseCoords, 0.0).rgb;
|
||||
baseCoords = PassSrg::m_identityLut32x32x32.Sample(PassSrg::PointSampler, baseCoords, 0.0).rgb;
|
||||
break;
|
||||
}
|
||||
case LutResolution::Lut64x64x64:
|
||||
{
|
||||
baseCoords = convert2Dto3DLutCoords(IN.m_texCoord, 4096, 64);
|
||||
lutColor = PassSrg::m_identityLut64x64x64.Sample(PassSrg::PointSampler, baseCoords, 0.0).rgb;
|
||||
baseCoords = PassSrg::m_identityLut64x64x64.Sample(PassSrg::PointSampler, baseCoords, 0.0).rgb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float3 gradedColor = ColorGrade(lutColor);
|
||||
float3 linearColor = ShaperToLinear(baseCoords, shaperType, PassSrg::m_shaperBias, PassSrg::m_shaperScale);
|
||||
|
||||
gradedColor = ShaperToLinear(gradedColor, shaperType, PassSrg::m_shaperBias, PassSrg::m_shaperScale);
|
||||
linearColor = TransformColor(linearColor, ColorSpaceId::LinearSRGB, ColorSpaceId::ACEScg);
|
||||
float3 gradedColor = ColorGrade(linearColor);
|
||||
gradedColor = TransformColor(gradedColor, ColorSpaceId::ACEScg, ColorSpaceId::LinearSRGB);
|
||||
|
||||
OUT.m_lutOutput = float4(gradedColor, 1.0);
|
||||
// Bring back coordinates into 0-1
|
||||
float3 shapedColor = LinearToShaper(gradedColor, shaperType, PassSrg::m_shaperBias, PassSrg::m_shaperScale);
|
||||
shapedColor = saturate(shapedColor);
|
||||
|
||||
OUT.m_lutOutput = float4(shapedColor, 1.0);
|
||||
return OUT;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
|
||||
#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
|
||||
#include <Atom/Features/PostProcessing/HDRColorGradingCommon.azsl>
|
||||
|
||||
ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback
|
||||
{
|
||||
@@ -60,27 +59,7 @@ ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback
|
||||
float4 m_smhHighlightsColor;
|
||||
}
|
||||
|
||||
// perform color grading in ACEScg space
|
||||
float3 ColorGrade(float3 frameColor)
|
||||
{
|
||||
frameColor = ColorGradePostExposure(frameColor, PassSrg::m_colorGradingExposure);
|
||||
//frameColor = ColorGradeKelvinColorTemp(frameColor, PassSrg::m_whiteBalanceKelvin);
|
||||
frameColor = ColorGradingContrast(frameColor, AcesCcMidGrey, PassSrg::m_colorGradingContrast);
|
||||
frameColor = ColorGradeColorFilter(frameColor, PassSrg::m_colorFilterSwatch.rgb,
|
||||
PassSrg::m_colorFilterMultiply, PassSrg::m_colorFilterIntensity);
|
||||
frameColor = max(frameColor, 0.0);
|
||||
frameColor = ColorGradeSaturation(frameColor, PassSrg::m_colorGradingPreSaturation);
|
||||
frameColor = ColorGradeSplitTone(frameColor, PassSrg::m_splitToneBalance, PassSrg::m_splitToneWeight,
|
||||
PassSrg::m_splitToneShadowsColor, PassSrg::m_splitToneHighlightsColor);
|
||||
frameColor = ColorGradeChannelMixer(frameColor, PassSrg::m_channelMixingRed, PassSrg::m_channelMixingGreen, PassSrg::m_channelMixingBlue);
|
||||
frameColor = max(frameColor, 0.0);
|
||||
frameColor = ColorGradeShadowsMidtonesHighlights(frameColor, PassSrg::m_smhShadowsStart, PassSrg::m_smhShadowsEnd,
|
||||
PassSrg::m_smhHighlightsStart, PassSrg::m_smhHighlightsEnd, PassSrg::m_smhWeight,
|
||||
PassSrg::m_smhShadowsColor, PassSrg::m_smhMidtonesColor, PassSrg::m_smhHighlightsColor);
|
||||
frameColor = ColorGradeHueShift(frameColor, PassSrg::m_colorGradingHueShift);
|
||||
frameColor = ColorGradeSaturation(frameColor, PassSrg::m_colorGradingPostSaturation);
|
||||
return max(frameColor.rgb, 0.0);
|
||||
}
|
||||
#include <Atom/Features/PostProcessing/HDRColorGradingCommon.azsl>
|
||||
|
||||
PSOutput MainPS(VSOutput IN)
|
||||
{
|
||||
|
||||
@@ -104,9 +104,8 @@ namespace AZ
|
||||
|
||||
bool LutGenerationPass::IsEnabled() const
|
||||
{
|
||||
//const auto* colorGradingSettings = GetHDRColorGradingSettings();
|
||||
//return colorGradingSettings ? colorGradingSettings->GetGenerateLut() : false;
|
||||
return true;
|
||||
const auto* colorGradingSettings = GetHDRColorGradingSettings();
|
||||
return colorGradingSettings ? colorGradingSettings->GetGenerateLut() : false;
|
||||
}
|
||||
|
||||
void LutGenerationPass::SetViewportScissorFromImageSize(const RHI::Size& imageSize)
|
||||
|
||||
+27
-30
@@ -104,7 +104,7 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_splitToneBalance, "Split Tone Balance", "Split Tone Balance Value")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Min, -1.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_splitToneShadowsColor, "Split Tone Shadows Color", "Split Tone Shadows Color")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_splitToneHighlightsColor, "Split Tone Highlights Color", "Split Tone Highlights Color")
|
||||
@@ -175,36 +175,35 @@ namespace AZ
|
||||
|
||||
void EditorHDRColorGradingComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
|
||||
{
|
||||
if (m_controller.m_configuration.m_generateLut && m_frameCounter)
|
||||
if (m_waitOneFrame)
|
||||
{
|
||||
--m_frameCounter;
|
||||
m_waitOneFrame = false;
|
||||
return;
|
||||
}
|
||||
else if (m_controller.m_configuration.m_generateLut && m_lutGenerationInProgress)
|
||||
|
||||
const char* LutAttachment = "LutOutput";
|
||||
const AZStd::vector<AZStd::string> LutGenerationPassHierarchy{ "LutGenerationPass" };
|
||||
|
||||
char resolvedOutputFilePath[AZ_MAX_PATH_LEN] = { 0 };
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(m_currentTiffFilePath.c_str(), resolvedOutputFilePath, AZ_MAX_PATH_LEN);
|
||||
|
||||
AZStd::string lutGenerationCacheFolder;
|
||||
AzFramework::StringFunc::Path::GetFolderPath(resolvedOutputFilePath, lutGenerationCacheFolder);
|
||||
AZ::IO::SystemFile::CreateDir(lutGenerationCacheFolder.c_str());
|
||||
|
||||
bool startedCapture = false;
|
||||
AZ::Render::FrameCaptureRequestBus::BroadcastResult(
|
||||
startedCapture,
|
||||
&AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachment,
|
||||
LutGenerationPassHierarchy,
|
||||
AZStd::string(LutAttachment),
|
||||
m_currentTiffFilePath,
|
||||
AZ::RPI::PassAttachmentReadbackOption::Output);
|
||||
|
||||
if (startedCapture)
|
||||
{
|
||||
const char* LutAttachment = "LutOutput";
|
||||
const AZStd::vector<AZStd::string> LutGenerationPassHierarchy{ "LutGenerationPass" };
|
||||
|
||||
char resolvedOutputFilePath[AZ_MAX_PATH_LEN] = { 0 };
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(m_currentTiffFilePath.c_str(), resolvedOutputFilePath, AZ_MAX_PATH_LEN);
|
||||
|
||||
AZStd::string lutGenerationCacheFolder;
|
||||
AzFramework::StringFunc::Path::GetFolderPath(resolvedOutputFilePath, lutGenerationCacheFolder);
|
||||
AZ::IO::SystemFile::CreateDir(lutGenerationCacheFolder.c_str());
|
||||
|
||||
// capture frame
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect();
|
||||
|
||||
bool startedCapture = false;
|
||||
AZ::Render::FrameCaptureRequestBus::BroadcastResult(
|
||||
startedCapture,
|
||||
&AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachment,
|
||||
LutGenerationPassHierarchy,
|
||||
AZStd::string(LutAttachment),
|
||||
m_currentTiffFilePath,
|
||||
AZ::RPI::PassAttachmentReadbackOption::Output);
|
||||
|
||||
m_lutGenerationInProgress = !startedCapture;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +237,6 @@ namespace AZ
|
||||
&AzToolsFramework::PropertyEditorGUIMessages::RequestRefresh,
|
||||
AzToolsFramework::PropertyModificationRefreshLevel::Refresh_EntireTree);
|
||||
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
AZ::Render::FrameCaptureNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
@@ -252,11 +250,10 @@ namespace AZ
|
||||
m_currentTiffFilePath = AZStd::string::format(TempTiffFilePath, uuidString.c_str());
|
||||
m_currentLutFilePath = "@projectroot@/" + AZStd::string::format(GeneratedLutRelativePath, uuidString.c_str());
|
||||
|
||||
m_lutGenerationInProgress = true;
|
||||
m_controller.m_configuration.m_generateLut = true;
|
||||
m_controller.SetGenerateLut(true);
|
||||
m_controller.OnConfigChanged();
|
||||
|
||||
m_frameCounter = FramesToWait;
|
||||
m_waitOneFrame = true;
|
||||
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
+1
-6
@@ -34,10 +34,6 @@ namespace AZ
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
static const int FramesToWait = 5;
|
||||
//static const char* LutAttachment;
|
||||
//static const AZStd::vector<AZStd::string> LutGenerationPassHierarchy;
|
||||
|
||||
EditorHDRColorGradingComponent() = default;
|
||||
EditorHDRColorGradingComponent(const HDRColorGradingComponentConfig& config);
|
||||
|
||||
@@ -55,8 +51,7 @@ namespace AZ
|
||||
AZ::u32 ActivateLut();
|
||||
bool GetGeneratedLutVisibilitySettings();
|
||||
|
||||
AZStd::atomic_bool m_lutGenerationInProgress = false;
|
||||
int m_frameCounter;
|
||||
bool m_waitOneFrame = false;
|
||||
AZStd::string m_currentTiffFilePath;
|
||||
AZStd::string m_currentLutFilePath;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user