diff --git a/hdr/crt-viewsonic-A90f+-4k-hdr.slangp b/hdr/crt-viewsonic-A90f+-4k-hdr.slangp new file mode 100644 index 0000000..709cd3a --- /dev/null +++ b/hdr/crt-viewsonic-A90f+-4k-hdr.slangp @@ -0,0 +1 @@ +#reference "crt-viewsonic-superclear-4k-hdr.slangp" \ No newline at end of file diff --git a/hdr/crt-viewsonic-superclear-4k-hdr.slangp b/hdr/crt-viewsonic-superclear-4k-hdr.slangp new file mode 100644 index 0000000..8c16218 --- /dev/null +++ b/hdr/crt-viewsonic-superclear-4k-hdr.slangp @@ -0,0 +1,55 @@ +/* +A shader that specifically tries to emulate Viewsonic SuperClear monitor's with an shadow mask screen but with full brightness. + +The novel thing about this shader is that it transforms the image output by the 'console/arcade/computer' into HDR space first i.e brightens it first and then applies +an shadow mask afterwards which is kind of what a CRT would actually do - its kind of a kin to the electron beam (but nothing like it lol). + +My DisplayHDR 600 monitor does seem to get reasonably close to the brightness of my PVM - its not quite there but its close. I think DisplayHDR 1000 and above will be able to match. + +Currently defaults towards a Viewsonic A90f+. + +To use: +Please Enable HDR in RetroArch 1.10+ + +NOTE: when this shader is envoked the Contrast, Peak Luminance and Paper White Luminance in the HDR menu do nothing instead set those values through the shader parameters + +For this shader set Paper White Luminance to above 700 and Peak Luminance to the peak luminance of your monitor. + +Also try to use a integer scaling - its just better - overscaling is fine/great. + +This shader doesn't do any geometry warping or bouncing of light around inside the screen - I think these effects just add unwanted noise, I know people disagree. Please feel free to make you own and add them + +Works only with the D3D11/D3D12/Vulkan drivers currently + +THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - QD-OLED or LCD (and variants thereof screens are fine) +*/ + +shaders = "1" +feedback_pass = "0" + +shader0 = "shaders/crt-shadow-mask-hdr.slang" +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +PaperWhiteNits = "400.000000" +RedConvergence = "0.000000" +GreenConvergence = "0.000000" +BlueConvergence = "0.000000" +RedScanlineMin = "0.5000000" +RedScanlineMax = "1.000000" +RedScanlineAttack = "0.350000" +GreenScanlineMin = "0.550000" +GreenScanlineMax = "1.000000" +GreenScanlineAttack = "0.350000" +BlueScanlineMin = "0.550000" +BlueScanlineMax = "1.000000" +BlueScanlineAttack = "0.350000" +RedBeamSharpness = "1.200000" +RedBeamAttack = "0.5000000" +GreenBeamSharpness = "1.200000" +GreenBeamAttack = "0.500000" +BlueBeamSharpness = "1.200000" +BlueBeamAttack = "0.500000" diff --git a/hdr/shaders/crt-aperture-grille-hdr.slang b/hdr/shaders/crt-aperture-grille-hdr.slang index 28e139f..ea113b6 100644 --- a/hdr/shaders/crt-aperture-grille-hdr.slang +++ b/hdr/shaders/crt-aperture-grille-hdr.slang @@ -36,10 +36,18 @@ THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - RG layout(push_constant) uniform Push { #include "include\user_properties.h" + + float CRTResolution; + #include "include\developer_properties.h" } params; #include "include\user_parameters.h" + +#pragma parameter Space3 " " 0.0 0.0 0.0 0.0 +#pragma parameter DeveloperSettings "DEVELOPER SETTINGS:" 0.0 0.0 0.0 0.0 +#pragma parameter CRTResolution " CRT Resolution: 600TVL/800TVL/1000TVL" 0.0 0.0 2.0 1.0 + #include "include\developer_parameters.h" layout(std140, set = 0, binding = 0) uniform UBO diff --git a/hdr/shaders/crt-shadow-mask-hdr.slang b/hdr/shaders/crt-shadow-mask-hdr.slang index ffefe1c..9efb4a4 100644 --- a/hdr/shaders/crt-shadow-mask-hdr.slang +++ b/hdr/shaders/crt-shadow-mask-hdr.slang @@ -36,10 +36,18 @@ THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - RG layout(push_constant) uniform Push { #include "include\user_properties.h" + + float ShadowMaskPattern; + #include "include\developer_properties.h" } params; #include "include\user_parameters.h" + +#pragma parameter Space3 " " 0.0 0.0 0.0 0.0 +#pragma parameter DeveloperSettings "DEVELOPER SETTINGS:" 0.0 0.0 0.0 0.0 +#pragma parameter ShadowMaskPattern " Shadow Mask: Fine/2x1/1x2/Diagonal/Coarse/8K Coarse" 0.0 0.0 5.0 1.0 + #include "include\developer_parameters.h" layout(std140, set = 0, binding = 0) uniform UBO @@ -88,65 +96,96 @@ layout(set = 0, binding = 2) uniform sampler2D Source; #define kWhite vec3(1.0, 1.0, 1.0) #define kBGRAxis 2 -#define kTVLAxis 3 +#define kPatternAxis 6 #define kResolutionAxis 2 -#define kMaxMaskSize 8 -#define kMaxShadowSize 2 +#define kMaxMaskSize 12 +#define kMaxShadowSize 8 +#define kMaxGridSize 2 -#define kXXXX { kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kXXXX { kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kMG { kMagenta, kGreen, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kGM { kGreen, kMagenta, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kMG { kMagenta, kGreen, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kGM { kGreen, kMagenta, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kBGR { kBlue, kGreen, kRed, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kRGB { kRed, kGreen, kBlue, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kMGCRYB { kMagenta, kGreen, kCyan, kRed, kYellow, kBlue, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kRYBMGC { kRed, kYellow, kBlue, kMagenta, kGreen, kCyan, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kRGBX { kRed, kGreen, kBlue, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kBGRX { kBlue, kGreen, kRed, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kRYCB { kRed, kYellow, kCyan, kBlue, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kCBRY { kCyan, kBlue, kRed, kYellow, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kXRGB { kBlack, kRed, kGreen, kBlue, kBlack, kBlack, kBlack, kBlack } -#define kXBGR { kBlack, kBlue, kGreen, kRed, kBlack, kBlack, kBlack, kBlack } +#define kBGR { kBlue, kGreen, kRed, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kRBG { kRed, kBlue, kGreen, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kGRB { kGreen, kRed, kBlue, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kRYCBX { kRed, kYellow, kCyan, kBlue, kBlack, kBlack, kBlack, kBlack } -#define kBCYRX { kBlue, kCyan, kYellow, kRed, kBlack, kBlack, kBlack, kBlack } +#define kYCM { kCyan, kYellow, kMagenta, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kMYC { kMagenta, kCyan, kYellow, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kCMY { kYellow, kMagenta, kCyan, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kXRYCB { kBlack, kRed, kYellow, kCyan, kBlue, kBlack, kBlack, kBlack } -#define kXBCYR { kBlack, kBlue, kCyan, kYellow, kRed, kBlack, kBlack, kBlack } +#define kGBRGBR { kGreen, kBlue, kRed, kGreen, kBlue, kRed, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +// TODO: #define kGBRGBR { kGreen, kBlue, kRed, kGreen, kBlue, kRed, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kRRGGBBX { kRed, kRed, kGreen, kGreen, kBlue, kBlue, kBlack, kBlack } -#define kBBGGRRX { kBlue, kBlue, kGreen, kGreen, kRed, kRed, kBlack, kBlack } +#define kGYRMBC { kGreen, kYellow, kRed, kMagenta, kBlue, kCyan, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +// TODO: #define kGYRMBC { kGreen, kYellow, kRed, kMagenta, kBlue, kCyan, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kXRRGGBB { kBlack, kRed, kRed, kGreen, kGreen, kBlue, kBlue, kBlack } -#define kXBBGGRR { kBlack, kBlue, kBlue, kGreen, kGreen, kRed, kRed, kBlack } +#define kMBCGYR { kMagenta, kBlue, kCyan, kGreen, kYellow, kRed, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +// TODO: #define kMBCGYR { kMagenta, kBlue, kCyan, kGreen, kYellow, kRed, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kMG_GM { kMG, kGM } -#define kGM_MG { kGM, kMG } +#define kGRRBBG { kGreen, kRed, kRed, kBlue, kBlue, kGreen, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kBBGGRR { kBlue, kBlue, kGreen, kGreen, kRed, kRed, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kBGR_BGR { kBGR, kRGB } -#define kRGB_RGB { kRGB, kBGR } +#define kGBBRRG { kGreen, kBlue, kBlue, kRed, kRed, kGreen, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } +#define kRRGGBB { kRed, kRed, kGreen, kGreen, kBlue, kBlue, kBlack, kBlack, kBlack, kBlack, kBlack, kBlack } -#define kRGBX_BGRX { kRGBX, kXRGB } -#define kBGRX_RGBX { kBGRX, kXBGR } +#define kGGRRRRBBBBGG { kGreen, kGreen, kRed, kRed, kRed, kRed, kBlue, kBlue, kBlue, kBlue, kGreen, kGreen } +#define kBBBBGGGGRRRR { kBlue, kBlue, kBlue, kBlue, kGreen, kGreen, kGreen, kGreen, kRed, kRed, kRed, kRed } -#define kRYCBX_BCYRX { kRYCBX, kXRYCB } -#define kBCYRX_RYCBX { kBCYRX, kXBCYR } +#define kGGBBBBRRRRGG { kGreen, kGreen, kBlue, kBlue, kBlue, kBlue, kRed, kRed, kRed, kRed, kGreen, kGreen } +#define kRRRRGGGGBBBB { kRed, kRed, kRed, kRed, kGreen, kGreen, kGreen, kGreen, kBlue, kBlue, kBlue, kBlue } -#define kRRGGBBX_BBGGRRX { kRRGGBBX, kXRRGGBB } -#define kBBGGRRX_RRGGBBX { kBBGGRRX, kXBBGGRR } +#define kMG_GM { kMG, kGM, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } +#define kGM_MG { kGM, kMG, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } -const uint kPhosphorMaskSize[kResolutionAxis][kTVLAxis] = { { 4, 3, 2 }, { 7, 5, 4 } }; //4K: 600 TVL, 800 TVL, 1000 TVL 8K: 600 TVL, 800 TVL, 1000 TVL +#define kBGR_RBG_GRB { kBGR, kRBG, kGRB, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } +// TODO: #define kBGR_RBG { kBGR, kRBG, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } -const vec3 kPhosphorMasks[kResolutionAxis][kTVLAxis][kBGRAxis][kMaxShadowSize][kMaxMaskSize] = { - { // 4K - { kRGBX_BGRX, kBGRX_RGBX }, // 600 TVL - { kBGR_BGR, kRGB_RGB }, // 800 TVL - { kMG_GM, kGM_MG } // 1000 TVL - }, - { // 8K - { kRRGGBBX_BBGGRRX, kBBGGRRX_RRGGBBX }, // 600 TVL - { kRYCBX_BCYRX, kBCYRX_RYCBX }, // 800 TVL - { kRGBX_BGRX, kBGRX_RGBX } // 1000 TVL - } +#define kYCM_MYC_CMY { kYCM, kMYC, kCMY, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } +// TODO: #define kBGR_RBG { kYCM, kMYC, kCMY, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } + +#define kMGMG_GMGM { kMG, kMG, kGM, kGM, kXXXX, kXXXX, kXXXX, kXXXX } +// TODO: #define kMG_GM { kMG, kGM, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } + +#define kGRRBBG_GRRBBG_BBGGRR_BBGGRR { kGRRBBG, kGRRBBG, kBBGGRR, kBBGGRR, kXXXX, kXXXX, kXXXX, kXXXX } +#define kGBBRRG_GBBRRG_RRGGBB_RRGGBB { kGBBRRG, kGBBRRG, kRRGGBB, kRRGGBB, kXXXX, kXXXX, kXXXX, kXXXX } + +#define kGGRRRRBBBBGG_GGRRRRBBBBGG_GGRRRRBBBBGG_GGRRRRBBBBGG_BBBBGGGGRRRR_BBBBGGGGRRRR_BBBBGGGGRRRR_BBBBGGGGRRRR { kGGRRRRBBBBGG, kGGRRRRBBBBGG, kGGRRRRBBBBGG, kGGRRRRBBBBGG, kBBBBGGGGRRRR, kBBBBGGGGRRRR, kBBBBGGGGRRRR, kBBBBGGGGRRRR } +#define kGGBBBBRRRRGG_GGBBBBRRRRGG_GGBBBBRRRRGG_GGBBBBRRRRGG_RRRRGGGGBBBB_RRRRGGGGBBBB_RRRRGGGGBBBB_RRRRGGGGBBBB { kGGBBBBRRRRGG, kGGBBBBRRRRGG, kGGBBBBRRRRGG, kGGBBBBRRRRGG, kRRRRGGGGBBBB, kRRRRGGGGBBBB, kRRRRGGGGBBBB, kRRRRGGGGBBBB } + +#define kRYCB_kCBRY { kRYCB, kCBRY, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } +// TODO: #define kRYCB_kCBRY { kRYCB, kCBRY, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } + +//#define kMGCRYB_RYBMGC { kMGCRYB, kRYBMGC, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } +// TODO: #define kMGCRYB_RYBMGC { kMGCRYB, kRYBMGC, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX, kXXXX } + +//#define kMGCRYB_MGCRYB_RYBMGC_RYBMGC { kMGCRYB, kMGCRYB, kRYBMGC, kRYBMGC, kXXXX, kXXXX, kXXXX, kXXXX } +// TODO: #define kMGCRYB_MGCRYB_RYBMGC_RYBMGC { kMGCRYB, kMGCRYB, kRYBMGC, kRYBMGC, kXXXX, kXXXX, kXXXX, kXXXX } + +#define kGBRGBR_GYRMBC_GBRGBR_MBCGYR { kGBRGBR, kGYRMBC, kGBRGBR, kMBCGYR, kXXXX, kXXXX, kXXXX, kXXXX } +// TODO: #define kGBRGBR_GYRMBC_GBRGBR_MBCGYR { kGBRGBR, kGYRMBC, kGBRGBR, kMBCGYR, kXXXX, kXXXX, kXXXX, kXXXX } + +const uint kPhosphorMaskSize[kPatternAxis] = { 2, 2, 4, 3, 6, 12 }; // , 6, 6, 6 +const uint kShadowMaskSize[kPatternAxis] = { 2, 4, 2, 3, 4, 8, }; // , 2, 4, 4 + +const vec3 kPhosphorMasks[kPatternAxis][kBGRAxis][kMaxShadowSize][kMaxMaskSize] = { + { kMG_GM, kGM_MG }, // Fine + { kMGMG_GMGM, kMGMG_GMGM }, + { kRYCB_kCBRY, kRYCB_kCBRY }, + { kBGR_RBG_GRB, kBGR_RBG_GRB }, // Coarse0 + //{ kYCM_MYC_CMY, kYCM_MYC_CMY }, + { kGRRBBG_GRRBBG_BBGGRR_BBGGRR, kGBBRRG_GBBRRG_RRGGBB_RRGGBB }, // Coarse1 + { kGGRRRRBBBBGG_GGRRRRBBBBGG_GGRRRRBBBBGG_GGRRRRBBBBGG_BBBBGGGGRRRR_BBBBGGGGRRRR_BBBBGGGGRRRR_BBBBGGGGRRRR, kGGBBBBRRRRGG_GGBBBBRRRRGG_GGBBBBRRRRGG_GGBBBBRRRRGG_RRRRGGGGBBBB_RRRRGGGGBBBB_RRRRGGGGBBBB_RRRRGGGGBBBB }, // 8K +// { kMGCRYB_RYBMGC, kMGCRYB_RYBMGC }, // Tile0 +// { kMGCRYB_MGCRYB_RYBMGC_RYBMGC, kMGCRYB_MGCRYB_RYBMGC_RYBMGC }, // Tile1 +// { kGBRGBR_GYRMBC_GBRGBR_MBCGYR, kGBRGBR_GYRMBC_GBRGBR_MBCGYR } // Tile2 }; float ModInteger(float a, float b) @@ -164,15 +203,14 @@ void main() vec3 scanline_colour = GenerateScanline(current_position); { - uint lcd_subpixel_layout = uint(params.LCDSubpixel); - uint crt_resolution = uint(params.CRTResolution); - uint lcd_resolution = uint(params.LCDResolution); + uint lcd_subpixel_layout = uint(params.LCDSubpixel); + uint shadow_mask = uint(params.ShadowMaskPattern); - uint shadow_y = uint(ModInteger(floor(current_position.y), kMaxShadowSize)); + uint shadow_y = uint(ModInteger(floor(current_position.y), kShadowMaskSize[shadow_mask])); - uint mask = uint(ModInteger(floor(current_position.x), kPhosphorMaskSize[lcd_resolution][crt_resolution])); + uint mask = uint(ModInteger(floor(current_position.x), kPhosphorMaskSize[shadow_mask])); - scanline_colour *= kPhosphorMasks[lcd_resolution][crt_resolution][lcd_subpixel_layout][shadow_y][mask]; + scanline_colour *= kPhosphorMasks[shadow_mask][lcd_subpixel_layout][shadow_y][mask]; } // HACK: To get maximum brightness we just set paper white luminance to max luminance diff --git a/hdr/shaders/crt-slot-mask-hdr.slang b/hdr/shaders/crt-slot-mask-hdr.slang index 76fd39c..3d56931 100644 --- a/hdr/shaders/crt-slot-mask-hdr.slang +++ b/hdr/shaders/crt-slot-mask-hdr.slang @@ -36,10 +36,18 @@ THIS SHADER DOES NOT SUPPORT WRGB OLED (Due to the sub pixel layout of WRGB - RG layout(push_constant) uniform Push { #include "include\user_properties.h" + + float CRTResolution; + #include "include\developer_properties.h" } params; #include "include\user_parameters.h" + +#pragma parameter Space3 " " 0.0 0.0 0.0 0.0 +#pragma parameter DeveloperSettings "DEVELOPER SETTINGS:" 0.0 0.0 0.0 0.0 +#pragma parameter CRTResolution " CRT Resolution: 600TVL/800TVL/1000TVL" 0.0 0.0 2.0 1.0 + #include "include\developer_parameters.h" layout(std140, set = 0, binding = 0) uniform UBO diff --git a/hdr/shaders/include/developer_parameters.h b/hdr/shaders/include/developer_parameters.h index 0afd130..0bbee4a 100644 --- a/hdr/shaders/include/developer_parameters.h +++ b/hdr/shaders/include/developer_parameters.h @@ -1,7 +1,4 @@ -#pragma parameter Space3 " " 0.0 0.0 0.0 0.0 -#pragma parameter DeveloperSettings "DEVELOPER SETTINGS:" 0.0 0.0 0.0 0.0 -#pragma parameter CRTResolution " CRT Resolution: 600TVL/800TVL/1000TVL" 0.0 0.0 2.0 1.0 #pragma parameter DeveloperSettings0 " VERTICAL SETTINGS:" 0.0 0.0 0.0 0.0 #pragma parameter RedScanlineMin " Red Scanline Min" 0.50 0.0 2.0 0.01 #pragma parameter RedScanlineMax " Red Scanline Max" 1.00 0.0 2.0 0.01 diff --git a/hdr/shaders/include/developer_properties.h b/hdr/shaders/include/developer_properties.h index c556afe..7afab48 100644 --- a/hdr/shaders/include/developer_properties.h +++ b/hdr/shaders/include/developer_properties.h @@ -1,7 +1,6 @@ // Developer Settings - float CRTResolution; // Vertical Settings float RedScanlineMin;