1010 float max_nits ; /* 1000.0f */
1111 uint subpixel_layout ; /* 0 */
1212 float scanlines ; /* 1.0f */
13- float expand_gamut ; /* 0.0f */
13+ uint expand_gamut ; /* 0 */
1414 float inverse_tonemap ;
1515 float hdr10 ;
1616};
@@ -82,14 +82,14 @@ static const float k_crt_green_horizontal_convergence = 0.0f;
8282static const float k_crt_blue_horizontal_convergence = 0.0f ;
8383
8484static const float k_crt_red_scanline_min = 0.45f ;
85- static const float k_crt_red_scanline_max = 0.70f ;
86- static const float k_crt_red_scanline_attack = 0.30f ;
85+ static const float k_crt_red_scanline_max = 0.90f ;
86+ static const float k_crt_red_scanline_attack = 0.60f ;
8787static const float k_crt_green_scanline_min = 0.45f ;
88- static const float k_crt_green_scanline_max = 0.70f ;
89- static const float k_crt_green_scanline_attack = 0.30f ;
88+ static const float k_crt_green_scanline_max = 0.90f ;
89+ static const float k_crt_green_scanline_attack = 0.60f ;
9090static const float k_crt_blue_scanline_min = 0.45f ;
91- static const float k_crt_blue_scanline_max = 0.70f ;
92- static const float k_crt_blue_scanline_attack = 0.30f ;
91+ static const float k_crt_blue_scanline_max = 0.90f ;
92+ static const float k_crt_blue_scanline_attack = 0.60f ;
9393
9494static const float k_crt_red_beam_sharpness = 1.30f ;
9595static const float k_crt_red_beam_attack = 1.00f ;
@@ -111,6 +111,13 @@ static const float3x3 k709to2020 =
111111 { 0.0163916f , 0.0880132f , 0.8955950f }
112112};
113113
114+ static const float3x3 k2020toP3 =
115+ {
116+ { 1.343578f , -0.282180f , -0.061399f },
117+ {-0.065297f , 1.075788f , -0.010490f },
118+ { 0.002822f , -0.019598f , 1.016777f }
119+ };
120+
114121static const float4 kFallOffControlPoints = float4 (0.0f , 0.0f , 0.0f , 1.0f );
115122static const float4 kAttackControlPoints = float4 (0.0f , 1.0f , 1.0f , 1.0f );
116123
@@ -122,9 +129,9 @@ static const float4x4 kCubicBezier = float4x4( 1.0f, 0.0f, 0.0f, 0.0f,
122129/* START Converted from (Copyright (c) Microsoft Corporation - Licensed under the MIT License.) https://github.com/microsoft/Xbox-ATG-Samples/tree/master/Kits/ATGTK/HDR */
123130static const float3x3 kExpanded709to2020 =
124131{
125- { 0.6274040f , 0.3292820f , 0.0433136f },
126- { 0.0457456 , 0.941777 , 0.0124772 },
127- { -0.00121055 , 0.0176041 , 0.983607 }
132+ { 0.6274040 , 0.3292820 , 0.0433136 },
133+ { 0.0457456 , 0.941777 , 0.0124772 },
134+ {-0.00121055 , 0.0176041 , 0.983607 }
128135};
129136
130137float3 LinearToST2084 (float3 normalizedLinearValue )
@@ -149,59 +156,110 @@ float3 InverseTonemap(const float3 sdr_linear, const float max_nits, const float
149156 return sdr_linear * (tonemapped_val / input_val );
150157}
151158
152- float4 Sample (float2 texcoord )
159+ float3 Sample (float2 texcoord )
153160{
154161 const float4 sdr = t0 .Sample (s0 , texcoord );
155162
156- const float3 sdr_linear = pow (abs (sdr .rgb ), 2.2f );
163+ const float3 sdr_linear = pow (abs (sdr .rgb ), 2.22f );
157164
158- return float4 ( sdr_linear , sdr . a ) ;
165+ return sdr_linear ;
159166}
160167
161168float4 Sample (float4 colour , float2 texcoord )
162169{
163170 const float4 sdr = colour * t0 .Sample (s0 , texcoord );
164171
165- const float3 sdr_linear = pow (abs (sdr .rgb ), 2.2f );
172+ const float3 sdr_linear = pow (abs (sdr .rgb ), 2.22f );
166173
167174 return float4 (sdr_linear , sdr .a );
168175}
169176
170- float4 HDR (const float4 sdr_linear )
177+ float3 To2020 (const float3 sdr_linear )
171178{
172- const float3 hdr_linear = InverseTonemap (sdr_linear .rgb , global .max_nits , global .paper_white_nits );
179+ float3 rec2020 ;
180+
181+ if (global .expand_gamut == 0 )
182+ {
183+ rec2020 = mul (k709to2020 , sdr_linear );
184+ }
185+ else if (global .expand_gamut == 1 )
186+ {
187+ rec2020 = mul ( kExpanded709to2020 , sdr_linear );
188+ }
189+ else if (global .expand_gamut == 2 )
190+ {
191+ rec2020 = mul (k709to2020 , sdr_linear );
192+ rec2020 = mul (k2020toP3 , rec2020 );
193+ }
194+ else
195+ {
196+ rec2020 = sdr_linear ;
197+ }
173198
174- return float4 (hdr_linear , sdr_linear .a );
199+ rec2020 = max (rec2020 , float3 (0.0f , 0.0f , 0.0f ));
200+
201+ return rec2020 ;
175202}
176203
177- float3 HDR10 (const float3 hdr_linear )
204+ float4 To2020 (const float4 sdr_linear )
178205{
179- float3 rec2020 = mul ( k709to2020 , hdr_linear ) ;
206+ float3 rec2020 ;
180207
181- if (global .expand_gamut > 0.0f )
208+ if (global .expand_gamut == 0 )
209+ {
210+ rec2020 = mul (k709to2020 , sdr_linear .rgb );
211+ }
212+ else if (global .expand_gamut == 1 )
213+ {
214+ rec2020 = mul ( kExpanded709to2020 , sdr_linear .rgb );
215+ }
216+ else if (global .expand_gamut == 2 )
217+ {
218+ rec2020 = mul (k709to2020 , sdr_linear .rgb );
219+ rec2020 = mul (k2020toP3 , rec2020 );
220+ }
221+ else
182222 {
183- rec2020 = mul ( kExpanded709to2020 , hdr_linear ) ;
223+ rec2020 = sdr_linear . rgb ;
184224 }
185225
186- const float3 linearColour = rec2020 * (global .paper_white_nits / kMaxNitsFor2084 );
226+ rec2020 = max (rec2020 , float3 (0.0f , 0.0f , 0.0f ));
227+
228+ return float4 (rec2020 , sdr_linear .a );
229+ }
230+
231+ float3 HDR (const float3 sdr_linear )
232+ {
233+ return InverseTonemap (sdr_linear , global .max_nits , global .paper_white_nits );
234+ }
235+
236+ float4 HDR (const float4 sdr_linear )
237+ {
238+ const float3 hdr_linear = InverseTonemap (sdr_linear .rgb , global .max_nits , global .paper_white_nits );
239+
240+ return float4 (hdr_linear , sdr_linear .a );
241+ }
242+
243+ float3 LinearToSignal (const float3 linear_colour )
244+ {
245+ // Always Encode to Gamma 2.4
246+ return pow (max (linear_colour .rgb , float3 (0.0f , 0.0f , 0.0f )), 1.0f / 2.4f );
247+ }
248+
249+ float3 HDR10 (const float3 hdr_linear )
250+ {
251+ const float3 pq_input = hdr_linear * (global .paper_white_nits / kMaxNitsFor2084 );
187252
188- const float3 hdr10 = LinearToST2084 (max (linearColour , 0.0f ));
253+ const float3 hdr10 = LinearToST2084 (max (pq_input , 0.0f ));
189254
190255 return hdr10 ;
191256}
192257
193258float4 HDR10 (const float4 hdr_linear )
194259{
195- float3 rec2020 = mul (k709to2020 , hdr_linear .rgb );
196-
197- if (global .expand_gamut > 0.0f )
198- {
199- rec2020 = mul ( kExpanded709to2020 , hdr_linear .rgb );
200- }
201-
202- const float3 linearColour = rec2020 * (global .paper_white_nits / kMaxNitsFor2084 );
260+ const float3 pq_input = hdr_linear .rgb * (global .paper_white_nits / kMaxNitsFor2084 );
203261
204- const float3 hdr10 = LinearToST2084 (max (linearColour , 0.0f ));
262+ const float3 hdr10 = LinearToST2084 (max (pq_input , 0.0f ));
205263
206264 return float4 (hdr10 , hdr_linear .a );
207265}
@@ -248,13 +306,13 @@ float ScanlineColour(const uint channel,
248306 const float2 tex_coord_0 = float2 (source_tex_coord_x , source_tex_coord_y );
249307 const float2 tex_coord_1 = float2 (source_tex_coord_x + (1.0f / source_size .x ), source_tex_coord_y );
250308
251- const float hdr_channel_0 = HDR (Sample (tex_coord_0 ))[channel ];
252- const float hdr_channel_1 = HDR (Sample (tex_coord_1 ))[channel ];
309+ const float hdr_channel_0 = LinearToSignal ( HDR (To2020 ( Sample (tex_coord_0 )) ))[channel ];
310+ const float hdr_channel_1 = LinearToSignal ( HDR (To2020 ( Sample (tex_coord_1 )) ))[channel ];
253311
254312 const float horiz_interp = Bezier (narrowed_source_pixel_offset , BeamControlPoints (beam_attack , hdr_channel_0 > hdr_channel_1 ));
255313 const float hdr_channel = lerp (hdr_channel_0 , hdr_channel_1 , horiz_interp );
256314
257- const float physics_signal = pow ( max ( hdr_channel , 0.0f ), 1.0f / 2.2f ) ;
315+ const float physics_signal = hdr_channel ;
258316
259317 const float signal_strength = clamp (physics_signal , 0.0f , 2.5f );
260318
@@ -368,7 +426,9 @@ float3 Scanlines(float2 texcoord)
368426 scanline_colour = scanline_channel_0 * kColourMask [channel_0 ];
369427 }
370428
371- return HDR10 (scanline_colour );
429+ float3 linear_colour = pow (max (scanline_colour , float3 (0.0f , 0.0f , 0.0f )), 2.4f );
430+
431+ return HDR10 (linear_colour );
372432}
373433
374434float4 PSMain (PSInput input ) : SV_TARGET
@@ -381,16 +441,16 @@ float4 PSMain(PSInput input) : SV_TARGET
381441 }
382442 else
383443 {
384- return HDR10 (HDR (Sample (input .color , input .texcoord )));
444+ return HDR10 (HDR (To2020 ( Sample (input .color , input .texcoord ) )));
385445 }
386446 }
387447 else if (global .inverse_tonemap > 0.0f )
388448 {
389- return HDR (Sample (input .color , input .texcoord ));
449+ return HDR (To2020 ( Sample (input .color , input .texcoord ) ));
390450 }
391451 else if (global .hdr10 > 0.0f )
392452 {
393- return HDR10 (Sample (input .color , input .texcoord ));
453+ return HDR10 (To2020 ( Sample (input .color , input .texcoord ) ));
394454 }
395455 else
396456 {
0 commit comments