-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HDR Enhancements for Resident Evil: Village (#88)
* feat(revillage): add final pq shader with tonemap * feat(revillage): add tonemap shaders * feat(revillage): add addon.cpp and shared.h * revilage: raise tonemapping ShoulderStart * feat(revillage): add gamma correction - add sRGB -> 2.2 gamma correction - raise DICE ShoulderStart as sRGB -> 2.2 lowers highlights - adjust lut scaling to reduce black crush with 2.2 gamma correction - declare bt709Color in Rec2020PS as float3 as w is unused * feat(revillage): add final pq shader with tonemap * feat(revillage): add tonemap shaders * feat(revillage): add addon.cpp and shared.h * revilage: raise tonemapping ShoulderStart * feat(revillage): add gamma correction - add sRGB -> 2.2 gamma correction - raise DICE ShoulderStart as sRGB -> 2.2 lowers highlights - adjust lut scaling to reduce black crush with 2.2 gamma correction - declare bt709Color in Rec2020PS as float3 as w is unused * feat(revillage): add final pq shader with tonemap * feat(revillage): add tonemap shaders * feat(revillage): add addon.cpp and shared.h * revilage: raise tonemapping ShoulderStart * feat(revillage): add gamma correction - add sRGB -> 2.2 gamma correction - raise DICE ShoulderStart as sRGB -> 2.2 lowers highlights - adjust lut scaling to reduce black crush with 2.2 gamma correction - declare bt709Color in Rec2020PS as float3 as w is unused
- Loading branch information
Showing
7 changed files
with
2,886 additions
and
0 deletions.
There are no files selected for viewing
75 changes: 75 additions & 0 deletions
75
src/games/revillage/ConvertRec2020PS_0x1405D21D.ps_6_5.hlsl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#include "./DICE.hlsl" | ||
#include "./shared.h" | ||
|
||
Texture2D<float4> tLinearImage : register(t0); | ||
|
||
cbuffer HDRMapping : register(b0) { | ||
float whitePaperNits : packoffset(c000.x); | ||
float displayMaxNits : packoffset(c000.z); | ||
float HDRMapping_000w : packoffset(c000.w); | ||
uint HDRMapping_004x : packoffset(c004.x); | ||
float HDRMapping_004y : packoffset(c004.y); | ||
}; | ||
|
||
SamplerState PointBorder : register(s0); | ||
|
||
float4 main( | ||
noperspective float4 SV_Position: SV_Position, | ||
linear float2 TEXCOORD: TEXCOORD) | ||
: SV_Target { | ||
#if 1 | ||
float3 bt709Color = tLinearImage.SampleLevel(PointBorder, TEXCOORD.xy, 0.0f).rgb; | ||
#if 1 | ||
bt709Color = renodx::color::correct::GammaSafe(bt709Color); | ||
#endif | ||
|
||
#if 1 | ||
DICESettings config = DefaultDICESettings(); | ||
config.Type = 3; | ||
config.ShoulderStart = 0.5; | ||
const float dicePaperWhite = whitePaperNits / renodx::color::srgb::REFERENCE_WHITE; | ||
const float dicePeakWhite = max(displayMaxNits, whitePaperNits) / renodx::color::srgb::REFERENCE_WHITE; | ||
bt709Color.rgb = DICETonemap(bt709Color.rgb * dicePaperWhite, dicePeakWhite, config) / dicePaperWhite; | ||
#endif | ||
|
||
float3 bt2020Color = renodx::color::bt2020::from::BT709(bt709Color.rgb); | ||
|
||
float3 pqColor = renodx::color::pq::Encode(bt2020Color, whitePaperNits); | ||
|
||
return float4(pqColor, 1.0); | ||
|
||
#else | ||
float4 SV_Target; | ||
float4 _6 = tLinearImage.SampleLevel(PointBorder, float2((TEXCOORD.x), (TEXCOORD.y)), 0.0f); | ||
float _7 = _6.x; | ||
float _8 = _6.y; | ||
float _9 = _6.z; | ||
float _20 = HDRMapping_004y; | ||
float _32 = 10000.0f / (whitePaperNits); | ||
float _45 = exp2(((log2((saturate(((exp2(((log2((mad(0.04331360012292862f, (_6.z), (mad(0.3292819857597351f, (_6.y), ((_6.x) * 0.627403974533081f))))))) * (HDRMapping_004y)))) / _32))))) * 0.1593017578125f)); | ||
float _46 = exp2(((log2((saturate(((exp2(((log2((mad(0.011361200362443924f, (_6.z), (mad(0.9195399880409241f, (_6.y), ((_6.x) * 0.06909699738025665f))))))) * (HDRMapping_004y)))) / _32))))) * 0.1593017578125f)); | ||
float _47 = exp2(((log2((saturate(((exp2(((log2((mad(0.8955950140953064f, (_6.z), (mad(0.08801320195198059f, (_6.y), ((_6.x) * 0.01639159955084324f))))))) * (HDRMapping_004y)))) / _32))))) * 0.1593017578125f)); | ||
float _72 = saturate((exp2(((log2((((_45 * 18.8515625f) + 0.8359375f) / ((_45 * 18.6875f) + 1.0f)))) * 78.84375f)))); | ||
float _73 = saturate((exp2(((log2((((_46 * 18.8515625f) + 0.8359375f) / ((_46 * 18.6875f) + 1.0f)))) * 78.84375f)))); | ||
float _74 = saturate((exp2(((log2((((_47 * 18.8515625f) + 0.8359375f) / ((_47 * 18.6875f) + 1.0f)))) * 78.84375f)))); | ||
|
||
float _139, _140, _141; | ||
if (!(((((uint)(HDRMapping_004x)) & 2) == 0))) { | ||
float _85 = exp2(((log2((saturate(((displayMaxNits) * 9.999999747378752e-05f))))) * 0.1593017578125f)); | ||
float _94 = saturate((exp2(((log2((((_85 * 18.8515625f) + 0.8359375f) / ((_85 * 18.6875f) + 1.0f)))) * 78.84375f)))); | ||
float _100 = exp2(((log2((saturate(((HDRMapping_000w) * 9.999999747378752e-05f))))) * 0.1593017578125f)); | ||
float _110 = _94 - (saturate((exp2(((log2((((_100 * 18.8515625f) + 0.8359375f) / ((_100 * 18.6875f) + 1.0f)))) * 78.84375f))))); | ||
float _114 = saturate((_72 / _94)); | ||
float _115 = saturate((_73 / _94)); | ||
float _116 = saturate((_74 / _94)); | ||
_139 = (min(((((2.0f - (_114 + _114)) * _110) + (_114 * _94)) * _114), _72)); | ||
_140 = (min(((((2.0f - (_115 + _115)) * _110) + (_115 * _94)) * _115), _73)); | ||
_141 = (min(((((2.0f - (_116 + _116)) * _110) + (_116 * _94)) * _116), _74)); | ||
} | ||
SV_Target.x = _139; | ||
SV_Target.y = _140; | ||
SV_Target.z = _141; | ||
SV_Target.w = 1.0f; | ||
return SV_Target; | ||
#endif | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
#include "./shared.h" | ||
|
||
float max3(float a, float b, float c) | ||
{ | ||
return max(a, max(b, c)); | ||
} | ||
|
||
float max3(float3 v) | ||
{ | ||
return max3(v.x, v.y, v.z); | ||
} | ||
|
||
static const float PQ_constant_M1 = 0.1593017578125f; | ||
static const float PQ_constant_M2 = 78.84375f; | ||
static const float PQ_constant_C1 = 0.8359375f; | ||
static const float PQ_constant_C2 = 18.8515625f; | ||
static const float PQ_constant_C3 = 18.6875f; | ||
|
||
// PQ (Perceptual Quantizer - ST.2084) encode/decode used for HDR10 BT.2100. | ||
// Clamp type: | ||
// 0 None | ||
// 1 Remove negative numbers | ||
// 2 Remove numbers beyond 0-1 | ||
// 3 Mirror negative numbers | ||
float3 Linear_to_PQ(float3 LinearColor, int clampType = 0) | ||
{ | ||
float3 LinearColorSign = sign(LinearColor); | ||
if (clampType == 1) | ||
{ | ||
LinearColor = max(LinearColor, 0.f); | ||
} | ||
else if (clampType == 2) | ||
{ | ||
LinearColor = saturate(LinearColor); | ||
} | ||
else if (clampType == 3) | ||
{ | ||
LinearColor = abs(LinearColor); | ||
} | ||
float3 colorPow = pow(LinearColor, PQ_constant_M1); | ||
float3 numerator = PQ_constant_C1 + PQ_constant_C2 * colorPow; | ||
float3 denominator = 1.f + PQ_constant_C3 * colorPow; | ||
float3 pq = pow(numerator / denominator, PQ_constant_M2); | ||
if (clampType == 3) | ||
{ | ||
return pq * LinearColorSign; | ||
} | ||
return pq; | ||
} | ||
|
||
float3 PQ_to_Linear(float3 ST2084Color, int clampType = 0) | ||
{ | ||
float3 ST2084ColorSign = sign(ST2084Color); | ||
if (clampType == 1) | ||
{ | ||
ST2084Color = max(ST2084Color, 0.f); | ||
} | ||
else if (clampType == 2) | ||
{ | ||
ST2084Color = saturate(ST2084Color); | ||
} | ||
else if (clampType == 3) | ||
{ | ||
ST2084Color = abs(ST2084Color); | ||
} | ||
float3 colorPow = pow(ST2084Color, 1.f / PQ_constant_M2); | ||
float3 numerator = max(colorPow - PQ_constant_C1, 0.f); | ||
float3 denominator = PQ_constant_C2 - (PQ_constant_C3 * colorPow); | ||
float3 linearColor = pow(numerator / denominator, 1.f / PQ_constant_M1); | ||
if (clampType == 3) | ||
{ | ||
return linearColor * ST2084ColorSign; | ||
} | ||
return linearColor; | ||
} | ||
|
||
// Aplies exponential ("Photographic") luminance/luma compression. | ||
// The pow can modulate the curve without changing the values around the edges. | ||
// The max is the max possible range to compress from, to not lose any output range if the input range was limited. | ||
float rangeCompress(float X, float Max = asfloat(0x7F7FFFFF)) | ||
{ | ||
// Branches are for static parameters optimizations | ||
if (Max == renodx::math::FLT_MAX) { | ||
// This does e^X. We expect X to be between 0 and 1. | ||
return 1.f - exp(-X); | ||
} | ||
const float lostRange = exp(-Max); | ||
const float restoreRangeScale = 1.f / (1.f - lostRange); | ||
return (1.f - exp(-X)) * restoreRangeScale; | ||
} | ||
|
||
// Refurbished DICE HDR tonemapper (per channel or luminance). | ||
// Expects "InValue" to be >= "ShoulderStart" and "OutMaxValue" to be > "ShoulderStart". | ||
float luminanceCompress( | ||
float InValue, | ||
float OutMaxValue, | ||
float ShoulderStart = 0.f, | ||
bool considerMaxValue = false, | ||
float InMaxValue = asfloat(0x7F7FFFFF)) | ||
{ | ||
const float compressableValue = InValue - ShoulderStart; | ||
const float compressableRange = InMaxValue - ShoulderStart; | ||
const float compressedRange = OutMaxValue - ShoulderStart; | ||
const float possibleOutValue = ShoulderStart + compressedRange * rangeCompress(compressableValue / compressedRange, considerMaxValue ? (compressableRange / compressedRange) : renodx::math::FLT_MAX); | ||
#if 1 | ||
return possibleOutValue; | ||
#else // Enable this branch if "InValue" can be smaller than "ShoulderStart" | ||
return (InValue <= ShoulderStart) ? InValue : possibleOutValue; | ||
#endif | ||
} | ||
|
||
#define DICE_TYPE_BY_LUMINANCE_RGB 0 | ||
// Doing the DICE compression in PQ (either on luminance or each color channel) produces a curve that is closer to our "perception" and leaves more detail highlights without overly compressing them | ||
#define DICE_TYPE_BY_LUMINANCE_PQ 1 | ||
// Modern HDR displays clip individual rgb channels beyond their "white" peak brightness, | ||
// like, if the peak brightness is 700 nits, any r g b color beyond a value of 700/80 will be clipped (not acknowledged, it won't make a difference). | ||
// Tonemapping by luminance, is generally more perception accurate but can then generate rgb colors "out of range". This setting fixes them up, | ||
// though it's optional as it's working based on assumptions on how current displays work, which might not be true anymore in the future. | ||
// Note that this can create some steep (rough, quickly changing) gradients on very bright colors. | ||
#define DICE_TYPE_BY_LUMINANCE_PQ_CORRECT_CHANNELS_BEYOND_PEAK_WHITE 2 | ||
// This might look more like classic SDR tonemappers and is closer to how modern TVs and Monitors play back colors (usually they clip each individual channel to the peak brightness value, though in their native panel color space, or current SDR/HDR mode color space). | ||
// Overall, this seems to handle bright gradients more smoothly, even if it shifts hues more (and generally desaturating). | ||
#define DICE_TYPE_BY_CHANNEL_PQ 3 | ||
|
||
struct DICESettings | ||
{ | ||
uint Type; | ||
// Determines where the highlights curve (shoulder) starts. | ||
// Values between 0.25 and 0.5 are good with DICE by PQ (any type). | ||
// With linear/rgb DICE this barely makes a difference, zero is a good default but (e.g.) 0.5 would also work. | ||
// This should always be between 0 and 1. | ||
float ShoulderStart; | ||
|
||
// For "Type == DICE_TYPE_BY_LUMINANCE_PQ_CORRECT_CHANNELS_BEYOND_PEAK_WHITE" only: | ||
// The sum of these needs to be <= 1, both within 0 and 1. | ||
// The closer the sum is to 1, the more each color channel will be contained within its peak range. | ||
float DesaturationAmount; | ||
float DarkeningAmount; | ||
}; | ||
|
||
DICESettings DefaultDICESettings() | ||
{ | ||
DICESettings Settings; | ||
Settings.Type = DICE_TYPE_BY_CHANNEL_PQ; | ||
Settings.ShoulderStart = (Settings.Type >= DICE_TYPE_BY_LUMINANCE_RGB) ? (1.f / 4.f) : 0.f; | ||
Settings.DesaturationAmount = 1.0 / 3.0; | ||
Settings.DarkeningAmount = 1.0 / 3.0; | ||
return Settings; | ||
} | ||
|
||
// Tonemapper inspired from DICE. Can work by luminance to maintain hue. | ||
// Takes scRGB colors with a white level (the value of 1 1 1) of 80 nits (sRGB) (to not be confused with paper white). | ||
// Paper white is expected to have already been multiplied in. | ||
float3 DICETonemap( | ||
float3 Color, | ||
float PeakWhite, | ||
const DICESettings Settings) | ||
{ | ||
const float sourceLuminance = renodx::color::y::from::BT709(Color); | ||
|
||
if (Settings.Type != DICE_TYPE_BY_LUMINANCE_RGB) | ||
{ | ||
static const float HDR10_MaxWhite = 10000.f / 80.f; | ||
|
||
const float shoulderStartPQ = Linear_to_PQ((Settings.ShoulderStart * PeakWhite) / HDR10_MaxWhite).x; | ||
if (Settings.Type == DICE_TYPE_BY_LUMINANCE_PQ || Settings.Type == DICE_TYPE_BY_LUMINANCE_PQ_CORRECT_CHANNELS_BEYOND_PEAK_WHITE) | ||
{ | ||
const float sourceLuminanceNormalized = sourceLuminance / HDR10_MaxWhite; | ||
const float sourceLuminancePQ = Linear_to_PQ(sourceLuminanceNormalized, 1).x; | ||
|
||
if (sourceLuminancePQ > shoulderStartPQ) // Luminance below the shoulder (or below zero) don't need to be adjusted | ||
{ | ||
const float peakWhitePQ = Linear_to_PQ(PeakWhite / HDR10_MaxWhite).x; | ||
|
||
const float compressedLuminancePQ = luminanceCompress(sourceLuminancePQ, peakWhitePQ, shoulderStartPQ); | ||
const float compressedLuminanceNormalized = PQ_to_Linear(compressedLuminancePQ).x; | ||
Color *= compressedLuminanceNormalized / sourceLuminanceNormalized; | ||
|
||
if (Settings.Type == DICE_TYPE_BY_LUMINANCE_PQ_CORRECT_CHANNELS_BEYOND_PEAK_WHITE) | ||
{ | ||
float3 Color_BT2020 = renodx::color::bt2020::from::BT709(Color); | ||
if (any(Color_BT2020 > PeakWhite)) // Optional "optimization" branch | ||
{ | ||
float colorLuminance = renodx::color::y::from::BT2020(Color_BT2020); | ||
float colorLuminanceInExcess = colorLuminance - PeakWhite; | ||
float maxColorInExcess = max3(Color_BT2020) - PeakWhite; // This is guaranteed to be >= "colorLuminanceInExcess" | ||
float brightnessReduction = saturate(renodx::math::SafeDivision(PeakWhite, max3(Color_BT2020), 1)); // Fall back to one in case of division by zero | ||
float desaturateAlpha = saturate(renodx::math::SafeDivision(maxColorInExcess, maxColorInExcess - colorLuminanceInExcess, 0)); // Fall back to zero in case of division by zero | ||
Color_BT2020 = lerp(Color_BT2020, colorLuminance, desaturateAlpha * Settings.DesaturationAmount); | ||
Color_BT2020 = lerp(Color_BT2020, Color_BT2020 * brightnessReduction, Settings.DarkeningAmount); // Also reduce the brightness to partially maintain the hue, at the cost of brightness | ||
Color = renodx::color::bt709::from::BT2020(Color_BT2020); | ||
} | ||
} | ||
} | ||
} | ||
else // DICE_TYPE_BY_CHANNEL_PQ | ||
{ | ||
const float peakWhitePQ = Linear_to_PQ(PeakWhite / HDR10_MaxWhite).x; | ||
|
||
// Tonemap in BT.2020 to more closely match the primaries of modern displays | ||
const float3 sourceColorNormalized = renodx::color::bt2020::from::BT709(Color) / HDR10_MaxWhite; | ||
const float3 sourceColorPQ = Linear_to_PQ(sourceColorNormalized, 1); | ||
|
||
for (uint i = 0; i < 3; i++) //TODO LUMA: optimize? will the shader compile already convert this to float3? Or should we already make a version with no branches that works in float3? | ||
{ | ||
if (sourceColorPQ[i] > shoulderStartPQ) // Colors below the shoulder (or below zero) don't need to be adjusted | ||
{ | ||
const float compressedColorPQ = luminanceCompress(sourceColorPQ[i], peakWhitePQ, shoulderStartPQ); | ||
const float compressedColorNormalized = PQ_to_Linear(compressedColorPQ).x; | ||
Color[i] = renodx::color::bt709::from::BT2020(Color[i] * (compressedColorNormalized / sourceColorNormalized[i])).x; | ||
} | ||
} | ||
} | ||
} | ||
else // DICE_TYPE_BY_LUMINANCE_RGB | ||
{ | ||
if (sourceLuminance > Settings.ShoulderStart) // Luminance below the shoulder (or below zero) don't need to be adjusted | ||
{ | ||
const float compressedLuminance = luminanceCompress(sourceLuminance, PeakWhite, PeakWhite * Settings.ShoulderStart); | ||
Color *= compressedLuminance / sourceLuminance; | ||
} | ||
} | ||
|
||
return Color; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#include "./shared.h" | ||
|
||
/// Adjusts gamma based on luminance using the guidelines from ITU BT.2408. | ||
/// At `gammaAdjustmentFactor` = 1.15, it works well to preserve the appearance of | ||
/// shadows and midtones at 100 cd/m2 while scaling the SDR nominal peak white to 203 cd/m2. | ||
/// See: https://www.itu.int/dms_pub/itu-r/opb/rep/R-REP-BT.2408-7-2023-PDF-E.pdf Section 5.1.3.2 | ||
/// @param linearColor The color to adjust. | ||
/// @param gammaAdjustmentFactor Factor to adjust the gamma. | ||
/// @return The color with adjusted gamma. | ||
float3 AdjustGammaOnLuminance(float3 linearColor, float gammaAdjustmentFactor) { | ||
if (gammaAdjustmentFactor == 1.f) return linearColor; | ||
// Calculate the original luminance | ||
float originalLuminance = renodx::color::y::from::BT709(abs(linearColor)); | ||
|
||
// Adjust luminance only if it is less than or equal to 1 | ||
float adjustedLuminance = originalLuminance > 1.0 ? originalLuminance : renodx::color::gamma::Encode(originalLuminance, 1 / gammaAdjustmentFactor); | ||
|
||
// Recombine the colors with the adjusted luminance | ||
if (originalLuminance == 0) return float3(0, 0, 0); // Prevent division by zero | ||
return linearColor * (adjustedLuminance / originalLuminance); | ||
} | ||
|
||
/// Applies a modified `renodx::lut::Sample` that accounts for only black level correction, | ||
/// leaving peak white untouched as LUTs are already HDR, ensuring no highlight impact. | ||
/// @param color_input Input color to apply the LUT to. | ||
/// @param lut_texture The LUT texture. | ||
/// @param lut_config Configuration for LUT sampling. | ||
/// @return Color output after applying LUT correction. | ||
float3 LUTBlackCorrection(float3 color_input, Texture3D lut_texture, renodx::lut::Config lut_config) { | ||
float3 lutInputColor = renodx::lut::ConvertInput(color_input, lut_config); | ||
float3 lutOutputColor = renodx::lut::SampleColor(lutInputColor, lut_config, lut_texture); | ||
float3 color_output = renodx::lut::LinearOutput(lutOutputColor, lut_config); | ||
|
||
float3 original_output = color_output; | ||
|
||
if (lut_config.scaling != 0) { | ||
float3 lutBlack = renodx::lut::SampleColor(renodx::lut::ConvertInput(0, lut_config), lut_config, lut_texture); | ||
float3 lutMid = renodx::lut::SampleColor(renodx::lut::ConvertInput(0.18f, lut_config), lut_config, lut_texture); | ||
float3 unclamped = renodx::lut::Unclamp( | ||
renodx::lut::GammaOutput(lutOutputColor, lut_config), | ||
renodx::lut::GammaOutput(lutBlack, lut_config), | ||
renodx::lut::GammaOutput(lutMid, lut_config), | ||
1.f, // set peak to 1 so it doesn't touch highlights | ||
renodx::lut::GammaInput(color_input, lutInputColor, lut_config)); | ||
float3 recolored = renodx::lut::RecolorUnclamped(color_output, renodx::lut::LinearUnclampedOutput(unclamped, lut_config)); | ||
color_output = lerp(color_output, recolored, lut_config.scaling); | ||
#if 1 // fixes crushed blacks with 2.2 gamma correction | ||
color_output = lerp(color_output, original_output, saturate(pow(color_output, lutMid))); | ||
#endif | ||
} | ||
color_output = renodx::lut::RestoreSaturationLoss(color_input, color_output, lut_config); | ||
if (lut_config.strength != 1.f) { | ||
color_output = lerp(color_input, color_output, lut_config.strength); | ||
} | ||
return color_output; | ||
} | ||
|
||
/// Applies a customized version of RenoDRT tonemapper that tonemaps down to 1.0. | ||
/// This function is used to compress HDR color to SDR range for use alongside `UpgradeToneMap`. | ||
/// | ||
/// @param lutInputColor The color input that needs to be tonemapped. | ||
/// @return The tonemapped color compressed to the SDR range, ensuring that it can be applied to SDR color grading with `UpgradeToneMap`. | ||
float3 renoDRTSmoothClamp(float3 untonemapped) { | ||
renodx::tonemap::renodrt::Config renodrt_config = renodx::tonemap::renodrt::config::Create(); | ||
renodrt_config.nits_peak = 100.f; | ||
renodrt_config.mid_gray_value = 0.18f; | ||
renodrt_config.mid_gray_nits = 18.f; | ||
renodrt_config.exposure = 1.f; | ||
renodrt_config.highlights = 1.f; | ||
renodrt_config.shadows = 1.f; | ||
renodrt_config.contrast = 1.05f; | ||
renodrt_config.saturation = 1.03f; | ||
renodrt_config.dechroma = 0.f; | ||
renodrt_config.flare = 0.f; | ||
renodrt_config.hue_correction_strength = 0.f; | ||
// renodrt_config.hue_correction_source = renodx::tonemap::uncharted2::BT709(untonemapped); | ||
renodrt_config.hue_correction_method = renodx::tonemap::renodrt::config::hue_correction_method::OKLAB; | ||
renodrt_config.tone_map_method = renodx::tonemap::renodrt::config::tone_map_method::DANIELE; | ||
renodrt_config.hue_correction_type = renodx::tonemap::renodrt::config::hue_correction_type::INPUT; | ||
renodrt_config.working_color_space = 2u; | ||
renodrt_config.per_channel = false; | ||
|
||
float3 renoDRTColor = renodx::tonemap::renodrt::BT709(untonemapped, renodrt_config); | ||
renoDRTColor = lerp(untonemapped, renoDRTColor, saturate(renodx::color::y::from::BT709(untonemapped) / renodrt_config.mid_gray_value)); | ||
|
||
return renoDRTColor; | ||
} |
Oops, something went wrong.