mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-02 18:11:38 +01:00
86 lines
2.4 KiB
Plaintext
86 lines
2.4 KiB
Plaintext
|
// References:
|
||
|
// https://www.unravel.com.au/understanding-color-spaces
|
||
|
|
||
|
// SMPTE 170M - BT.601 (NTSC-M) -> BT.709
|
||
|
mat3 from_NTSCM = transpose(mat3(
|
||
|
0.939497225737661, 0.0502268452914346, 0.0102759289709032,
|
||
|
0.0177558637510127, 0.965824605885027, 0.0164195303639603,
|
||
|
-0.00162163209967010, -0.00437400622653655, 1.00599563832621));
|
||
|
|
||
|
// ARIB TR-B9 (9300K+27MPCD with chromatic adaptation) (NTSC-J) -> BT.709
|
||
|
mat3 from_NTSCJ = transpose(mat3(
|
||
|
0.823613036967492, -0.0943227111084757, 0.00799341532931119,
|
||
|
0.0289258355537324, 1.02310733489462, 0.00243547111576797,
|
||
|
-0.00569501554980891, 0.0161828357559315, 1.22328453915712));
|
||
|
|
||
|
// EBU - BT.470BG/BT.601 (PAL) -> BT.709
|
||
|
mat3 from_PAL = transpose(mat3(
|
||
|
1.04408168421813, -0.0440816842181253, 0.000000000000000,
|
||
|
0.000000000000000, 1.00000000000000, 0.000000000000000,
|
||
|
0.000000000000000, 0.0118044782106489, 0.988195521789351));
|
||
|
|
||
|
float3 LinearTosRGBGamma(float3 color)
|
||
|
{
|
||
|
float a = 0.055;
|
||
|
|
||
|
for (int i = 0; i < 3; ++i)
|
||
|
{
|
||
|
float x = color[i];
|
||
|
if (x <= 0.0031308)
|
||
|
x = x * 12.92;
|
||
|
else
|
||
|
x = (1.0 + a) * pow(x, 1.0 / 2.4) - a;
|
||
|
color[i] = x;
|
||
|
}
|
||
|
|
||
|
return color;
|
||
|
}
|
||
|
|
||
|
void main()
|
||
|
{
|
||
|
// Note: sampling in gamma space is "wrong" if the source
|
||
|
// and target resolution don't match exactly.
|
||
|
// Fortunately at the moment here they always should but to do this correctly,
|
||
|
// we'd need to sample from 4 pixels, de-apply the gamma from each of these,
|
||
|
// and then do linear sampling on their corrected value.
|
||
|
float4 color = Sample();
|
||
|
|
||
|
// Convert to linear space to do any other kind of operation
|
||
|
color.rgb = pow(color.rgb, game_gamma.xxx);
|
||
|
|
||
|
if (OptionEnabled(correct_color_space))
|
||
|
{
|
||
|
if (game_color_space == 0)
|
||
|
color.rgb = color.rgb * from_NTSCM;
|
||
|
else if (game_color_space == 1)
|
||
|
color.rgb = color.rgb * from_NTSCJ;
|
||
|
else if (game_color_space == 2)
|
||
|
color.rgb = color.rgb * from_PAL;
|
||
|
}
|
||
|
|
||
|
if (OptionEnabled(hdr_output))
|
||
|
{
|
||
|
const float hdr_paper_white = hdr_paper_white_nits / hdr_sdr_white_nits;
|
||
|
color.rgb *= hdr_paper_white;
|
||
|
}
|
||
|
|
||
|
if (OptionEnabled(linear_space_output))
|
||
|
{
|
||
|
// Nothing to do here
|
||
|
}
|
||
|
// Correct the SDR gamma for sRGB (PC/Monitor) or ~2.2 (Common TV gamma)
|
||
|
else if (OptionEnabled(correct_gamma))
|
||
|
{
|
||
|
if (OptionEnabled(sdr_display_gamma_sRGB))
|
||
|
color.rgb = LinearTosRGBGamma(color.rgb);
|
||
|
else
|
||
|
color.rgb = pow(color.rgb, (1.0 / sdr_display_custom_gamma).xxx);
|
||
|
}
|
||
|
// Restore the original gamma without changes
|
||
|
else
|
||
|
{
|
||
|
color.rgb = pow(color.rgb, (1.0 / game_gamma).xxx);
|
||
|
}
|
||
|
|
||
|
SetOutput(color);
|
||
|
}
|