From a05c9cb03d397caa5c71157a368c8f100512b34a Mon Sep 17 00:00:00 2001 From: papadanku Date: Wed, 9 Oct 2024 11:36:46 -0700 Subject: [PATCH 1/2] cRaySchism: Added initial color grading stage --- shaders/cRaySchism.fx | 113 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 8 deletions(-) diff --git a/shaders/cRaySchism.fx b/shaders/cRaySchism.fx index 9d4b01a..271bddf 100644 --- a/shaders/cRaySchism.fx +++ b/shaders/cRaySchism.fx @@ -99,6 +99,44 @@ > = false; #endif +uniform float _GradePostExposure < + ui_category = "Color Grading"; + ui_label = "Post Exposure"; + ui_type = "drag"; +> = 0.0; + +uniform float _GradeContrast < + ui_category = "Color Grading"; + ui_label = "Contrast"; + ui_type = "slider"; + ui_min = -100.0; + ui_max = 100.0; +> = 0.0; + +uniform float3 _GradeColorFilter < + ui_category = "Color Grading"; + ui_label = "Color Filter"; + ui_type = "color"; + ui_min = 0.0; + ui_max = 1.0; +> = 1.0; + +uniform float _GradeHueShift < + ui_category = "Color Grading"; + ui_label = "Hue Shift"; + ui_type = "slider"; + ui_min = -180.0; + ui_max = 180.0; +> = 0.0; + +uniform float _GradeSaturation < + ui_category = "Color Grading"; + ui_label = "Saturation"; + ui_type = "slider"; + ui_min = -100.0; + ui_max = 100.0; +> = 0.0; + #include "shared/cShadeHDR.fxh" #if ENABLE_AUTOEXPOSURE #include "shared/cCameraInput.fxh" @@ -158,7 +196,7 @@ float2 SpotMeterTex = (Tex * 2.0) - 1.0; // Expand the UV so [-1, 1] fills the shape of its input texture instead of output - #if BUFFER_WIDTH > BUFFER_HEIGHT + #if !ENABLE_BLOOM && (BUFFER_WIDTH > BUFFER_HEIGHT) SpotMeterTex.x /= ASPECT_RATIO; #else SpotMeterTex.y /= ASPECT_RATIO; @@ -178,20 +216,34 @@ Height conversion | [0, 1] -> [-N, N] */ float2 OverlayPos = UnormTex; - OverlayPos -= float2(_ExposureOffset.x, -_ExposureOffset.y); + OverlayPos += float2(-_ExposureOffset.x, _ExposureOffset.y); OverlayPos /= _ExposureScale; // Shrink the UV so [-1, 1] fills a square - #if BUFFER_WIDTH > BUFFER_HEIGHT - OverlayPos.x *= ASPECT_RATIO; - #else - OverlayPos.y *= ASPECT_RATIO; + #if !ENABLE_BLOOM + #if (BUFFER_WIDTH > BUFFER_HEIGHT) + OverlayPos.x *= ASPECT_RATIO; + #else + OverlayPos.y *= ASPECT_RATIO; + #endif #endif // Create the needed mask; output 1 if the texcoord is within square range float Factor = 1.0 * _ExposureScale; float SquareMask = all(abs(OverlayPos) <= Factor); - float DotMask = CProcedural_GetAntiAliasShape(length(OverlayPos), Factor * 0.1); + + float2 DotPos = UnormTex; + DotPos += float2(-_ExposureOffset.x, _ExposureOffset.y); + DotPos /= _ExposureScale; + + // Shrink the UV so [-1, 1] fills a square + #if BUFFER_WIDTH > BUFFER_HEIGHT + DotPos.x *= ASPECT_RATIO; + #else + DotPos.y *= ASPECT_RATIO; + #endif + + float DotMask = CProcedural_GetAntiAliasShape(length(DotPos), Factor * 0.1); // Apply square mask to output Color = lerp(Color, NonExposedColor.rgb, SquareMask); @@ -311,6 +363,49 @@ CREATE_PS_UPSCALE(PS_Upscale1, SampleTempTex2) #endif +/* + Modification of Jasper's color grading tutorial + https://catlikecoding.com/unity/tutorials/custom-srp/color-grading/ + + MIT No Attribution (MIT-0) + + Copyright 2021 Jasper Flick + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +void ApplyColorGrading(inout float3 Color) +{ + // Constants + const float ACEScc_MIDGRAY = 0.4135884; + + // Convert user-friendly uniform settings + float PostExposure = exp2(_GradePostExposure); + float Contrast = (_GradeContrast / 100.0) + 1.0; + float HueShift = _GradeHueShift / 360.0; + float Saturation = (_GradeSaturation / 100.0) + 1.0; + + // Apply post exposure + Color *= PostExposure; + + // Apply contrast + Color = CCamera_EncodeLogC(Color); + Color = (Color - ACEScc_MIDGRAY) * Contrast + ACEScc_MIDGRAY; + Color = CCamera_DecodeLogC(Color); + + // Apply hue shifting + Color = CColor_GetHSVfromRGB(Color); + Color.x += HueShift; + Color = CColor_GetRGBfromHSV(Color); + + // Apply color filter + Color *= _GradeColorFilter; + + Color = max(Color, 0.0); +} + float4 PS_Composite(CShade_VS2PS_Quad Input) : SV_TARGET0 { float3 BaseColor = CShade_BackBuffer2D(Input.Tex0).rgb; @@ -329,6 +424,8 @@ float4 PS_Composite(CShade_VS2PS_Quad Input) : SV_TARGET0 BaseColor = (_BloomRenderMode == 0) ? BaseColor + BloomColor : BloomColor; #endif + ApplyColorGrading(BaseColor); + // Apply tonemapping BaseColor = CTonemap_ApplyOutputTonemap(BaseColor); @@ -346,7 +443,7 @@ float4 PS_Composite(CShade_VS2PS_Quad Input) : SV_TARGET0 ApplyAverageLumaOverlay(BaseColor, UnormTex, ExposureData); } #endif - BaseColor = saturate(BaseColor); + return CBlend_OutputChannels(float4(BaseColor, _CShadeAlphaFactor)); } From c1af73845cb26057b5a177ed0ec816f82cf45316 Mon Sep 17 00:00:00 2001 From: papadanku Date: Wed, 9 Oct 2024 11:42:03 -0700 Subject: [PATCH 2/2] cRaySchism: Added OKLab saturation --- shaders/cRaySchism.fx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/shaders/cRaySchism.fx b/shaders/cRaySchism.fx index 271bddf..afda5b3 100644 --- a/shaders/cRaySchism.fx +++ b/shaders/cRaySchism.fx @@ -384,7 +384,7 @@ void ApplyColorGrading(inout float3 Color) // Convert user-friendly uniform settings float PostExposure = exp2(_GradePostExposure); float Contrast = (_GradeContrast / 100.0) + 1.0; - float HueShift = _GradeHueShift / 360.0; + float HueShift = (_GradeHueShift / 360.0) * CMath_GetPi(); float Saturation = (_GradeSaturation / 100.0) + 1.0; // Apply post exposure @@ -395,14 +395,18 @@ void ApplyColorGrading(inout float3 Color) Color = (Color - ACEScc_MIDGRAY) * Contrast + ACEScc_MIDGRAY; Color = CCamera_DecodeLogC(Color); - // Apply hue shifting - Color = CColor_GetHSVfromRGB(Color); - Color.x += HueShift; - Color = CColor_GetRGBfromHSV(Color); - // Apply color filter Color *= _GradeColorFilter; + // Apply hue shifting + Color = CColor_GetOKLCHfromRGB(Color); + Color.z += HueShift; + Color = CColor_GetRGBfromOKLCH(Color); + + // Apply saturation + float Luminance = CColor_GetLuma(Color, 3); + Color = lerp(Luminance, Color, Saturation); + Color = max(Color, 0.0); }