|
1 | 1 | #include "./shared.h" |
2 | 2 | #include "./psycho_test11.hlsli" |
3 | | -#include "./macleod_boynton.hlsl" |
4 | 3 |
|
5 | 4 | #define WUWA_PEAK_SCALING (RENODX_PEAK_NITS / RENODX_GAME_NITS) |
6 | 5 |
|
@@ -58,107 +57,70 @@ float3 CorrectHueAndPurityMBGated( |
58 | 57 | float curve_gamma = 1.f, |
59 | 58 | float2 mb_white_override = float2(-1.f, -1.f), |
60 | 59 | float t_min = 1e-6f) { |
| 60 | + static const float MB_NEAR_WHITE_EPSILON = 1e-14f; |
| 61 | + |
61 | 62 | if (purity_strength <= 0.f && hue_strength <= 0.f) { |
62 | 63 | return target_color_bt709; |
63 | 64 | } |
64 | 65 |
|
65 | 66 | float3 target_color_bt2020 = renodx::color::bt2020::from::BT709(target_color_bt709); |
66 | 67 | float3 reference_color_bt2020 = renodx::color::bt2020::from::BT709(reference_color_bt709); |
67 | 68 |
|
68 | | - if (hue_strength <= 0.f) { |
69 | | - float target_purity01 = renodx::color::macleod_boynton::ApplyBT2020( |
70 | | - target_color_bt2020, 1.f, 1.f, mb_white_override, t_min) |
71 | | - .purityCur01; |
72 | | - float reference_purity01 = renodx::color::macleod_boynton::ApplyBT2020( |
73 | | - reference_color_bt2020, 1.f, 1.f, mb_white_override, t_min) |
74 | | - .purityCur01; |
75 | | - float applied_purity01 = lerp(target_purity01, reference_purity01, saturate(purity_strength)); |
76 | | - return renodx::color::bt709::from::BT2020( |
77 | | - renodx::color::macleod_boynton::ApplyBT2020( |
78 | | - target_color_bt2020, applied_purity01, curve_gamma, mb_white_override, t_min) |
79 | | - .rgbOut); |
80 | | - } |
| 69 | + float3 target_mb = renodx::color::macleod_boynton::from::BT2020(target_color_bt2020); |
| 70 | + float3 reference_mb = renodx::color::macleod_boynton::from::BT2020(reference_color_bt2020); |
81 | 71 |
|
82 | | - float3 target_lms = mul(renodx::color::macleod_boynton::XYZ_TO_LMS_2006, |
83 | | - mul(renodx::color::BT2020_TO_XYZ_MAT, target_color_bt2020)); |
84 | | - float target_t = target_lms.x + target_lms.y; |
85 | | - if (target_t <= t_min) { |
| 72 | + if (target_mb.z <= t_min) { |
86 | 73 | return target_color_bt709; |
87 | 74 | } |
88 | 75 |
|
89 | | - float hue_blend = saturate(hue_strength) * |
90 | | - saturate(renodx::math::DivideSafe(target_t - hue_t_ramp_start, |
91 | | - hue_t_ramp_end - hue_t_ramp_start, 0.f)); |
92 | | - |
93 | | - float target_purity01 = renodx::color::macleod_boynton::ApplyBT2020( |
94 | | - target_color_bt2020, 1.f, 1.f, mb_white_override, t_min) |
95 | | - .purityCur01; |
96 | | - float reference_purity01 = renodx::color::macleod_boynton::ApplyBT2020( |
97 | | - reference_color_bt2020, 1.f, 1.f, mb_white_override, t_min) |
98 | | - .purityCur01; |
99 | | - float applied_purity01 = lerp(target_purity01, reference_purity01, saturate(purity_strength)); |
100 | | - |
101 | | - if (hue_blend <= 0.f) { |
102 | | - return renodx::color::bt709::from::BT2020( |
103 | | - renodx::color::macleod_boynton::ApplyBT2020( |
104 | | - target_color_bt2020, applied_purity01, curve_gamma, mb_white_override, t_min) |
105 | | - .rgbOut); |
106 | | - } |
107 | | - |
108 | | - float3 reference_lms = mul(renodx::color::macleod_boynton::XYZ_TO_LMS_2006, |
109 | | - mul(renodx::color::BT2020_TO_XYZ_MAT, reference_color_bt2020)); |
110 | | - |
111 | 76 | float2 white = (mb_white_override.x >= 0.f && mb_white_override.y >= 0.f) |
112 | 77 | ? mb_white_override |
113 | | - : renodx::color::macleod_boynton::MB_White_D65(); |
| 78 | + : renodx::color::macleod_boynton::from::D65XY(); |
114 | 79 |
|
115 | | - float2 target_direction = renodx::color::macleod_boynton::MB_From_LMS(target_lms) - white; |
116 | | - float2 reference_direction = renodx::color::macleod_boynton::MB_From_LMS(reference_lms) - white; |
| 80 | + float2 target_direction = target_mb.xy - white; |
| 81 | + float2 reference_direction = reference_mb.xy - white; |
117 | 82 |
|
118 | 83 | float target_len_sq = dot(target_direction, target_direction); |
119 | 84 | float reference_len_sq = dot(reference_direction, reference_direction); |
120 | 85 |
|
121 | | - if (target_len_sq < renodx::color::macleod_boynton::MB_NEAR_WHITE_EPSILON && |
122 | | - reference_len_sq < renodx::color::macleod_boynton::MB_NEAR_WHITE_EPSILON) { |
123 | | - return renodx::color::bt709::from::BT2020( |
124 | | - renodx::color::macleod_boynton::ApplyBT2020( |
125 | | - target_color_bt2020, applied_purity01, curve_gamma, mb_white_override, t_min) |
126 | | - .rgbOut); |
| 86 | + if (target_len_sq < MB_NEAR_WHITE_EPSILON && reference_len_sq < MB_NEAR_WHITE_EPSILON) { |
| 87 | + return target_color_bt709; |
127 | 88 | } |
128 | 89 |
|
129 | | - float2 target_unit = (target_len_sq > renodx::color::macleod_boynton::MB_NEAR_WHITE_EPSILON) |
| 90 | + float target_len = sqrt(max(target_len_sq, 0.f)); |
| 91 | + float reference_len = sqrt(max(reference_len_sq, 0.f)); |
| 92 | + |
| 93 | + float hue_blend = saturate(hue_strength) * |
| 94 | + saturate(renodx::math::DivideSafe(target_mb.z - hue_t_ramp_start, |
| 95 | + hue_t_ramp_end - hue_t_ramp_start, 0.f)); |
| 96 | + |
| 97 | + float purity_blend = pow(saturate(purity_strength), max(curve_gamma, 1e-6f)); |
| 98 | + float applied_purity = lerp(target_len, reference_len, purity_blend); |
| 99 | + |
| 100 | + float2 target_unit = (target_len > MB_NEAR_WHITE_EPSILON) |
130 | 101 | ? target_direction * rsqrt(target_len_sq) |
131 | 102 | : float2(0.f, 0.f); |
132 | | - float2 reference_unit = (reference_len_sq > renodx::color::macleod_boynton::MB_NEAR_WHITE_EPSILON) |
| 103 | + float2 reference_unit = (reference_len > MB_NEAR_WHITE_EPSILON) |
133 | 104 | ? reference_direction * rsqrt(reference_len_sq) |
134 | 105 | : target_unit; |
135 | | - if (target_len_sq <= renodx::color::macleod_boynton::MB_NEAR_WHITE_EPSILON) { |
| 106 | + if (target_len <= MB_NEAR_WHITE_EPSILON) { |
136 | 107 | target_unit = reference_unit; |
137 | 108 | } |
138 | 109 |
|
139 | | - float2 blended_unit = lerp(target_unit, reference_unit, hue_blend); |
140 | | - float blended_len_sq = dot(blended_unit, blended_unit); |
141 | | - if (blended_len_sq <= renodx::color::macleod_boynton::MB_NEAR_WHITE_EPSILON) { |
142 | | - blended_unit = (hue_blend >= 0.5f) ? reference_unit : target_unit; |
143 | | - blended_len_sq = dot(blended_unit, blended_unit); |
144 | | - } |
145 | | - blended_unit *= rsqrt(max(blended_len_sq, 1e-20f)); |
146 | | - |
147 | | - float seed_len = sqrt(max(target_len_sq, 0.f)); |
148 | | - if (seed_len <= 1e-6f) { |
149 | | - seed_len = sqrt(max(reference_len_sq, 0.f)); |
| 110 | + float2 blended_unit = target_unit; |
| 111 | + if (hue_blend > 0.f) { |
| 112 | + blended_unit = lerp(target_unit, reference_unit, hue_blend); |
| 113 | + float blended_len_sq = dot(blended_unit, blended_unit); |
| 114 | + if (blended_len_sq <= MB_NEAR_WHITE_EPSILON) { |
| 115 | + blended_unit = (hue_blend >= 0.5f) ? reference_unit : target_unit; |
| 116 | + blended_len_sq = dot(blended_unit, blended_unit); |
| 117 | + } |
| 118 | + blended_unit *= rsqrt(max(blended_len_sq, 1e-20f)); |
150 | 119 | } |
151 | | - seed_len = max(seed_len, 1e-6f); |
152 | | - |
153 | | - float3 seed_bt2020 = mul( |
154 | | - renodx::color::XYZ_TO_BT2020_MAT, |
155 | | - mul(renodx::color::macleod_boynton::LMS_TO_XYZ_2006, |
156 | | - renodx::color::macleod_boynton::LMS_From_MB_T(white + blended_unit * seed_len, target_t))); |
157 | 120 |
|
158 | | - return renodx::color::bt709::from::BT2020( |
159 | | - renodx::color::macleod_boynton::ApplyBT2020( |
160 | | - seed_bt2020, applied_purity01, curve_gamma, mb_white_override, t_min) |
161 | | - .rgbOut); |
| 121 | + float2 final_mb_xy = white + blended_unit * max(applied_purity, 0.f); |
| 122 | + float3 final_bt2020 = renodx::color::bt2020::from::MacLeodBoynton(final_mb_xy, target_mb.z); |
| 123 | + return renodx::color::bt709::from::BT2020(final_bt2020); |
162 | 124 | } |
163 | 125 |
|
164 | 126 | namespace lut { |
|
0 commit comments