Grade - Formatting + Notes + Cosmetics (#465)

* Grade - Formatting + Notes + Cosmetics

- Adopted some GLES related type consistency and formatting (still not compatible with GLES and not planned)
- Some notes on Phosphors
- Cosmetics

* Grade - Formatting + Notes + Cosmetics

- Adopted some GLES related type consistency and formatting (still not compatible with GLES and not planned)
- Some notes on Phosphors
- Cosmetics
This commit is contained in:
Dogway 2023-07-20 03:08:28 +01:00 committed by GitHub
parent 75b81b5a6e
commit 6485e4c610
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 116 deletions

View file

@ -82,7 +82,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
} global; } global;
/* /*
Grade (16-06-2023) Grade (17-07-2023)
> See settings decriptions at: https://forums.libretro.com/t/dogways-grading-shader-slang/27148/442 > See settings decriptions at: https://forums.libretro.com/t/dogways-grading-shader-slang/27148/442
> Ubershader grouping some monolithic color related shaders: > Ubershader grouping some monolithic color related shaders:
@ -287,17 +287,17 @@ vec3 YxytoXYZ(vec3 Yxy) {
vec3 wp_adjust(vec3 RGB, float temperature, mat3 primaries, mat3 display) { vec3 wp_adjust(vec3 RGB, float temperature, mat3 primaries, mat3 display) {
float temp3 = 1000. / temperature; float temp3 = 1000. / temperature;
float temp6 = 1000000. / pow(temperature, 2.); float temp6 = 1000000. / pow(temperature, 2.0);
float temp9 = 1000000000. / pow(temperature, 3.); float temp9 = 1000000000. / pow(temperature, 3.0);
vec3 wp = vec3(1.); vec3 wp = vec3(1.0);
wp.x = (temperature < 5500.) ? 0.244058 + 0.0989971 * temp3 + 2.96545 * temp6 - 4.59673 * temp9 : \ wp.x = (temperature < 5500.) ? 0.244058 + 0.0989971 * temp3 + 2.96545 * temp6 - 4.59673 * temp9 : \
(temperature < 8000.) ? 0.200033 + 0.9545630 * temp3 - 2.53169 * temp6 + 7.08578 * temp9 : \ (temperature < 8000.) ? 0.200033 + 0.9545630 * temp3 - 2.53169 * temp6 + 7.08578 * temp9 : \
0.237045 + 0.2437440 * temp3 + 1.94062 * temp6 - 2.11004 * temp9 ; 0.237045 + 0.2437440 * temp3 + 1.94062 * temp6 - 2.11004 * temp9 ;
wp.y = -0.275275 + 2.87396 * wp.x - 3.02034 * pow(wp.x,2) + 0.0297408 * pow(wp.x,3); wp.y = -0.275275 + 2.87396 * wp.x - 3.02034 * pow(wp.x,2.0) + 0.0297408 * pow(wp.x,3.0);
wp.z = 1. - wp.x - wp.y; wp.z = 1.0 - wp.x - wp.y;
const mat3 CAT16 = mat3( const mat3 CAT16 = mat3(
0.401288,-0.250268, -0.002079, 0.401288,-0.250268, -0.002079,
@ -334,17 +334,17 @@ float EOTF_1886a(float color, float bl, float brightness, float contrast) {
// Contrast = 100 // Contrast = 100
const float wl = 100.0; const float wl = 100.0;
float b = pow(bl, 1/2.4); float b = pow(bl, 1./2.4);
float a = pow(wl, 1/2.4)-b; float a = pow(wl, 1./2.4)-b;
b = (brightness-50) / 250. + b/a; // -0.20 to +0.20 b = (brightness-50.) / 250. + b/a; // -0.20 to +0.20
a = contrast!=50 ? pow(2,(contrast-50)/50.) : 1.; // 0.50 to +2.00 a = contrast!=50. ? pow(2.,(contrast-50.)/50.) : 1.; // 0.50 to +2.00
const float Vc = 0.35; // Offset const float Vc = 0.35; // Offset
float Lw = wl/100. * a; // White level float Lw = wl/100. * a; // White level
float Lb = min( b * a,Vc); // Black level float Lb = min( b * a,Vc); // Black level
const float a1 = 2.6; // Shoulder gamma const float a1 = 2.6; // Shoulder gamma
const float a2 = 3.0; // Knee gamma const float a2 = 3.0; // Knee gamma
float k = Lw /pow(1 + Lb, a1); float k = Lw /pow(1. + Lb, a1);
float sl = k * pow(Vc + Lb, a1-a2); // Slope for knee gamma float sl = k * pow(Vc + Lb, a1-a2); // Slope for knee gamma
color = color >= Vc ? k * pow(color + Lb, a1 ) : sl * pow(color + Lb, a2 ); color = color >= Vc ? k * pow(color + Lb, a1 ) : sl * pow(color + Lb, a2 );
@ -442,7 +442,7 @@ float rolled_gain(float color, float gain) {
float gx = abs(gain) + 0.001; float gx = abs(gain) + 0.001;
float anch = (gain > 0.0) ? 0.5 / (gx / 2.0) : 0.5 / gx; float anch = (gain > 0.0) ? 0.5 / (gx / 2.0) : 0.5 / gx;
color = (gain > 0.0) ? color * ((color - anch) / (1 - anch)) : color * ((1 - anch) / (color - anch)) * (1 - gain); color = (gain > 0.0) ? color * ((color - anch) / (1.0 - anch)) : color * ((1.0 - anch) / (color - anch)) * (1.0 - gain);
return color; return color;
} }
@ -475,11 +475,11 @@ float SatMask(float color_r, float color_g, float color_b) {
vec3 GamutCompression (vec3 rgb, float grey) { vec3 GamutCompression (vec3 rgb, float grey) {
// Limit/Thres order is Cyan, Magenta, Yellow // Limit/Thres order is Cyan, Magenta, Yellow
vec3 beam = max(vec3(0.0),vec3(beamg,(beamb+beamr)/2,(beamr+beamg)/2)); vec3 beam = max(vec3(0.0),vec3(beamg,(beamb+beamr)/2.,(beamr+beamg)/2.));
vec3 sat = max(vec3(0.0),vec3(satg, (satb +satr) /2,(satr +satg) /2)+1); // center at 1 vec3 sat = max(vec3(0.0),vec3(satg, (satb +satr) /2.,(satr +satg) /2.)+1.); // center at 1
float temp = max(0,abs(global.wp_temperature-7000)-1000)/825.0+1; // center at 1 float temp = max(0.0,abs(global.wp_temperature-7000.)-1000.)/825.+1.; // center at 1
vec3 WPD = global.wp_temperature < 7000 ? vec3(1,temp,(temp-1)/2+1) : vec3((temp-1)/2+1,temp,1); vec3 WPD = global.wp_temperature < 7000. ? vec3(1.,temp,(temp-1.)/2.+1.) : vec3((temp-1.)/2.+1.,temp,1.);
sat = max(0.0,g_sat+1)*(sat*beam) * WPD; sat = max(0.0,g_sat+1.0)*(sat*beam) * WPD;
mat2x3 LimThres = mat2x3( 0.100000,0.100000,0.100000, mat2x3 LimThres = mat2x3( 0.100000,0.100000,0.100000,
0.125000,0.125000,0.125000); 0.125000,0.125000,0.125000);
@ -522,7 +522,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
vec3 dl = 1.0+vec3(LimThres[0])*sat; vec3 dl = 1.0+vec3(LimThres[0])*sat;
// Calculate scale so compression function passes through distance limit: (x=dl, y=1) // Calculate scale so compression function passes through distance limit: (x=dl, y=1)
vec3 s = (vec3(1)-th)/sqrt(max(vec3(1.001), dl)-1.0); vec3 s = (vec3(1.0)-th)/sqrt(max(vec3(1.001), dl)-1.0);
// Achromatic axis // Achromatic axis
float ac = max(rgb.x, max(rgb.y, rgb.z)); float ac = max(rgb.x, max(rgb.y, rgb.z));
@ -539,7 +539,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
// Inverse RGB Ratios to RGB // Inverse RGB Ratios to RGB
// and Mask with "luma" // and Mask with "luma"
return mix(rgb, ac-cd.xyz*abs(ac), pow(grey,1/params.g_CRT_l)); return mix(rgb, ac-cd.xyz*abs(ac), pow(grey,1.0/params.g_CRT_l));
} }
@ -563,8 +563,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
// Rymax 0.701088 // Rymax 0.701088
// R'G'B' full range to Decorrelated Intermediate (Y,B-Y,R-Y) // R'G'B' full range to Decorrelated Intermediate (Y,B-Y,R-Y)
// Rows should sum to 0, except first one which sums 1 // Rows should sum to 0, except first one which sums 1
const mat3 YByRy = const mat3 YByRy = mat3(
mat3(
0.298912, 0.586603, 0.114485, 0.298912, 0.586603, 0.114485,
-0.298912,-0.586603, 0.885515, -0.298912,-0.586603, 0.885515,
0.701088,-0.586603,-0.114485); 0.701088,-0.586603,-0.114485);
@ -578,8 +577,8 @@ const mat3 YByRy =
// Y excursion is limited to 16-235 for NTSC-U and 0-235 for PAL and NTSC-J // Y excursion is limited to 16-235 for NTSC-U and 0-235 for PAL and NTSC-J
vec3 r601_YUV(vec3 RGB, float NTSC_U) { vec3 r601_YUV(vec3 RGB, float NTSC_U) {
const float sclU = ((0.5*(235-16)+16)/255.); // This yields Luma grey at around 0.49216 or 125.5 in 8-bit const float sclU = ((0.5*(235.-16.)+16.)/255.); // This yields Luma grey at around 0.49216 or 125.5 in 8-bit
const float sclV = (240-16) /255. ; // This yields Chroma range at around 0.87843 or 224 in 8-bit const float sclV = (240.-16.) /255. ; // This yields Chroma range at around 0.87843 or 224 in 8-bit
mat3 conv_mat = mat3( mat3 conv_mat = mat3(
vec3(YByRy[0]), vec3(YByRy[0]),
@ -628,14 +627,12 @@ vec3 Quantize8_f3(vec3 col) {
// Hunt-Pointer-Estevez D65 cone response // Hunt-Pointer-Estevez D65 cone response
// modification for IPT model // modification for IPT model
const mat3 LMS = const mat3 LMS = mat3(
mat3(
0.4002, 0.7075, -0.0807, 0.4002, 0.7075, -0.0807,
-0.2280, 1.1500, 0.0612, -0.2280, 1.1500, 0.0612,
0.0000, 0.0000, 0.9184); 0.0000, 0.0000, 0.9184);
const mat3 IPT = const mat3 IPT = mat3(
mat3(
0.4000, 0.4000, 0.2000, 0.4000, 0.4000, 0.2000,
4.4550, -4.8510, 0.3960, 4.4550, -4.8510, 0.3960,
0.8056, 0.3572, -1.1628); 0.8056, 0.3572, -1.1628);
@ -649,28 +646,28 @@ mat3(
////// STANDARDS /////// ////// STANDARDS ///////
// SMPTE RP 145-1994 (SMPTE-C), 170M-1999 // SMPTE RP 145-1994 (SMPTE-C), 170M-1999
// SMPTE-C - Standard Phosphor (Rec.601 NTSC) // SMPTE-C - Standard Phosphor (Rec.601 NTSC)
// Standardized in 1982 (as CCIR Rec.601-1) after "Conrac Corp. & RCA" P22 phosphors (circa 1969) for consumer CRTs
// ILLUMINANT: D65->[0.31266142,0.3289589] // ILLUMINANT: D65->[0.31266142,0.3289589]
const mat3 SMPTE170M_ph = const mat3 SMPTE170M_ph = mat3(
mat3(
0.630, 0.310, 0.155, 0.630, 0.310, 0.155,
0.340, 0.595, 0.070, 0.340, 0.595, 0.070,
0.030, 0.095, 0.775); 0.030, 0.095, 0.775);
// ITU-R BT.470/601 (B/G) // ITU-R BT.470/601 (B/G)
// EBU Tech.3213 PAL - Standard Phosphor for Studio Monitors // EBU Tech.3213 PAL - Standard Phosphor for Studio Monitors (also used in Sony BVMs and Higher-end PVMs)
// ILLUMINANT: D65->[0.31266142,0.3289589] // ILLUMINANT: D65->[0.31266142,0.3289589]
const mat3 SMPTE470BG_ph = const mat3 SMPTE470BG_ph = mat3(
mat3(
0.640, 0.290, 0.150, 0.640, 0.290, 0.150,
0.330, 0.600, 0.060, 0.330, 0.600, 0.060,
0.030, 0.110, 0.790); 0.030, 0.110, 0.790);
// NTSC-J P22 // NTSC-J P22
// Mix between averaging KV-20M20, KDS VS19, Dell D93, 4-TR-B09v1_0.pdf and Phosphor Handbook 'P22' // Mix between averaging KV-20M20, KDS VS19, Dell D93, 4-TR-B09v1_0.pdf and Phosphor Handbook 'P22'
// Phosphors based on 1975's EBU Tech.3123-E (formerly known as JEDEC-P22)
// Typical P22 phosphors used in Japanese consumer CRTs with 9300K+27MPCD white point
// ILLUMINANT: D93->[0.281000,0.311000] (CCT of 8945.436K) // ILLUMINANT: D93->[0.281000,0.311000] (CCT of 8945.436K)
// ILLUMINANT: D97->[0.285000,0.285000] (CCT of 9696K) for Nanao MS-2930s series (around 10000.0K for wp_adjust() daylight fit) // ILLUMINANT: D97->[0.285000,0.285000] (CCT of 9696K) for Nanao MS-2930s series (around 10000.0K for wp_adjust() daylight fit)
const mat3 P22_J_ph = const mat3 P22_J_ph = mat3(
mat3(
0.625, 0.280, 0.152, 0.625, 0.280, 0.152,
0.350, 0.605, 0.062, 0.350, 0.605, 0.062,
0.025, 0.115, 0.786); 0.025, 0.115, 0.786);
@ -681,22 +678,19 @@ const mat3 P22_J_ph =
// You can run any of these P22 primaries either through D65 or D93 indistinctly but typically these were D65 based. // You can run any of these P22 primaries either through D65 or D93 indistinctly but typically these were D65 based.
// P22_80 is roughly the same as the old P22 gamut in Grade 2020. P22 1979-1994 meta measurement. // P22_80 is roughly the same as the old P22 gamut in Grade 2020. P22 1979-1994 meta measurement.
// ILLUMINANT: D65->[0.31266142,0.3289589] // ILLUMINANT: D65->[0.31266142,0.3289589]
const mat3 P22_80s_ph = const mat3 P22_80s_ph = mat3(
mat3(
0.6470, 0.2820, 0.1472, 0.6470, 0.2820, 0.1472,
0.3430, 0.6200, 0.0642, 0.3430, 0.6200, 0.0642,
0.0100, 0.0980, 0.7886); 0.0100, 0.0980, 0.7886);
// P22 improved with tinted phosphors (Use this for NTSC-U 16-bits, and above for 8-bits) // P22 improved with tinted phosphors (Use this for NTSC-U 16-bits, and above for 8-bits)
const mat3 P22_90s_ph = const mat3 P22_90s_ph = mat3(
mat3(
0.6661, 0.3134, 0.1472, 0.6661, 0.3134, 0.1472,
0.3329, 0.6310, 0.0642, 0.3329, 0.6310, 0.0642,
0.0010, 0.0556, 0.7886); 0.0010, 0.0556, 0.7886);
// RPTV (Rear Projection TV) for NTSC-U late 90s, early 00s // RPTV (Rear Projection TV) for NTSC-U late 90s, early 00s
const mat3 RPTV_95s_ph = const mat3 RPTV_95s_ph = mat3(
mat3(
0.640, 0.341, 0.150, 0.640, 0.341, 0.150,
0.335, 0.586, 0.070, 0.335, 0.586, 0.070,
0.025, 0.073, 0.780); 0.025, 0.073, 0.780);
@ -708,29 +702,25 @@ const mat3 RPTV_95s_ph =
//----------------------- Display Primaries ----------------------- //----------------------- Display Primaries -----------------------
// sRGB (IEC 61966-2-1) and ITU-R BT.709-6 (originally CCIR Rec.709) // sRGB (IEC 61966-2-1) and ITU-R BT.709-6 (originally CCIR Rec.709)
const mat3 sRGB_prims = const mat3 sRGB_prims = mat3(
mat3(
0.640, 0.300, 0.150, 0.640, 0.300, 0.150,
0.330, 0.600, 0.060, 0.330, 0.600, 0.060,
0.030, 0.100, 0.790); 0.030, 0.100, 0.790);
// Adobe RGB (1998) // Adobe RGB (1998)
const mat3 Adobe_prims = const mat3 Adobe_prims = mat3(
mat3(
0.640, 0.210, 0.150, 0.640, 0.210, 0.150,
0.330, 0.710, 0.060, 0.330, 0.710, 0.060,
0.030, 0.080, 0.790); 0.030, 0.080, 0.790);
// BT-2020/BT-2100 (from 630nm, 532nm and 467nm) // BT-2020/BT-2100 (from 630nm, 532nm and 467nm)
const mat3 rec2020_prims = const mat3 rec2020_prims = mat3(
mat3(
0.707917792, 0.170237195, 0.131370635, 0.707917792, 0.170237195, 0.131370635,
0.292027109, 0.796518542, 0.045875976, 0.292027109, 0.796518542, 0.045875976,
0.000055099, 0.033244263, 0.822753389); 0.000055099, 0.033244263, 0.822753389);
// SMPTE RP 432-2 (DCI-P3) // SMPTE RP 432-2 (DCI-P3)
const mat3 DCIP3_prims = const mat3 DCIP3_prims = mat3(
mat3(
0.680, 0.265, 0.150, 0.680, 0.265, 0.150,
0.320, 0.690, 0.060, 0.320, 0.690, 0.060,
0.000, 0.045, 0.790); 0.000, 0.045, 0.790);
@ -843,7 +833,7 @@ void main()
float hue_radians_b = 100.0 * M_PI; float hue_radians_b = 100.0 * M_PI;
float hue_b = cos(hue_at + hue_radians_b); float hue_b = cos(hue_at + hue_radians_b);
float msk = dot(clamp(vec3(hue_r, hue_g, hue_b) * chroma * 2, 0.0, 1.0), -vec3(satr, satg, satb)); float msk = dot(clamp(vec3(hue_r, hue_g, hue_b) * chroma * 2.0, 0.0, 1.0), -vec3(satr, satg, satb));
src_h = mix(col, vec3(dot(coeff, col)), msk); src_h = mix(col, vec3(dot(coeff, col)), msk);
float sat_msk = (vibr < 0.0) ? 1.0 - abs(SatMask(src_h.x, src_h.y, src_h.z) - 1.0) * abs(vibr) : \ float sat_msk = (vibr < 0.0) ? 1.0 - abs(SatMask(src_h.x, src_h.y, src_h.z) - 1.0) * abs(vibr) : \
@ -890,13 +880,13 @@ void main()
vpos *= 1.0 - vpos.xy; vpos *= 1.0 - vpos.xy;
float vig = vpos.x * vpos.y * vstr; float vig = vpos.x * vpos.y * vstr;
vig = min(pow(vig, vpower), 1.0); vig = min(pow(vig, vpower), 1.0);
vig = vig >= 0.5 ? smoothstep(0,1,vig) : vig; vig = vig >= 0.5 ? smoothstep(0.0,1.0,vig) : vig;
src_h *= (vignette == 1.0) ? vig : 1.0; src_h *= (vignette == 1.0) ? vig : 1.0;
// Dark to Dim adaptation OOTF; for 709, P3-D65 and 2020 // Dark to Dim adaptation OOTF; for 709, P3-D65 and 2020
float DtD = global.g_Dark_to_Dim > 0.0 ? 1/0.9811 : 1.0; float DtD = global.g_Dark_to_Dim > 0.0 ? 1.0/0.9811 : 1.0;
// EOTF^-1 - Inverted Electro-Optical Transfer Function // EOTF^-1 - Inverted Electro-Optical Transfer Function
vec3 TRC = (SPC == 3.0) ? clamp(pow(src_h, vec3(1./ (563./256.))), 0., 1.) : \ vec3 TRC = (SPC == 3.0) ? clamp(pow(src_h, vec3(1./ (563./256.))), 0., 1.) : \

View file

@ -86,7 +86,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
} global; } global;
/* /*
Grade (16-06-2023) Grade (17-07-2023)
> See settings decriptions at: https://forums.libretro.com/t/dogways-grading-shader-slang/27148/442 > See settings decriptions at: https://forums.libretro.com/t/dogways-grading-shader-slang/27148/442
> Ubershader grouping some monolithic color related shaders: > Ubershader grouping some monolithic color related shaders:
@ -297,17 +297,17 @@ vec3 YxytoXYZ(vec3 Yxy) {
vec3 wp_adjust(vec3 RGB, float temperature, mat3 primaries, mat3 display) { vec3 wp_adjust(vec3 RGB, float temperature, mat3 primaries, mat3 display) {
float temp3 = 1000. / temperature; float temp3 = 1000. / temperature;
float temp6 = 1000000. / pow(temperature, 2.); float temp6 = 1000000. / pow(temperature, 2.0);
float temp9 = 1000000000. / pow(temperature, 3.); float temp9 = 1000000000. / pow(temperature, 3.0);
vec3 wp = vec3(1.); vec3 wp = vec3(1.0);
wp.x = (temperature < 5500.) ? 0.244058 + 0.0989971 * temp3 + 2.96545 * temp6 - 4.59673 * temp9 : \ wp.x = (temperature < 5500.) ? 0.244058 + 0.0989971 * temp3 + 2.96545 * temp6 - 4.59673 * temp9 : \
(temperature < 8000.) ? 0.200033 + 0.9545630 * temp3 - 2.53169 * temp6 + 7.08578 * temp9 : \ (temperature < 8000.) ? 0.200033 + 0.9545630 * temp3 - 2.53169 * temp6 + 7.08578 * temp9 : \
0.237045 + 0.2437440 * temp3 + 1.94062 * temp6 - 2.11004 * temp9 ; 0.237045 + 0.2437440 * temp3 + 1.94062 * temp6 - 2.11004 * temp9 ;
wp.y = -0.275275 + 2.87396 * wp.x - 3.02034 * pow(wp.x,2) + 0.0297408 * pow(wp.x,3); wp.y = -0.275275 + 2.87396 * wp.x - 3.02034 * pow(wp.x,2.0) + 0.0297408 * pow(wp.x,3.0);
wp.z = 1. - wp.x - wp.y; wp.z = 1.0 - wp.x - wp.y;
const mat3 CAT16 = mat3( const mat3 CAT16 = mat3(
0.401288,-0.250268, -0.002079, 0.401288,-0.250268, -0.002079,
@ -344,17 +344,17 @@ float EOTF_1886a(float color, float bl, float brightness, float contrast) {
// Contrast = 100 // Contrast = 100
const float wl = 100.0; const float wl = 100.0;
float b = pow(bl, 1/2.4); float b = pow(bl, 1./2.4);
float a = pow(wl, 1/2.4)-b; float a = pow(wl, 1./2.4)-b;
b = (brightness-50) / 250. + b/a; // -0.20 to +0.20 b = (brightness-50.) / 250. + b/a; // -0.20 to +0.20
a = contrast!=50 ? pow(2,(contrast-50)/50.) : 1.; // 0.50 to +2.00 a = contrast!=50. ? pow(2.,(contrast-50.)/50.) : 1.; // 0.50 to +2.00
const float Vc = 0.35; // Offset const float Vc = 0.35; // Offset
float Lw = wl/100. * a; // White level float Lw = wl/100. * a; // White level
float Lb = min( b * a,Vc); // Black level float Lb = min( b * a,Vc); // Black level
const float a1 = 2.6; // Shoulder gamma const float a1 = 2.6; // Shoulder gamma
const float a2 = 3.0; // Knee gamma const float a2 = 3.0; // Knee gamma
float k = Lw /pow(1 + Lb, a1); float k = Lw /pow(1. + Lb, a1);
float sl = k * pow(Vc + Lb, a1-a2); // Slope for knee gamma float sl = k * pow(Vc + Lb, a1-a2); // Slope for knee gamma
color = color >= Vc ? k * pow(color + Lb, a1 ) : sl * pow(color + Lb, a2 ); color = color >= Vc ? k * pow(color + Lb, a1 ) : sl * pow(color + Lb, a2 );
@ -452,7 +452,7 @@ float rolled_gain(float color, float gain) {
float gx = abs(gain) + 0.001; float gx = abs(gain) + 0.001;
float anch = (gain > 0.0) ? 0.5 / (gx / 2.0) : 0.5 / gx; float anch = (gain > 0.0) ? 0.5 / (gx / 2.0) : 0.5 / gx;
color = (gain > 0.0) ? color * ((color - anch) / (1 - anch)) : color * ((1 - anch) / (color - anch)) * (1 - gain); color = (gain > 0.0) ? color * ((color - anch) / (1.0 - anch)) : color * ((1.0 - anch) / (color - anch)) * (1.0 - gain);
return color; return color;
} }
@ -498,11 +498,11 @@ vec4 mixfix_v4(vec4 a, vec4 b, float c) {
vec3 GamutCompression (vec3 rgb, float grey) { vec3 GamutCompression (vec3 rgb, float grey) {
// Limit/Thres order is Cyan, Magenta, Yellow // Limit/Thres order is Cyan, Magenta, Yellow
vec3 beam = max(vec3(0.0),vec3(beamg,(beamb+beamr)/2,(beamr+beamg)/2)); vec3 beam = max(vec3(0.0),vec3(beamg,(beamb+beamr)/2.,(beamr+beamg)/2.));
vec3 sat = max(vec3(0.0),vec3(satg, (satb +satr) /2,(satr +satg) /2)+1); // center at 1 vec3 sat = max(vec3(0.0),vec3(satg, (satb +satr) /2.,(satr +satg) /2.)+1.); // center at 1
float temp = max(0,abs(global.wp_temperature-7000)-1000)/825.0+1; // center at 1 float temp = max(0.0,abs(global.wp_temperature-7000.)-1000.)/825.+1.; // center at 1
vec3 WPD = global.wp_temperature < 7000 ? vec3(1,temp,(temp-1)/2+1) : vec3((temp-1)/2+1,temp,1); vec3 WPD = global.wp_temperature < 7000. ? vec3(1.,temp,(temp-1.)/2.+1.) : vec3((temp-1.)/2.+1.,temp,1.);
sat = max(0.0,g_sat+1)*(sat*beam) * WPD; sat = max(0.0,g_sat+1.0)*(sat*beam) * WPD;
mat2x3 LimThres = mat2x3( 0.100000,0.100000,0.100000, mat2x3 LimThres = mat2x3( 0.100000,0.100000,0.100000,
0.125000,0.125000,0.125000); 0.125000,0.125000,0.125000);
@ -545,7 +545,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
vec3 dl = 1.0+vec3(LimThres[0])*sat; vec3 dl = 1.0+vec3(LimThres[0])*sat;
// Calculate scale so compression function passes through distance limit: (x=dl, y=1) // Calculate scale so compression function passes through distance limit: (x=dl, y=1)
vec3 s = (vec3(1)-th)/sqrt(max(vec3(1.001), dl)-1.0); vec3 s = (vec3(1.0)-th)/sqrt(max(vec3(1.001), dl)-1.0);
// Achromatic axis // Achromatic axis
float ac = max(rgb.x, max(rgb.y, rgb.z)); float ac = max(rgb.x, max(rgb.y, rgb.z));
@ -562,7 +562,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
// Inverse RGB Ratios to RGB // Inverse RGB Ratios to RGB
// and Mask with "luma" // and Mask with "luma"
return mix(rgb, ac-cd.xyz*abs(ac), pow(grey,1/params.g_CRT_l)); return mix(rgb, ac-cd.xyz*abs(ac), pow(grey,1.0/params.g_CRT_l));
} }
@ -586,8 +586,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
// Rymax 0.701088 // Rymax 0.701088
// R'G'B' full range to Decorrelated Intermediate (Y,B-Y,R-Y) // R'G'B' full range to Decorrelated Intermediate (Y,B-Y,R-Y)
// Rows should sum to 0, except first one which sums 1 // Rows should sum to 0, except first one which sums 1
const mat3 YByRy = const mat3 YByRy = mat3(
mat3(
0.298912, 0.586603, 0.114485, 0.298912, 0.586603, 0.114485,
-0.298912,-0.586603, 0.885515, -0.298912,-0.586603, 0.885515,
0.701088,-0.586603,-0.114485); 0.701088,-0.586603,-0.114485);
@ -601,8 +600,8 @@ const mat3 YByRy =
// Y excursion is limited to 16-235 for NTSC-U and 0-235 for PAL and NTSC-J // Y excursion is limited to 16-235 for NTSC-U and 0-235 for PAL and NTSC-J
vec3 r601_YUV(vec3 RGB, float NTSC_U) { vec3 r601_YUV(vec3 RGB, float NTSC_U) {
const float sclU = ((0.5*(235-16)+16)/255.); // This yields Luma grey at around 0.49216 or 125.5 in 8-bit const float sclU = ((0.5*(235.-16.)+16.)/255.); // This yields Luma grey at around 0.49216 or 125.5 in 8-bit
const float sclV = (240-16) /255. ; // This yields Chroma range at around 0.87843 or 224 in 8-bit const float sclV = (240.-16.) /255. ; // This yields Chroma range at around 0.87843 or 224 in 8-bit
mat3 conv_mat = mat3( mat3 conv_mat = mat3(
vec3(YByRy[0]), vec3(YByRy[0]),
@ -651,14 +650,12 @@ vec3 Quantize8_f3(vec3 col) {
// Hunt-Pointer-Estevez D65 cone response // Hunt-Pointer-Estevez D65 cone response
// modification for IPT model // modification for IPT model
const mat3 LMS = const mat3 LMS = mat3(
mat3(
0.4002, 0.7075, -0.0807, 0.4002, 0.7075, -0.0807,
-0.2280, 1.1500, 0.0612, -0.2280, 1.1500, 0.0612,
0.0000, 0.0000, 0.9184); 0.0000, 0.0000, 0.9184);
const mat3 IPT = const mat3 IPT = mat3(
mat3(
0.4000, 0.4000, 0.2000, 0.4000, 0.4000, 0.2000,
4.4550, -4.8510, 0.3960, 4.4550, -4.8510, 0.3960,
0.8056, 0.3572, -1.1628); 0.8056, 0.3572, -1.1628);
@ -672,28 +669,28 @@ mat3(
////// STANDARDS /////// ////// STANDARDS ///////
// SMPTE RP 145-1994 (SMPTE-C), 170M-1999 // SMPTE RP 145-1994 (SMPTE-C), 170M-1999
// SMPTE-C - Standard Phosphor (Rec.601 NTSC) // SMPTE-C - Standard Phosphor (Rec.601 NTSC)
// Standardized in 1982 (as CCIR Rec.601-1) after "Conrac Corp. & RCA" P22 phosphors (circa 1969) for consumer CRTs
// ILLUMINANT: D65->[0.31266142,0.3289589] // ILLUMINANT: D65->[0.31266142,0.3289589]
const mat3 SMPTE170M_ph = const mat3 SMPTE170M_ph = mat3(
mat3(
0.630, 0.310, 0.155, 0.630, 0.310, 0.155,
0.340, 0.595, 0.070, 0.340, 0.595, 0.070,
0.030, 0.095, 0.775); 0.030, 0.095, 0.775);
// ITU-R BT.470/601 (B/G) // ITU-R BT.470/601 (B/G)
// EBU Tech.3213 PAL - Standard Phosphor for Studio Monitors // EBU Tech.3213 PAL - Standard Phosphor for Studio Monitors (also used in Sony BVMs and Higher-end PVMs)
// ILLUMINANT: D65->[0.31266142,0.3289589] // ILLUMINANT: D65->[0.31266142,0.3289589]
const mat3 SMPTE470BG_ph = const mat3 SMPTE470BG_ph = mat3(
mat3(
0.640, 0.290, 0.150, 0.640, 0.290, 0.150,
0.330, 0.600, 0.060, 0.330, 0.600, 0.060,
0.030, 0.110, 0.790); 0.030, 0.110, 0.790);
// NTSC-J P22 // NTSC-J P22
// Mix between averaging KV-20M20, KDS VS19, Dell D93, 4-TR-B09v1_0.pdf and Phosphor Handbook 'P22' // Mix between averaging KV-20M20, KDS VS19, Dell D93, 4-TR-B09v1_0.pdf and Phosphor Handbook 'P22'
// Phosphors based on 1975's EBU Tech.3123-E (formerly known as JEDEC-P22)
// Typical P22 phosphors used in Japanese consumer CRTs with 9300K+27MPCD white point
// ILLUMINANT: D93->[0.281000,0.311000] (CCT of 8945.436K) // ILLUMINANT: D93->[0.281000,0.311000] (CCT of 8945.436K)
// ILLUMINANT: D97->[0.285000,0.285000] (CCT of 9696K) for Nanao MS-2930s series (around 10000.0K for wp_adjust() daylight fit) // ILLUMINANT: D97->[0.285000,0.285000] (CCT of 9696K) for Nanao MS-2930s series (around 10000.0K for wp_adjust() daylight fit)
const mat3 P22_J_ph = const mat3 P22_J_ph = mat3(
mat3(
0.625, 0.280, 0.152, 0.625, 0.280, 0.152,
0.350, 0.605, 0.062, 0.350, 0.605, 0.062,
0.025, 0.115, 0.786); 0.025, 0.115, 0.786);
@ -704,22 +701,19 @@ const mat3 P22_J_ph =
// You can run any of these P22 primaries either through D65 or D93 indistinctly but typically these were D65 based. // You can run any of these P22 primaries either through D65 or D93 indistinctly but typically these were D65 based.
// P22_80 is roughly the same as the old P22 gamut in Grade 2020. P22 1979-1994 meta measurement. // P22_80 is roughly the same as the old P22 gamut in Grade 2020. P22 1979-1994 meta measurement.
// ILLUMINANT: D65->[0.31266142,0.3289589] // ILLUMINANT: D65->[0.31266142,0.3289589]
const mat3 P22_80s_ph = const mat3 P22_80s_ph = mat3(
mat3(
0.6470, 0.2820, 0.1472, 0.6470, 0.2820, 0.1472,
0.3430, 0.6200, 0.0642, 0.3430, 0.6200, 0.0642,
0.0100, 0.0980, 0.7886); 0.0100, 0.0980, 0.7886);
// P22 improved with tinted phosphors (Use this for NTSC-U 16-bits, and above for 8-bits) // P22 improved with tinted phosphors (Use this for NTSC-U 16-bits, and above for 8-bits)
const mat3 P22_90s_ph = const mat3 P22_90s_ph = mat3(
mat3(
0.6661, 0.3134, 0.1472, 0.6661, 0.3134, 0.1472,
0.3329, 0.6310, 0.0642, 0.3329, 0.6310, 0.0642,
0.0010, 0.0556, 0.7886); 0.0010, 0.0556, 0.7886);
// RPTV (Rear Projection TV) for NTSC-U late 90s, early 00s // RPTV (Rear Projection TV) for NTSC-U late 90s, early 00s
const mat3 RPTV_95s_ph = const mat3 RPTV_95s_ph = mat3(
mat3(
0.640, 0.341, 0.150, 0.640, 0.341, 0.150,
0.335, 0.586, 0.070, 0.335, 0.586, 0.070,
0.025, 0.073, 0.780); 0.025, 0.073, 0.780);
@ -731,29 +725,25 @@ const mat3 RPTV_95s_ph =
//----------------------- Display Primaries ----------------------- //----------------------- Display Primaries -----------------------
// sRGB (IEC 61966-2-1) and ITU-R BT.709-6 (originally CCIR Rec.709) // sRGB (IEC 61966-2-1) and ITU-R BT.709-6 (originally CCIR Rec.709)
const mat3 sRGB_prims = const mat3 sRGB_prims = mat3(
mat3(
0.640, 0.300, 0.150, 0.640, 0.300, 0.150,
0.330, 0.600, 0.060, 0.330, 0.600, 0.060,
0.030, 0.100, 0.790); 0.030, 0.100, 0.790);
// Adobe RGB (1998) // Adobe RGB (1998)
const mat3 Adobe_prims = const mat3 Adobe_prims = mat3(
mat3(
0.640, 0.210, 0.150, 0.640, 0.210, 0.150,
0.330, 0.710, 0.060, 0.330, 0.710, 0.060,
0.030, 0.080, 0.790); 0.030, 0.080, 0.790);
// BT-2020/BT-2100 (from 630nm, 532nm and 467nm) // BT-2020/BT-2100 (from 630nm, 532nm and 467nm)
const mat3 rec2020_prims = const mat3 rec2020_prims = mat3(
mat3(
0.707917792, 0.170237195, 0.131370635, 0.707917792, 0.170237195, 0.131370635,
0.292027109, 0.796518542, 0.045875976, 0.292027109, 0.796518542, 0.045875976,
0.000055099, 0.033244263, 0.822753389); 0.000055099, 0.033244263, 0.822753389);
// SMPTE RP 432-2 (DCI-P3) // SMPTE RP 432-2 (DCI-P3)
const mat3 DCIP3_prims = const mat3 DCIP3_prims = mat3(
mat3(
0.680, 0.265, 0.150, 0.680, 0.265, 0.150,
0.320, 0.690, 0.060, 0.320, 0.690, 0.060,
0.000, 0.045, 0.790); 0.000, 0.045, 0.790);
@ -878,7 +868,7 @@ void main()
float hue_radians_b = 100.0 * M_PI; float hue_radians_b = 100.0 * M_PI;
float hue_b = cos(hue_at + hue_radians_b); float hue_b = cos(hue_at + hue_radians_b);
float msk = dot(clamp(vec3(hue_r, hue_g, hue_b) * chroma * 2, 0.0, 1.0), -vec3(satr, satg, satb)); float msk = dot(clamp(vec3(hue_r, hue_g, hue_b) * chroma * 2.0, 0.0, 1.0), -vec3(satr, satg, satb));
src_h = mix(col, vec3(dot(coeff, col)), msk); src_h = mix(col, vec3(dot(coeff, col)), msk);
float sat_msk = (vibr < 0.0) ? 1.0 - abs(SatMask(src_h.x, src_h.y, src_h.z) - 1.0) * abs(vibr) : \ float sat_msk = (vibr < 0.0) ? 1.0 - abs(SatMask(src_h.x, src_h.y, src_h.z) - 1.0) * abs(vibr) : \
@ -925,13 +915,13 @@ void main()
vpos *= 1.0 - vpos.xy; vpos *= 1.0 - vpos.xy;
float vig = vpos.x * vpos.y * vstr; float vig = vpos.x * vpos.y * vstr;
vig = min(pow(vig, vpower), 1.0); vig = min(pow(vig, vpower), 1.0);
vig = vig >= 0.5 ? smoothstep(0,1,vig) : vig; vig = vig >= 0.5 ? smoothstep(0.0,1.0,vig) : vig;
src_h *= (vignette == 1.0) ? vig : 1.0; src_h *= (vignette == 1.0) ? vig : 1.0;
// Dark to Dim adaptation OOTF; for 709, P3-D65 and 2020 // Dark to Dim adaptation OOTF; for 709, P3-D65 and 2020
float DtD = global.g_Dark_to_Dim > 0.0 ? 1/0.9811 : 1.0; float DtD = global.g_Dark_to_Dim > 0.0 ? 1.0/0.9811 : 1.0;
// EOTF^-1 - Inverted Electro-Optical Transfer Function // EOTF^-1 - Inverted Electro-Optical Transfer Function
vec3 TRC = (SPC == 3.0) ? clamp(pow(src_h, vec3(1./ (563./256.))), 0., 1.) : \ vec3 TRC = (SPC == 3.0) ? clamp(pow(src_h, vec3(1./ (563./256.))), 0., 1.) : \