mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-29 19:01:31 +11:00
Grade - Update + Cosmetics (#451)
* Grade - Update + Cosmetics - P3-D65 now uses 1886 EOTF - Mask for GamutCompression is now CRT Gamma adjusted instead of 2.4 constant - Fix uninitialized 'm_in' variable - Cosmetics * Update grade-no-LUT.slang * Update grade.slang
This commit is contained in:
parent
91a5ff8445
commit
5f64d80b7f
|
@ -82,7 +82,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
} global;
|
} global;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Grade (03-06-2023)
|
Grade (16-06-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:
|
||||||
|
@ -94,7 +94,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
**Syh, Nesguy, hunterk, and the libretro forum members.
|
**Syh, Nesguy, hunterk, and the libretro forum members.
|
||||||
|
|
||||||
|
|
||||||
######################################...PRESETS...#######################################
|
#####################################...STANDARDS...######################################
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
### ###
|
### ###
|
||||||
### PAL ###
|
### PAL ###
|
||||||
|
@ -177,7 +177,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#define V_SHIFT params.g_V_SHIFT
|
#define V_SHIFT params.g_V_SHIFT
|
||||||
#define U_MUL params.g_U_MUL
|
#define U_MUL params.g_U_MUL
|
||||||
#define V_MUL params.g_V_MUL
|
#define V_MUL params.g_V_MUL
|
||||||
#define g_CRT_l -(100000.*log((72981.-500000./(3.*max(2.3,params.g_CRT_l)))/9058.))/945461.
|
#define CRT_l -(100000.*log((72981.-500000./(3.*max(2.3,params.g_CRT_l)))/9058.))/945461.
|
||||||
#define lum_fix params.g_lum_fix
|
#define lum_fix params.g_lum_fix
|
||||||
#define vignette global.g_vignette
|
#define vignette global.g_vignette
|
||||||
#define GCompress global.g_GCompress
|
#define GCompress global.g_GCompress
|
||||||
|
@ -242,19 +242,18 @@ mat3 RGB_to_XYZ_mat(mat3 primaries) {
|
||||||
0.0, 0.0, T.z);
|
0.0, 0.0, T.z);
|
||||||
|
|
||||||
return TB * primaries;
|
return TB * primaries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 RGB_to_XYZ(vec3 RGB, mat3 primaries) {
|
vec3 RGB_to_XYZ(vec3 RGB, mat3 primaries) {
|
||||||
|
|
||||||
return RGB * RGB_to_XYZ_mat(primaries);
|
return RGB * RGB_to_XYZ_mat(primaries);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 XYZ_to_RGB(vec3 XYZ, mat3 primaries) {
|
vec3 XYZ_to_RGB(vec3 XYZ, mat3 primaries) {
|
||||||
|
|
||||||
return XYZ * inverse(RGB_to_XYZ_mat(primaries));
|
return XYZ * inverse(RGB_to_XYZ_mat(primaries));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vec3 XYZtoYxy(vec3 XYZ) {
|
vec3 XYZtoYxy(vec3 XYZ) {
|
||||||
|
@ -263,7 +262,7 @@ vec3 XYZtoYxy(vec3 XYZ) {
|
||||||
float Yxyg = (XYZrgb <= 0.0) ? 0.3805 : XYZ.r / XYZrgb;
|
float Yxyg = (XYZrgb <= 0.0) ? 0.3805 : XYZ.r / XYZrgb;
|
||||||
float Yxyb = (XYZrgb <= 0.0) ? 0.3769 : XYZ.g / XYZrgb;
|
float Yxyb = (XYZrgb <= 0.0) ? 0.3769 : XYZ.g / XYZrgb;
|
||||||
return vec3(XYZ.g, Yxyg, Yxyb);
|
return vec3(XYZ.g, Yxyg, Yxyb);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 YxytoXYZ(vec3 Yxy) {
|
vec3 YxytoXYZ(vec3 Yxy) {
|
||||||
|
|
||||||
|
@ -271,13 +270,13 @@ vec3 YxytoXYZ(vec3 Yxy) {
|
||||||
float Xsz = (Yxy.r <= 0.0) ? 0.0 : 1.0;
|
float Xsz = (Yxy.r <= 0.0) ? 0.0 : 1.0;
|
||||||
vec3 XYZ = vec3(Xsz,Xsz,Xsz) * vec3(Xs, Yxy.r, (Xs/Yxy.g)-Xs-Yxy.r);
|
vec3 XYZ = vec3(Xsz,Xsz,Xsz) * vec3(Xs, Yxy.r, (Xs/Yxy.g)-Xs-Yxy.r);
|
||||||
return XYZ;
|
return XYZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////// White Point Mapping /////////////////////////
|
///////////////////////// White Point Mapping /////////////////////////
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// PAL: D65 NTSC-U: D65 NTSC-J: CCT NTSC-J
|
// PAL: D65 NTSC-U: D65 NTSC-J: CCT 9300K+27MPCD
|
||||||
// PAL: 6503.512K NTSC-U: 6503.512K NTSC-J: ~8945.436K
|
// PAL: 6503.512K NTSC-U: 6503.512K NTSC-J: ~8945.436K
|
||||||
// [x:0.31266142 y:0.3289589] [x:0.281 y:0.311]
|
// [x:0.31266142 y:0.3289589] [x:0.281 y:0.311]
|
||||||
|
|
||||||
|
@ -318,7 +317,7 @@ vec3 wp_adjust(vec3 RGB, float temperature, mat3 primaries, mat3 display) {
|
||||||
mat3 matb = RGB_to_XYZ_mat(display);
|
mat3 matb = RGB_to_XYZ_mat(display);
|
||||||
|
|
||||||
return RGB.rgb * ((mata * CAM) * inverse(matb));
|
return RGB.rgb * ((mata * CAM) * inverse(matb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -366,8 +365,8 @@ vec3 EOTF_1886a_f3( vec3 color, float BlackLevel, float brightness, float contra
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
float moncurve_f( float color, float gamma, float offs)
|
float moncurve_f( float color, float gamma, float offs) {
|
||||||
{
|
|
||||||
// Forward monitor curve
|
// Forward monitor curve
|
||||||
color = clamp(color, 0.0, 1.0);
|
color = clamp(color, 0.0, 1.0);
|
||||||
float fs = (( gamma - 1.0) / offs) * pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
float fs = (( gamma - 1.0) / offs) * pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
||||||
|
@ -375,20 +374,20 @@ float moncurve_f( float color, float gamma, float offs)
|
||||||
|
|
||||||
color = ( color > xb) ? pow( ( color + offs) / ( 1.0 + offs), gamma) : color * fs;
|
color = ( color > xb) ? pow( ( color + offs) / ( 1.0 + offs), gamma) : color * fs;
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 moncurve_f_f3( vec3 color, float gamma, float offs)
|
vec3 moncurve_f_f3( vec3 color, float gamma, float offs) {
|
||||||
{
|
|
||||||
color.r = moncurve_f( color.r, gamma, offs);
|
color.r = moncurve_f( color.r, gamma, offs);
|
||||||
color.g = moncurve_f( color.g, gamma, offs);
|
color.g = moncurve_f( color.g, gamma, offs);
|
||||||
color.b = moncurve_f( color.b, gamma, offs);
|
color.b = moncurve_f( color.b, gamma, offs);
|
||||||
return color.rgb;
|
return color.rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float moncurve_r( float color, float gamma, float offs)
|
float moncurve_r( float color, float gamma, float offs) {
|
||||||
{
|
|
||||||
// Reverse monitor curve
|
// Reverse monitor curve
|
||||||
color = clamp(color, 0.0, 1.0);
|
color = clamp(color, 0.0, 1.0);
|
||||||
float yb = pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
float yb = pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
||||||
|
@ -396,23 +395,23 @@ float moncurve_r( float color, float gamma, float offs)
|
||||||
|
|
||||||
color = ( color > yb) ? ( 1.0 + offs) * pow( color, 1.0 / gamma) - offs : color * rs;
|
color = ( color > yb) ? ( 1.0 + offs) * pow( color, 1.0 / gamma) - offs : color * rs;
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 moncurve_r_f3( vec3 color, float gamma, float offs)
|
vec3 moncurve_r_f3( vec3 color, float gamma, float offs) {
|
||||||
{
|
|
||||||
color.r = moncurve_r( color.r, gamma, offs);
|
color.r = moncurve_r( color.r, gamma, offs);
|
||||||
color.g = moncurve_r( color.g, gamma, offs);
|
color.g = moncurve_r( color.g, gamma, offs);
|
||||||
color.b = moncurve_r( color.b, gamma, offs);
|
color.b = moncurve_r( color.b, gamma, offs);
|
||||||
return color.rgb;
|
return color.rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------- Luma Functions ----------------------------
|
//-------------------------- Luma Functions ----------------------------
|
||||||
|
|
||||||
|
|
||||||
// Performs better in gamma encoded space
|
// Performs better in gamma encoded space
|
||||||
float contrast_sigmoid(float color, float cont, float pivot){
|
float contrast_sigmoid(float color, float cont, float pivot) {
|
||||||
|
|
||||||
cont = pow(cont + 1., 3.);
|
cont = pow(cont + 1., 3.);
|
||||||
|
|
||||||
|
@ -422,11 +421,11 @@ float contrast_sigmoid(float color, float cont, float pivot){
|
||||||
color =(1. / (1. + exp(cont * (pivot - color))) - knee) / (shldr - knee);
|
color =(1. / (1. + exp(cont * (pivot - color))) - knee) / (shldr - knee);
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Performs better in gamma encoded space
|
// Performs better in gamma encoded space
|
||||||
float contrast_sigmoid_inv(float color, float cont, float pivot){
|
float contrast_sigmoid_inv(float color, float cont, float pivot) {
|
||||||
|
|
||||||
cont = pow(cont - 1., 3.);
|
cont = pow(cont - 1., 3.);
|
||||||
|
|
||||||
|
@ -436,36 +435,36 @@ float contrast_sigmoid_inv(float color, float cont, float pivot){
|
||||||
color = pivot - log(1. / (color * (shldr - knee) + knee) - 1.) / cont;
|
color = pivot - log(1. / (color * (shldr - knee) + knee) - 1.) / cont;
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float rolled_gain(float color, float gain){
|
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 - anch)) : color * ((1 - anch) / (color - anch)) * (1 - gain);
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 rolled_gain_v3(vec3 color, float gain){
|
vec3 rolled_gain_v3(vec3 color, float gain) {
|
||||||
|
|
||||||
color.r = rolled_gain(color.r, gain);
|
color.r = rolled_gain(color.r, gain);
|
||||||
color.g = rolled_gain(color.g, gain);
|
color.g = rolled_gain(color.g, gain);
|
||||||
color.b = rolled_gain(color.b, gain);
|
color.b = rolled_gain(color.b, gain);
|
||||||
|
|
||||||
return color.rgb;
|
return color.rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float SatMask(float color_r, float color_g, float color_b)
|
float SatMask(float color_r, float color_g, float color_b) {
|
||||||
{
|
|
||||||
float max_rgb = max(color_r, max(color_g, color_b));
|
float max_rgb = max(color_r, max(color_g, color_b));
|
||||||
float min_rgb = min(color_r, min(color_g, color_b));
|
float min_rgb = min(color_r, min(color_g, color_b));
|
||||||
float msk = clamp((max_rgb - min_rgb) / (max_rgb + min_rgb), 0.0, 1.0);
|
float msk = clamp((max_rgb - min_rgb) / (max_rgb + min_rgb), 0.0, 1.0);
|
||||||
return msk;
|
return msk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -482,8 +481,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
|
||||||
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)*(sat*beam) * WPD;
|
||||||
|
|
||||||
mat2x3 LimThres = \
|
mat2x3 LimThres = mat2x3( 0.100000,0.100000,0.100000,
|
||||||
mat2x3( 0.100000,0.100000,0.100000,
|
|
||||||
0.125000,0.125000,0.125000);
|
0.125000,0.125000,0.125000);
|
||||||
if (SPC < 1.0) {
|
if (SPC < 1.0) {
|
||||||
|
|
||||||
|
@ -541,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/2.4));
|
return mix(rgb, ac-cd.xyz*abs(ac), pow(grey,1/params.g_CRT_l));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -550,7 +548,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Matrices in OpenGL column-major
|
// Matrices in column-major
|
||||||
|
|
||||||
|
|
||||||
//----------------------- Y'UV color model -----------------------
|
//----------------------- Y'UV color model -----------------------
|
||||||
|
@ -670,7 +668,7 @@ const mat3 SMPTE470BG_ph =
|
||||||
// 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'
|
||||||
// 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 (in practice prolly more like ~9177.98K)
|
// 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,
|
||||||
|
@ -696,8 +694,8 @@ const mat3 P22_90s_ph =
|
||||||
0.3329, 0.6310, 0.0642,
|
0.3329, 0.6310, 0.0642,
|
||||||
0.0010, 0.0556, 0.7886);
|
0.0010, 0.0556, 0.7886);
|
||||||
|
|
||||||
// CRT for Projection Tubes for NTSC-U late 90s, early 00s
|
// RPTV (Rear Projection TV) for NTSC-U late 90s, early 00s
|
||||||
const mat3 CRT_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,
|
||||||
|
@ -777,7 +775,7 @@ void main()
|
||||||
col = signal > 0.0 ? max(Quantize8_f3(YUV_r601(col.xyz, NTSC_U ? 1.0 : 0.0))/255.0, 0.0) : src;
|
col = signal > 0.0 ? max(Quantize8_f3(YUV_r601(col.xyz, NTSC_U ? 1.0 : 0.0))/255.0, 0.0) : src;
|
||||||
|
|
||||||
// CRT EOTF. To Display Referred Linear: Undo developer baked CRT gamma (from 2.40 at default 0.1 CRT black level, to 2.60 at 0.0 CRT black level)
|
// CRT EOTF. To Display Referred Linear: Undo developer baked CRT gamma (from 2.40 at default 0.1 CRT black level, to 2.60 at 0.0 CRT black level)
|
||||||
col = EOTF_1886a_f3(col, g_CRT_l, params.g_CRT_b, params.g_CRT_c);
|
col = EOTF_1886a_f3(col, CRT_l, params.g_CRT_b, params.g_CRT_c);
|
||||||
|
|
||||||
|
|
||||||
//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||||
|
@ -797,16 +795,16 @@ void main()
|
||||||
screen *= transpose(color);
|
screen *= transpose(color);
|
||||||
|
|
||||||
|
|
||||||
// CRT Phosphor Gamut (0.0 is noop)
|
// CRT Phosphor Gamut (0.0 is sRGB/noop)
|
||||||
mat3 m_in;
|
mat3 m_in;
|
||||||
|
|
||||||
if (crtgamut == -3.0) { m_in = SMPTE170M_ph; } else
|
if (crtgamut == -3.0) { m_in = SMPTE170M_ph; } else
|
||||||
if (crtgamut == -2.0) { m_in = CRT_95s_ph; } else
|
if (crtgamut == -2.0) { m_in = RPTV_95s_ph; } else
|
||||||
if (crtgamut == -1.0) { m_in = P22_80s_ph; } else
|
if (crtgamut == -1.0) { m_in = P22_80s_ph; } else
|
||||||
if (crtgamut == 0.0) { m_in = sRGB_prims; } else
|
|
||||||
if (crtgamut == 1.0) { m_in = P22_90s_ph; } else
|
if (crtgamut == 1.0) { m_in = P22_90s_ph; } else
|
||||||
if (crtgamut == 2.0) { m_in = P22_J_ph; } else
|
if (crtgamut == 2.0) { m_in = P22_J_ph; } else
|
||||||
if (crtgamut == 3.0) { m_in = SMPTE470BG_ph; }
|
if (crtgamut == 3.0) { m_in = SMPTE470BG_ph; } else
|
||||||
|
{ m_in = sRGB_prims; }
|
||||||
|
|
||||||
|
|
||||||
// Display color space
|
// Display color space
|
||||||
|
@ -897,15 +895,13 @@ void main()
|
||||||
src_h *= (vignette == 1.0) ? vig : 1.0;
|
src_h *= (vignette == 1.0) ? vig : 1.0;
|
||||||
|
|
||||||
|
|
||||||
// Dark to Dim adaptation OOTF; only for 709 and 2020
|
// Dark to Dim adaptation OOTF; for 709, P3-D65 and 2020
|
||||||
vec3 src_D = global.g_Dark_to_Dim > 0.0 ? pow(src_h,vec3(0.9811)) : src_h;
|
float DtD = global.g_Dark_to_Dim > 0.0 ? 1/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.) : \
|
||||||
(SPC == 2.0) ? moncurve_r_f3(src_D, 2.20 + 0.022222, 0.0993) : \
|
|
||||||
(SPC == 1.0) ? clamp(pow(src_h, vec3(1./(2.20 + 0.40))), 0., 1.) : \
|
|
||||||
(SPC == 0.0) ? moncurve_r_f3(src_h, 2.20 + 0.20, 0.0550) : \
|
(SPC == 0.0) ? moncurve_r_f3(src_h, 2.20 + 0.20, 0.0550) : \
|
||||||
clamp(pow( src_D, vec3(1./(2.20 + 0.20))), 0., 1.) ;
|
clamp(pow( src_h, vec3(1./((2.20 + 0.20)*DtD))), 0., 1.) ;
|
||||||
|
|
||||||
|
|
||||||
// External Flare for Surround Illuminant 2700K (Soft White) at F0 (Lambertian reflectance); defines offset thus also black lift
|
// External Flare for Surround Illuminant 2700K (Soft White) at F0 (Lambertian reflectance); defines offset thus also black lift
|
||||||
|
|
|
@ -86,7 +86,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
} global;
|
} global;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Grade (03-06-2023)
|
Grade (16-06-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:
|
||||||
|
@ -98,7 +98,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
**Syh, Nesguy, hunterk, and the libretro forum members.
|
**Syh, Nesguy, hunterk, and the libretro forum members.
|
||||||
|
|
||||||
|
|
||||||
######################################...PRESETS...#######################################
|
#####################################...STANDARDS...######################################
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
### ###
|
### ###
|
||||||
### PAL ###
|
### PAL ###
|
||||||
|
@ -185,7 +185,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#define V_SHIFT params.g_V_SHIFT
|
#define V_SHIFT params.g_V_SHIFT
|
||||||
#define U_MUL params.g_U_MUL
|
#define U_MUL params.g_U_MUL
|
||||||
#define V_MUL params.g_V_MUL
|
#define V_MUL params.g_V_MUL
|
||||||
#define g_CRT_l -(100000.*log((72981.-500000./(3.*max(2.3,params.g_CRT_l)))/9058.))/945461.
|
#define CRT_l -(100000.*log((72981.-500000./(3.*max(2.3,params.g_CRT_l)))/9058.))/945461.
|
||||||
#define lum_fix params.g_lum_fix
|
#define lum_fix params.g_lum_fix
|
||||||
#define vignette global.g_vignette
|
#define vignette global.g_vignette
|
||||||
#define GCompress global.g_GCompress
|
#define GCompress global.g_GCompress
|
||||||
|
@ -252,19 +252,18 @@ mat3 RGB_to_XYZ_mat(mat3 primaries) {
|
||||||
0.0, 0.0, T.z);
|
0.0, 0.0, T.z);
|
||||||
|
|
||||||
return TB * primaries;
|
return TB * primaries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 RGB_to_XYZ(vec3 RGB, mat3 primaries) {
|
vec3 RGB_to_XYZ(vec3 RGB, mat3 primaries) {
|
||||||
|
|
||||||
return RGB * RGB_to_XYZ_mat(primaries);
|
return RGB * RGB_to_XYZ_mat(primaries);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 XYZ_to_RGB(vec3 XYZ, mat3 primaries) {
|
vec3 XYZ_to_RGB(vec3 XYZ, mat3 primaries) {
|
||||||
|
|
||||||
return XYZ * inverse(RGB_to_XYZ_mat(primaries));
|
return XYZ * inverse(RGB_to_XYZ_mat(primaries));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vec3 XYZtoYxy(vec3 XYZ) {
|
vec3 XYZtoYxy(vec3 XYZ) {
|
||||||
|
@ -273,7 +272,7 @@ vec3 XYZtoYxy(vec3 XYZ) {
|
||||||
float Yxyg = (XYZrgb <= 0.0) ? 0.3805 : XYZ.r / XYZrgb;
|
float Yxyg = (XYZrgb <= 0.0) ? 0.3805 : XYZ.r / XYZrgb;
|
||||||
float Yxyb = (XYZrgb <= 0.0) ? 0.3769 : XYZ.g / XYZrgb;
|
float Yxyb = (XYZrgb <= 0.0) ? 0.3769 : XYZ.g / XYZrgb;
|
||||||
return vec3(XYZ.g, Yxyg, Yxyb);
|
return vec3(XYZ.g, Yxyg, Yxyb);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 YxytoXYZ(vec3 Yxy) {
|
vec3 YxytoXYZ(vec3 Yxy) {
|
||||||
|
|
||||||
|
@ -281,13 +280,13 @@ vec3 YxytoXYZ(vec3 Yxy) {
|
||||||
float Xsz = (Yxy.r <= 0.0) ? 0.0 : 1.0;
|
float Xsz = (Yxy.r <= 0.0) ? 0.0 : 1.0;
|
||||||
vec3 XYZ = vec3(Xsz,Xsz,Xsz) * vec3(Xs, Yxy.r, (Xs/Yxy.g)-Xs-Yxy.r);
|
vec3 XYZ = vec3(Xsz,Xsz,Xsz) * vec3(Xs, Yxy.r, (Xs/Yxy.g)-Xs-Yxy.r);
|
||||||
return XYZ;
|
return XYZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////// White Point Mapping /////////////////////////
|
///////////////////////// White Point Mapping /////////////////////////
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// PAL: D65 NTSC-U: D65 NTSC-J: CCT NTSC-J
|
// PAL: D65 NTSC-U: D65 NTSC-J: CCT 9300K+27MPCD
|
||||||
// PAL: 6503.512K NTSC-U: 6503.512K NTSC-J: ~8945.436K
|
// PAL: 6503.512K NTSC-U: 6503.512K NTSC-J: ~8945.436K
|
||||||
// [x:0.31266142 y:0.3289589] [x:0.281 y:0.311]
|
// [x:0.31266142 y:0.3289589] [x:0.281 y:0.311]
|
||||||
|
|
||||||
|
@ -328,7 +327,7 @@ vec3 wp_adjust(vec3 RGB, float temperature, mat3 primaries, mat3 display) {
|
||||||
mat3 matb = RGB_to_XYZ_mat(display);
|
mat3 matb = RGB_to_XYZ_mat(display);
|
||||||
|
|
||||||
return RGB.rgb * ((mata * CAM) * inverse(matb));
|
return RGB.rgb * ((mata * CAM) * inverse(matb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -376,8 +375,8 @@ vec3 EOTF_1886a_f3( vec3 color, float BlackLevel, float brightness, float contra
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
float moncurve_f( float color, float gamma, float offs)
|
float moncurve_f( float color, float gamma, float offs) {
|
||||||
{
|
|
||||||
// Forward monitor curve
|
// Forward monitor curve
|
||||||
color = clamp(color, 0.0, 1.0);
|
color = clamp(color, 0.0, 1.0);
|
||||||
float fs = (( gamma - 1.0) / offs) * pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
float fs = (( gamma - 1.0) / offs) * pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
||||||
|
@ -385,20 +384,20 @@ float moncurve_f( float color, float gamma, float offs)
|
||||||
|
|
||||||
color = ( color > xb) ? pow( ( color + offs) / ( 1.0 + offs), gamma) : color * fs;
|
color = ( color > xb) ? pow( ( color + offs) / ( 1.0 + offs), gamma) : color * fs;
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 moncurve_f_f3( vec3 color, float gamma, float offs)
|
vec3 moncurve_f_f3( vec3 color, float gamma, float offs) {
|
||||||
{
|
|
||||||
color.r = moncurve_f( color.r, gamma, offs);
|
color.r = moncurve_f( color.r, gamma, offs);
|
||||||
color.g = moncurve_f( color.g, gamma, offs);
|
color.g = moncurve_f( color.g, gamma, offs);
|
||||||
color.b = moncurve_f( color.b, gamma, offs);
|
color.b = moncurve_f( color.b, gamma, offs);
|
||||||
return color.rgb;
|
return color.rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float moncurve_r( float color, float gamma, float offs)
|
float moncurve_r( float color, float gamma, float offs) {
|
||||||
{
|
|
||||||
// Reverse monitor curve
|
// Reverse monitor curve
|
||||||
color = clamp(color, 0.0, 1.0);
|
color = clamp(color, 0.0, 1.0);
|
||||||
float yb = pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
float yb = pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
||||||
|
@ -406,23 +405,23 @@ float moncurve_r( float color, float gamma, float offs)
|
||||||
|
|
||||||
color = ( color > yb) ? ( 1.0 + offs) * pow( color, 1.0 / gamma) - offs : color * rs;
|
color = ( color > yb) ? ( 1.0 + offs) * pow( color, 1.0 / gamma) - offs : color * rs;
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 moncurve_r_f3( vec3 color, float gamma, float offs)
|
vec3 moncurve_r_f3( vec3 color, float gamma, float offs) {
|
||||||
{
|
|
||||||
color.r = moncurve_r( color.r, gamma, offs);
|
color.r = moncurve_r( color.r, gamma, offs);
|
||||||
color.g = moncurve_r( color.g, gamma, offs);
|
color.g = moncurve_r( color.g, gamma, offs);
|
||||||
color.b = moncurve_r( color.b, gamma, offs);
|
color.b = moncurve_r( color.b, gamma, offs);
|
||||||
return color.rgb;
|
return color.rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------- Luma Functions ----------------------------
|
//-------------------------- Luma Functions ----------------------------
|
||||||
|
|
||||||
|
|
||||||
// Performs better in gamma encoded space
|
// Performs better in gamma encoded space
|
||||||
float contrast_sigmoid(float color, float cont, float pivot){
|
float contrast_sigmoid(float color, float cont, float pivot) {
|
||||||
|
|
||||||
cont = pow(cont + 1., 3.);
|
cont = pow(cont + 1., 3.);
|
||||||
|
|
||||||
|
@ -432,11 +431,11 @@ float contrast_sigmoid(float color, float cont, float pivot){
|
||||||
color =(1. / (1. + exp(cont * (pivot - color))) - knee) / (shldr - knee);
|
color =(1. / (1. + exp(cont * (pivot - color))) - knee) / (shldr - knee);
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Performs better in gamma encoded space
|
// Performs better in gamma encoded space
|
||||||
float contrast_sigmoid_inv(float color, float cont, float pivot){
|
float contrast_sigmoid_inv(float color, float cont, float pivot) {
|
||||||
|
|
||||||
cont = pow(cont - 1., 3.);
|
cont = pow(cont - 1., 3.);
|
||||||
|
|
||||||
|
@ -446,51 +445,49 @@ float contrast_sigmoid_inv(float color, float cont, float pivot){
|
||||||
color = pivot - log(1. / (color * (shldr - knee) + knee) - 1.) / cont;
|
color = pivot - log(1. / (color * (shldr - knee) + knee) - 1.) / cont;
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float rolled_gain(float color, float gain){
|
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 - anch)) : color * ((1 - anch) / (color - anch)) * (1 - gain);
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 rolled_gain_v3(vec3 color, float gain){
|
vec3 rolled_gain_v3(vec3 color, float gain) {
|
||||||
|
|
||||||
color.r = rolled_gain(color.r, gain);
|
color.r = rolled_gain(color.r, gain);
|
||||||
color.g = rolled_gain(color.g, gain);
|
color.g = rolled_gain(color.g, gain);
|
||||||
color.b = rolled_gain(color.b, gain);
|
color.b = rolled_gain(color.b, gain);
|
||||||
|
|
||||||
return color.rgb;
|
return color.rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float SatMask(float color_r, float color_g, float color_b)
|
float SatMask(float color_r, float color_g, float color_b) {
|
||||||
{
|
|
||||||
float max_rgb = max(color_r, max(color_g, color_b));
|
float max_rgb = max(color_r, max(color_g, color_b));
|
||||||
float min_rgb = min(color_r, min(color_g, color_b));
|
float min_rgb = min(color_r, min(color_g, color_b));
|
||||||
float msk = clamp((max_rgb - min_rgb) / (max_rgb + min_rgb), 0.0, 1.0);
|
float msk = clamp((max_rgb - min_rgb) / (max_rgb + min_rgb), 0.0, 1.0);
|
||||||
return msk;
|
return msk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This shouldn't be necessary but it seems some undefined values can
|
// This shouldn't be necessary but it seems some undefined values can
|
||||||
// creep in and each GPU vendor handles that differently. This keeps
|
// creep in and each GPU vendor handles that differently. This keeps
|
||||||
// all values within a safe range
|
// all values within a safe range
|
||||||
vec3 mixfix(vec3 a, vec3 b, float c)
|
vec3 mixfix(vec3 a, vec3 b, float c) {
|
||||||
{
|
|
||||||
return (a.z < 1.0) ? mix(a, b, c) : a;
|
return (a.z < 1.0) ? mix(a, b, c) : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec4 mixfix_v4(vec4 a, vec4 b, float c)
|
vec4 mixfix_v4(vec4 a, vec4 b, float c) {
|
||||||
{
|
|
||||||
return (a.z < 1.0) ? mix(a, b, c) : a;
|
return (a.z < 1.0) ? mix(a, b, c) : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -507,8 +504,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
|
||||||
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)*(sat*beam) * WPD;
|
||||||
|
|
||||||
mat2x3 LimThres = \
|
mat2x3 LimThres = mat2x3( 0.100000,0.100000,0.100000,
|
||||||
mat2x3( 0.100000,0.100000,0.100000,
|
|
||||||
0.125000,0.125000,0.125000);
|
0.125000,0.125000,0.125000);
|
||||||
if (SPC < 1.0) {
|
if (SPC < 1.0) {
|
||||||
|
|
||||||
|
@ -566,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/2.4));
|
return mix(rgb, ac-cd.xyz*abs(ac), pow(grey,1/params.g_CRT_l));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -575,7 +571,7 @@ vec3 GamutCompression (vec3 rgb, float grey) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Matrices in OpenGL column-major
|
// Matrices in column-major
|
||||||
|
|
||||||
|
|
||||||
//----------------------- Y'UV color model -----------------------
|
//----------------------- Y'UV color model -----------------------
|
||||||
|
@ -695,7 +691,7 @@ const mat3 SMPTE470BG_ph =
|
||||||
// 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'
|
||||||
// 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 (in practice prolly more like ~9177.98K)
|
// 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,
|
||||||
|
@ -721,8 +717,8 @@ const mat3 P22_90s_ph =
|
||||||
0.3329, 0.6310, 0.0642,
|
0.3329, 0.6310, 0.0642,
|
||||||
0.0010, 0.0556, 0.7886);
|
0.0010, 0.0556, 0.7886);
|
||||||
|
|
||||||
// CRT for Projection Tubes for NTSC-U late 90s, early 00s
|
// RPTV (Rear Projection TV) for NTSC-U late 90s, early 00s
|
||||||
const mat3 CRT_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,
|
||||||
|
@ -813,7 +809,7 @@ void main()
|
||||||
|
|
||||||
|
|
||||||
// CRT EOTF. To Display Referred Linear: Undo developer baked CRT gamma (from 2.40 at default 0.1 CRT black level, to 2.60 at 0.0 CRT black level)
|
// CRT EOTF. To Display Referred Linear: Undo developer baked CRT gamma (from 2.40 at default 0.1 CRT black level, to 2.60 at 0.0 CRT black level)
|
||||||
col = EOTF_1886a_f3(vcolor, g_CRT_l, params.g_CRT_b, params.g_CRT_c);
|
col = EOTF_1886a_f3(vcolor, CRT_l, params.g_CRT_b, params.g_CRT_c);
|
||||||
|
|
||||||
|
|
||||||
//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||||
|
@ -833,16 +829,16 @@ void main()
|
||||||
screen *= transpose(color);
|
screen *= transpose(color);
|
||||||
|
|
||||||
|
|
||||||
// CRT Phosphor Gamut (0.0 is noop)
|
// CRT Phosphor Gamut (0.0 is sRGB/noop)
|
||||||
mat3 m_in;
|
mat3 m_in;
|
||||||
|
|
||||||
if (crtgamut == -3.0) { m_in = SMPTE170M_ph; } else
|
if (crtgamut == -3.0) { m_in = SMPTE170M_ph; } else
|
||||||
if (crtgamut == -2.0) { m_in = CRT_95s_ph; } else
|
if (crtgamut == -2.0) { m_in = RPTV_95s_ph; } else
|
||||||
if (crtgamut == -1.0) { m_in = P22_80s_ph; } else
|
if (crtgamut == -1.0) { m_in = P22_80s_ph; } else
|
||||||
if (crtgamut == 0.0) { m_in = sRGB_prims; } else
|
|
||||||
if (crtgamut == 1.0) { m_in = P22_90s_ph; } else
|
if (crtgamut == 1.0) { m_in = P22_90s_ph; } else
|
||||||
if (crtgamut == 2.0) { m_in = P22_J_ph; } else
|
if (crtgamut == 2.0) { m_in = P22_J_ph; } else
|
||||||
if (crtgamut == 3.0) { m_in = SMPTE470BG_ph; }
|
if (crtgamut == 3.0) { m_in = SMPTE470BG_ph; } else
|
||||||
|
{ m_in = sRGB_prims; }
|
||||||
|
|
||||||
m_in = (global.LUT1_toggle == 0.0) ? m_in : sRGB_prims;
|
m_in = (global.LUT1_toggle == 0.0) ? m_in : sRGB_prims;
|
||||||
|
|
||||||
|
@ -934,15 +930,13 @@ void main()
|
||||||
src_h *= (vignette == 1.0) ? vig : 1.0;
|
src_h *= (vignette == 1.0) ? vig : 1.0;
|
||||||
|
|
||||||
|
|
||||||
// Dark to Dim adaptation OOTF; only for 709 and 2020
|
// Dark to Dim adaptation OOTF; for 709, P3-D65 and 2020
|
||||||
vec3 src_D = global.g_Dark_to_Dim > 0.0 ? pow(src_h,vec3(0.9811)) : src_h;
|
float DtD = global.g_Dark_to_Dim > 0.0 ? 1/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.) : \
|
||||||
(SPC == 2.0) ? moncurve_r_f3(src_D, 2.20 + 0.022222, 0.0993) : \
|
|
||||||
(SPC == 1.0) ? clamp(pow(src_h, vec3(1./(2.20 + 0.40))), 0., 1.) : \
|
|
||||||
(SPC == 0.0) ? moncurve_r_f3(src_h, 2.20 + 0.20, 0.0550) : \
|
(SPC == 0.0) ? moncurve_r_f3(src_h, 2.20 + 0.20, 0.0550) : \
|
||||||
clamp(pow( src_D, vec3(1./(2.20 + 0.20))), 0., 1.) ;
|
clamp(pow( src_h, vec3(1./((2.20 + 0.20)*DtD))), 0., 1.) ;
|
||||||
|
|
||||||
|
|
||||||
// External Flare for Surround Illuminant 2700K (Soft White) at F0 (Lambertian reflectance); defines offset thus also black lift
|
// External Flare for Surround Illuminant 2700K (Soft White) at F0 (Lambertian reflectance); defines offset thus also black lift
|
||||||
|
|
Loading…
Reference in a new issue