diff --git a/crt/crt-hyllian-curvature-ntsc.slangp b/crt/crt-hyllian-curvature-ntsc.slangp deleted file mode 100644 index 7b8886a8..00000000 --- a/crt/crt-hyllian-curvature-ntsc.slangp +++ /dev/null @@ -1,105 +0,0 @@ -shaders = "9" - -shader0 = ../stock.slang -alias0 = PrePass0 - -shader1 = shaders/guest/advanced/ntsc/ntsc-pass1.slang -alias1 = NPass1 -scale_type_x1 = source -scale_type_y1 = source -scale_x1 = 4.0 -scale_y1 = 1.0 -float_framebuffer1 = true -filter_linear1 = false - -shader2 = shaders/guest/advanced/ntsc/ntsc-pass2.slang -filter_linear2 = true -float_framebuffer2 = true -scale_type2 = source -scale_x2 = 0.5 -scale_y2 = 1.0 - -shader3 = shaders/guest/advanced/ntsc/ntsc-pass3.slang -filter_linear3 = true -scale_type3 = source -scale_x3 = 1.0 -scale_y3 = 1.0 - -shader4 = "../crt/shaders/hyllian/crt-hyllian-curvature.slang" -filter_linear4 = "false" -wrap_mode4 = "clamp_to_border" -mipmap_input4 = "false" -alias4 = "CRTPass" -float_framebuffer4 = "false" -srgb_framebuffer4 = "true" -scale_type_x4 = "viewport" -scale_x4 = "1.000000" -scale_type_y4 = "viewport" -scale_y4 = "1.000000" -shader5 = "../crt/shaders/glow/threshold.slang" -filter_linear5 = "true" -wrap_mode5 = "clamp_to_border" -mipmap_input5 = "false" -alias5 = "" -float_framebuffer5 = "false" -srgb_framebuffer5 = "true" -shader6 = "../crt/shaders/glow/blur_horiz.slang" -filter_linear6 = "true" -wrap_mode6 = "clamp_to_border" -mipmap_input6 = "true" -alias6 = "" -float_framebuffer6 = "false" -srgb_framebuffer6 = "true" -scale_type_x6 = "viewport" -scale_x6 = "0.200000" -scale_type_y6 = "viewport" -scale_y6 = "0.200000" -shader7 = "../crt/shaders/glow/blur_vert.slang" -filter_linear7 = "true" -wrap_mode7 = "clamp_to_border" -mipmap_input7 = "false" -alias7 = "" -float_framebuffer7 = "false" -srgb_framebuffer7 = "true" -shader8 = "../crt/shaders/glow/resolve.slang" -filter_linear8 = "true" -wrap_mode8 = "clamp_to_border" -mipmap_input8 = "false" -alias8 = "" -float_framebuffer8 = "false" -srgb_framebuffer8 = "false" -scale_type8 = viewport -parameters = "linearize;quality;ntsc_sat;BEAM_PROFILE;HFILTER_PROFILE;BEAM_MIN_WIDTH;BEAM_MAX_WIDTH;SCANLINES_STRENGTH;COLOR_BOOST;PHOSPHOR_LAYOUT;MASK_INTENSITY;CRT_ANTI_RINGING;InputGamma;OutputGamma;VSCANLINES;CRT_CURVATURE;CRT_warpX;CRT_warpY;CRT_cornersize;CRT_cornersmooth;GLOW_WHITEPOINT;GLOW_ROLLOFF;BLOOM_STRENGTH;OUTPUT_GAMMA;CURVATURE;warpX;warpY;cornersize;cornersmooth;noise_amt;shadowMask;maskDark;maskLight" -BEAM_PROFILE = "0.000000" -HFILTER_PROFILE = "1.000000" -BEAM_MIN_WIDTH = "0.920000" -BEAM_MAX_WIDTH = "1.000000" -SCANLINES_STRENGTH = "0.720000" -COLOR_BOOST = "1.600000" -PHOSPHOR_LAYOUT = "4.000000" -MASK_INTENSITY = "0.700000" -CRT_ANTI_RINGING = "1.000000" -InputGamma = "2.000000" -OutputGamma = "2.000000" -VSCANLINES = "0.000000" -CRT_CURVATURE = "1.000000" -CRT_warpX = "0.015000" -CRT_warpY = "0.015000" -CRT_cornersize = "0.010000" -CRT_cornersmooth = "380.000000" -GLOW_WHITEPOINT = "0.900000" -GLOW_ROLLOFF = "3.000000" -BLOOM_STRENGTH = "0.100000" -OUTPUT_GAMMA = "2.200000" -CURVATURE = "0.000000" -warpX = "0.015000" -warpY = "0.015000" -cornersize = "0.010000" -cornersmooth = "380.000000" -noise_amt = "0.000000" -shadowMask = "0.000000" -maskDark = "0.500000" -maskLight = "1.500000" -linearize = "1.0" -quality = "0.0" -ntsc_sat = "1.2" diff --git a/crt/crt-hyllian-curvature.slangp b/crt/crt-hyllian-curvature.slangp deleted file mode 100644 index 6d87923c..00000000 --- a/crt/crt-hyllian-curvature.slangp +++ /dev/null @@ -1,5 +0,0 @@ -shaders = 1 - -shader0 = shaders/hyllian/crt-hyllian-curvature.slang -filter_linear0 = false -scale_type0 = viewport diff --git a/crt/crt-hyllian-dedither.slangp b/crt/crt-hyllian-dedither.slangp deleted file mode 100644 index a7767424..00000000 --- a/crt/crt-hyllian-dedither.slangp +++ /dev/null @@ -1,97 +0,0 @@ -shaders = "9" - -shader0 = "../crt/shaders/glow/linearize.slang" -filter_linear0 = "false" -wrap_mode0 = "clamp_to_border" -mipmap_input0 = "false" -alias0 = "LinearGamma" -float_framebuffer0 = "false" -srgb_framebuffer0 = "true" - - -shader1 = ../dithering/shaders/checkerboard-dedither/checkerboard-dedither-pass1.slang -filter_linear1 = false -scale_type1 = source -scale1 = 1.0 - -shader2 = ../dithering/shaders/checkerboard-dedither/checkerboard-dedither-pass2.slang -filter_linear2 = false -scale_type2 = source -scale2 = 1.0 - -shader3 = ../dithering/shaders/checkerboard-dedither/checkerboard-dedither-pass3.slang -filter_linear3 = false -scale_type3 = source -scale3 = 1.0 - -shader4 = "shaders/hyllian/crt-hyllian.slang" -filter_linear4 = "false" -wrap_mode4 = "clamp_to_border" -mipmap_input4 = "false" -alias4 = "CRTPass" -float_framebuffer4 = "false" -srgb_framebuffer4 = "true" -scale_type_x4 = "viewport" -scale_x4 = "1.000000" -scale_type_y4 = "viewport" -scale_y4 = "1.000000" -shader5 = "../crt/shaders/glow/threshold.slang" -filter_linear5 = "false" -wrap_mode5 = "clamp_to_border" -mipmap_input5 = "false" -alias5 = "" -float_framebuffer5 = "false" -srgb_framebuffer5 = "true" -shader6 = "../crt/shaders/glow/blur_horiz.slang" -filter_linear6 = "true" -wrap_mode6 = "clamp_to_border" -mipmap_input6 = "true" -alias6 = "" -float_framebuffer6 = "false" -srgb_framebuffer6 = "true" -scale_type_x6 = "viewport" -scale_x6 = "0.200000" -scale_type_y6 = "viewport" -scale_y6 = "0.200000" -shader7 = "../crt/shaders/glow/blur_vert.slang" -filter_linear7 = "true" -wrap_mode7 = "clamp_to_border" -mipmap_input7 = "false" -alias7 = "" -float_framebuffer7 = "false" -srgb_framebuffer7 = "true" -shader8 = "../crt/shaders/glow/resolve.slang" -filter_linear8 = "true" -wrap_mode8 = "clamp_to_border" -mipmap_input8 = "false" -alias8 = "" -float_framebuffer8 = "false" -srgb_framebuffer8 = "false" -scale_type8 = viewport -parameters = "CD_HUD_DETAILS;INPUT_GAMMA;HFILTER_PROFILE;BEAM_MIN_WIDTH;BEAM_MAX_WIDTH;SCANLINES_STRENGTH;COLOR_BOOST;SHARPNESS_HACK;PHOSPHOR_LAYOUT;MASK_INTENSITY;InputGamma;OutputGamma;VSCANLINES;GLOW_WHITEPOINT;GLOW_ROLLOFF;BLOOM_STRENGTH;OUTPUT_GAMMA;CURVATURE;warpX;warpY;cornersize;cornersmooth;noise_amt;shadowMask;maskDark;maskLight" -CD_HUD_DETAILS = "5.0" -INPUT_GAMMA = "2.000000" -HFILTER_PROFILE = "0.000000" -BEAM_MIN_WIDTH = "1.000000" -BEAM_MAX_WIDTH = "1.000000" -SCANLINES_STRENGTH = "0.580000" -COLOR_BOOST = "1.300000" -SHARPNESS_HACK = "1.000000" -PHOSPHOR_LAYOUT = "4.000000" -MASK_INTENSITY = "0.700000" -InputGamma = "2.400000" -OutputGamma = "1.000000" -VSCANLINES = "0.000000" -GLOW_WHITEPOINT = "0.900000" -GLOW_ROLLOFF = "3.000000" -BLOOM_STRENGTH = "0.100000" -OUTPUT_GAMMA = "2.200000" -CURVATURE = "0.000000" -warpX = "0.010000" -warpY = "0.020000" -cornersize = "0.010000" -cornersmooth = "280.000000" -noise_amt = "1.000000" -shadowMask = "0.000000" -maskDark = "0.500000" -maskLight = "1.500000" diff --git a/crt/crt-hyllian-glow.slangp b/crt/crt-hyllian-glow.slangp deleted file mode 100644 index 556ca535..00000000 --- a/crt/crt-hyllian-glow.slangp +++ /dev/null @@ -1,80 +0,0 @@ -shaders = "6" -shader0 = "shaders/glow/linearize.slang" -filter_linear0 = "false" -wrap_mode0 = "clamp_to_border" -mipmap_input0 = "false" -alias0 = "" -float_framebuffer0 = "false" -srgb_framebuffer0 = "true" -shader1 = "shaders/hyllian/crt-hyllian.slang" -filter_linear1 = "false" -wrap_mode1 = "clamp_to_border" -mipmap_input1 = "false" -alias1 = "CRTPass" -float_framebuffer1 = "false" -srgb_framebuffer1 = "true" -scale_type_x1 = "viewport" -scale_x1 = "1.000000" -scale_type_y1 = "viewport" -scale_y1 = "1.000000" -shader2 = "shaders/glow/threshold.slang" -filter_linear2 = "true" -wrap_mode2 = "clamp_to_border" -mipmap_input2 = "false" -alias2 = "" -float_framebuffer2 = "false" -srgb_framebuffer2 = "true" -shader3 = "shaders/glow/blur_horiz.slang" -filter_linear3 = "true" -wrap_mode3 = "clamp_to_border" -mipmap_input3 = "true" -alias3 = "" -float_framebuffer3 = "false" -srgb_framebuffer3 = "true" -scale_type_x3 = "viewport" -scale_x3 = "0.200000" -scale_type_y3 = "viewport" -scale_y3 = "0.200000" -shader4 = "shaders/glow/blur_vert.slang" -filter_linear4 = "true" -wrap_mode4 = "clamp_to_border" -mipmap_input4 = "false" -alias4 = "" -float_framebuffer4 = "false" -srgb_framebuffer4 = "true" -shader5 = "shaders/glow/resolve.slang" -filter_linear5 = "true" -wrap_mode5 = "clamp_to_border" -mipmap_input5 = "false" -alias5 = "" -float_framebuffer5 = "false" -srgb_framebuffer5 = "false" -scale_type5 = viewport -parameters = "INPUT_GAMMA;BEAM_PROFILE;HFILTER_PROFILE;BEAM_MIN_WIDTH;BEAM_MAX_WIDTH;SCANLINES_STRENGTH;COLOR_BOOST;SHARPNESS_HACK;PHOSPHOR_LAYOUT;MASK_INTENSITY;CRT_ANTI_RINGING;InputGamma;OutputGamma;VSCANLINES;GLOW_WHITEPOINT;GLOW_ROLLOFF;BLOOM_STRENGTH;OUTPUT_GAMMA;CURVATURE;warpX;warpY;cornersize;cornersmooth;noise_amt;shadowMask;maskDark;maskLight" -INPUT_GAMMA = "2.400000" -BEAM_PROFILE = "0.000000" -HFILTER_PROFILE = "0.000000" -BEAM_MIN_WIDTH = "1.000000" -BEAM_MAX_WIDTH = "1.000000" -SCANLINES_STRENGTH = "0.580000" -COLOR_BOOST = "1.350000" -SHARPNESS_HACK = "1.000000" -PHOSPHOR_LAYOUT = "4.000000" -MASK_INTENSITY = "0.700000" -CRT_ANTI_RINGING = "1.000000" -InputGamma = "1.000000" -OutputGamma = "1.000000" -VSCANLINES = "0.000000" -GLOW_WHITEPOINT = "0.900000" -GLOW_ROLLOFF = "3.000000" -BLOOM_STRENGTH = "0.100000" -OUTPUT_GAMMA = "2.200000" -CURVATURE = "0.000000" -warpX = "0.015000" -warpY = "0.015000" -cornersize = "0.010000" -cornersmooth = "380.000000" -noise_amt = "0.000000" -shadowMask = "0.000000" -maskDark = "0.500000" -maskLight = "1.500000" diff --git a/crt/crt-hyllian-multipass.slangp b/crt/crt-hyllian-multipass.slangp deleted file mode 100644 index 2cca3359..00000000 --- a/crt/crt-hyllian-multipass.slangp +++ /dev/null @@ -1,19 +0,0 @@ -shaders = 2 - -shader0 = shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass0.slang -filter_linear0 = false -srgb_framebuffer0 = true -scale_type_x0 = viewport -scale_type_y0 = source -scale_x0 = 1.0 -scale_y0 = 1.0 - -shader1 = shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass1.slang -filter_linear1 = false -scale_type1 = viewport - -# Uncomment these lines for a sharper variation -#parameters = "SHARPNESS;SCANLINES_STRENGTH;BEAM_MIN_WIDTH" -#SHARPNESS = "2.0" -#SCANLINES_STRENGTH = "0.50" -#BEAM_MIN_WIDTH = "0.44" diff --git a/crt/crt-hyllian-ntsc-rainbow.slangp b/crt/crt-hyllian-ntsc-rainbow.slangp new file mode 100644 index 00000000..bde3e886 --- /dev/null +++ b/crt/crt-hyllian-ntsc-rainbow.slangp @@ -0,0 +1,72 @@ +shaders = "5" +feedback_pass = "0" +shader0 = "shaders/hyllian/support/multiLUT-modified.slang" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "1.000000" +scale_type_y0 = "source" +scale_y0 = "1.000000" +shader1 = "shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass1.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_edge" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "true" +srgb_framebuffer1 = "false" +scale_type_x1 = "source" +scale_x1 = "4.000000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +shader2 = "shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass2.slang" +filter_linear2 = "true" +wrap_mode2 = "clamp_to_edge" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "false" +scale_type_x2 = "source" +scale_x2 = "1.000000" +scale_type_y2 = "source" +scale_y2 = "1.000000" +shader3 = "shaders/hyllian/support/linearize.slang" +filter_linear3 = "true" +wrap_mode3 = "clamp_to_edge" +mipmap_input3 = "false" +alias3 = "" +float_framebuffer3 = "false" +srgb_framebuffer3 = "true" +scale_type_x3 = "viewport" +scale_x3 = "1.000000" +scale_type_y3 = "source" +scale_y3 = "1.000000" +shader4 = "shaders/hyllian/crt-hyllian-pass1.slang" +filter_linear4 = "false" +wrap_mode4 = "clamp_to_edge" +mipmap_input4 = "false" +alias4 = "" +float_framebuffer4 = "false" +srgb_framebuffer4 = "false" +scale_type_x4 = "viewport" +scale_x4 = "1.000000" +scale_type_y4 = "viewport" +scale_y4 = "1.000000" +LUT_selector_param = "2.000000" +quality = "-1.000000" +chroma_scale = "3.000000" +cust_artifacting = "0.500000" +ntsc_artifacting_rainbow = "1.000000" +HFILTER_PROFILE = "0.000000" +BEAM_MIN_WIDTH = "0.860000" +BRIGHTBOOST = "1.600000" +PHOSPHOR_LAYOUT = "2.000000" +InputGamma = "2.400000" +textures = "SamplerLUT1;SamplerLUT2" +SamplerLUT1 = "shaders/guest/advanced/lut/ntsc-lut.png" +SamplerLUT1_linear = true +SamplerLUT2 = "shaders/hyllian/support/LUT/some-grade.png" +SamplerLUT2_linear = true + diff --git a/crt/crt-hyllian-ntsc.slangp b/crt/crt-hyllian-ntsc.slangp new file mode 100644 index 00000000..783bb201 --- /dev/null +++ b/crt/crt-hyllian-ntsc.slangp @@ -0,0 +1,70 @@ +shaders = "5" +feedback_pass = "0" +shader0 = "shaders/hyllian/support/multiLUT-modified.slang" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "1.000000" +scale_type_y0 = "source" +scale_y0 = "1.000000" +shader1 = "shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass1.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_edge" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "true" +srgb_framebuffer1 = "false" +scale_type_x1 = "source" +scale_x1 = "4.000000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +shader2 = "shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass2.slang" +filter_linear2 = "true" +wrap_mode2 = "clamp_to_edge" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "false" +scale_type_x2 = "source" +scale_x2 = "1.000000" +scale_type_y2 = "source" +scale_y2 = "1.000000" +shader3 = "shaders/hyllian/support/linearize.slang" +filter_linear3 = "true" +wrap_mode3 = "clamp_to_edge" +mipmap_input3 = "false" +alias3 = "" +float_framebuffer3 = "false" +srgb_framebuffer3 = "true" +scale_type_x3 = "viewport" +scale_x3 = "1.000000" +scale_type_y3 = "source" +scale_y3 = "1.000000" +shader4 = "shaders/hyllian/crt-hyllian-pass1.slang" +filter_linear4 = "false" +wrap_mode4 = "clamp_to_edge" +mipmap_input4 = "false" +alias4 = "" +float_framebuffer4 = "false" +srgb_framebuffer4 = "false" +scale_type_x4 = "viewport" +scale_x4 = "1.000000" +scale_type_y4 = "viewport" +scale_y4 = "1.000000" +LUT_selector_param = "2.000000" +quality = "-1.000000" +chroma_scale = "4.000000" +HFILTER_PROFILE = "0.000000" +BEAM_MIN_WIDTH = "0.860000" +BRIGHTBOOST = "1.600000" +PHOSPHOR_LAYOUT = "2.000000" +InputGamma = "2.400000" +textures = "SamplerLUT1;SamplerLUT2" +SamplerLUT1 = "shaders/guest/advanced/lut/ntsc-lut.png" +SamplerLUT1_linear = true +SamplerLUT2 = "shaders/hyllian/support/LUT/some-grade.png" +SamplerLUT2_linear = true + diff --git a/crt/crt-hyllian-rgb-slotmask.slangp b/crt/crt-hyllian-rgb-slotmask.slangp new file mode 100644 index 00000000..a7887d97 --- /dev/null +++ b/crt/crt-hyllian-rgb-slotmask.slangp @@ -0,0 +1,52 @@ +shaders = "3" +feedback_pass = "0" +shader0 = "shaders/hyllian/support/multiLUT-modified.slang" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "1.000000" +scale_type_y0 = "source" +scale_y0 = "1.000000" +shader1 = "shaders/hyllian/crt-hyllian-pass0.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "false" +srgb_framebuffer1 = "true" +scale_type_x1 = "viewport" +scale_x1 = "1.000000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +shader2 = "shaders/hyllian/crt-hyllian-pass1.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_edge" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "true" +scale_type_x2 = "source" +scale_x2 = "1.000000" +scale_type_y2 = "viewport" +scale_y2 = "1.000000" +LUT_selector_param = "2.000000" +HFILTER_PROFILE = "0.000000" +BEAM_MIN_WIDTH = "0.860000" +BEAM_MAX_WIDTH = "1.000000" +PHOSPHOR_LAYOUT = "11.000000" +MASK_INTENSITY = "0.650000" +BRIGHTBOOST = "1.300000" +SCANLINES_STRENGTH = "0.550000" +CURVATURE = "1.000000" +WARP_X = "0.020000" +WARP_Y = "0.025000" +CORNER_SIZE = "0.025000" +CORNER_SMOOTHNESS = "1.080000" +textures = "SamplerLUT1;SamplerLUT2" +SamplerLUT1 = "shaders/guest/advanced/lut/ntsc-lut.png" +SamplerLUT1_linear = true +SamplerLUT2 = "shaders/hyllian/support/LUT/some-grade.png" +SamplerLUT2_linear = true diff --git a/crt/crt-hyllian-rgb-trinitron.slangp b/crt/crt-hyllian-rgb-trinitron.slangp new file mode 100644 index 00000000..23c67e7a --- /dev/null +++ b/crt/crt-hyllian-rgb-trinitron.slangp @@ -0,0 +1,51 @@ +shaders = "3" +feedback_pass = "0" +shader0 = "shaders/hyllian/support/multiLUT-modified.slang" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "1.000000" +scale_type_y0 = "source" +scale_y0 = "1.000000" +shader1 = "shaders/hyllian/crt-hyllian-pass0.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "false" +srgb_framebuffer1 = "true" +scale_type_x1 = "viewport" +scale_x1 = "1.000000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +shader2 = "shaders/hyllian/crt-hyllian-pass1.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_edge" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "true" +scale_type_x2 = "source" +scale_x2 = "1.000000" +scale_type_y2 = "viewport" +scale_y2 = "1.000000" +LUT_selector_param = "2.000000" +HFILTER_PROFILE = "0.000000" +BEAM_MIN_WIDTH = "0.860000" +BEAM_MAX_WIDTH = "1.000000" +SCANLINES_STRENGTH = "0.720000" +BRIGHTBOOST = "1.500000" +PHOSPHOR_LAYOUT = "2.000000" +MASK_INTENSITY = "0.650000" +CURVATURE = "1.000000" +WARP_X = "0.000000" +WARP_Y = "0.025000" +CORNER_SIZE = "0.011000" +textures = "SamplerLUT1;SamplerLUT2" +SamplerLUT1 = "shaders/guest/advanced/lut/ntsc-lut.png" +SamplerLUT1_linear = true +SamplerLUT2 = "shaders/hyllian/support/LUT/some-grade.png" +SamplerLUT2_linear = true diff --git a/crt/crt-hyllian-sinc-composite.slangp b/crt/crt-hyllian-sinc-composite.slangp new file mode 100644 index 00000000..637488e3 --- /dev/null +++ b/crt/crt-hyllian-sinc-composite.slangp @@ -0,0 +1,43 @@ +shaders = "3" +feedback_pass = "0" +shader0 = "shaders/hyllian/support/multiLUT-modified.slang" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "1.000000" +scale_type_y0 = "source" +scale_y0 = "1.000000" +shader1 = "shaders/hyllian/crt-hyllian-sinc-pass0.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "false" +srgb_framebuffer1 = "true" +scale_type_x1 = "viewport" +scale_x1 = "1.000000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +shader2 = "shaders/hyllian/crt-hyllian-pass1.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_edge" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "true" +scale_type_x2 = "source" +scale_x2 = "1.000000" +scale_type_y2 = "viewport" +scale_y2 = "1.000000" +LUT_selector_param = "2.000000" +HFILTER_PROFILE = "2.000000" +PHOSPHOR_LAYOUT = "2.000000" +BRIGHTBOOST = "1.500000 +textures = "SamplerLUT1;SamplerLUT2" +SamplerLUT1 = "shaders/guest/advanced/lut/ntsc-lut.png" +SamplerLUT1_linear = true +SamplerLUT2 = "shaders/hyllian/support/LUT/some-grade.png" +SamplerLUT2_linear = true diff --git a/crt/crt-hyllian-sinc-curvature.slangp b/crt/crt-hyllian-sinc-curvature.slangp deleted file mode 100644 index 5682ad0f..00000000 --- a/crt/crt-hyllian-sinc-curvature.slangp +++ /dev/null @@ -1,6 +0,0 @@ -shaders = 1 - -shader0 = shaders/hyllian/crt-hyllian-sinc-curvature.slang -filter_linear0 = false -float_framebuffer0 = true -scale_type0 = viewport diff --git a/crt/crt-hyllian-sinc-glow.slangp b/crt/crt-hyllian-sinc-glow.slangp deleted file mode 100644 index a23c603d..00000000 --- a/crt/crt-hyllian-sinc-glow.slangp +++ /dev/null @@ -1,78 +0,0 @@ -shaders = "6" -shader0 = "shaders/glow/linearize.slang" -filter_linear0 = "false" -wrap_mode0 = "clamp_to_border" -mipmap_input0 = "false" -alias0 = "" -float_framebuffer0 = "false" -srgb_framebuffer0 = "true" -shader1 = "shaders/hyllian/crt-hyllian-sinc.slang" -filter_linear1 = "false" -wrap_mode1 = "clamp_to_border" -mipmap_input1 = "false" -alias1 = "CRTPass" -float_framebuffer1 = "false" -srgb_framebuffer1 = "true" -scale_type_x1 = "viewport" -scale_x1 = "1.000000" -scale_type_y1 = "viewport" -scale_y1 = "1.000000" -shader2 = "shaders/glow/threshold.slang" -filter_linear2 = "true" -wrap_mode2 = "clamp_to_border" -mipmap_input2 = "false" -alias2 = "" -float_framebuffer2 = "false" -srgb_framebuffer2 = "true" -shader3 = "shaders/glow/blur_horiz.slang" -filter_linear3 = "true" -wrap_mode3 = "clamp_to_border" -mipmap_input3 = "true" -alias3 = "" -float_framebuffer3 = "false" -srgb_framebuffer3 = "true" -scale_type_x3 = "viewport" -scale_x3 = "0.200000" -scale_type_y3 = "viewport" -scale_y3 = "0.200000" -shader4 = "shaders/glow/blur_vert.slang" -filter_linear4 = "true" -wrap_mode4 = "clamp_to_border" -mipmap_input4 = "false" -alias4 = "" -float_framebuffer4 = "false" -srgb_framebuffer4 = "true" -shader5 = "shaders/glow/resolve.slang" -filter_linear5 = "true" -wrap_mode5 = "clamp_to_border" -mipmap_input5 = "false" -alias5 = "" -float_framebuffer5 = "false" -srgb_framebuffer5 = "false" -scale_type5 = viewport -parameters = "INPUT_GAMMA;BEAM_PROFILE;BEAM_MIN_WIDTH;BEAM_MAX_WIDTH;SCANLINES_STRENGTH;COLOR_BOOST;HFILTER_SHARPNESS;PHOSPHOR_LAYOUT;MASK_INTENSITY;CRT_ANTI_RINGING;InputGamma;OutputGamma;VSCANLINES;GLOW_WHITEPOINT;GLOW_ROLLOFF;BLOOM_STRENGTH;OUTPUT_GAMMA;CURVATURE;warpX;warpY;cornersize;cornersmooth;noise_amt;shadowMask;maskDark;maskLight" -INPUT_GAMMA = "2.400000" -BEAM_PROFILE = "0'.000000" -BEAM_MIN_WIDTH = "0.920000" -BEAM_MAX_WIDTH = "1.000000" -SCANLINES_STRENGTH = "0.720000" -COLOR_BOOST = "1.250000" -PHOSPHOR_LAYOUT = "4.000000" -MASK_INTENSITY = "0.700000" -CRT_ANTI_RINGING = "0.000000" -InputGamma = "1.000000" -OutputGamma = "1.000000" -VSCANLINES = "0.000000" -GLOW_WHITEPOINT = "0.900000" -GLOW_ROLLOFF = "3.000000" -BLOOM_STRENGTH = "0.100000" -OUTPUT_GAMMA = "2.200000" -CURVATURE = "0.000000" -warpX = "0.015000" -warpY = "0.015000" -cornersize = "0.010000" -cornersmooth = "380.000000" -noise_amt = "0.250000" -shadowMask = "0.000000" -maskDark = "0.500000" -maskLight = "1.500000" diff --git a/crt/crt-hyllian-sinc.slangp b/crt/crt-hyllian-sinc.slangp deleted file mode 100644 index 54f0c483..00000000 --- a/crt/crt-hyllian-sinc.slangp +++ /dev/null @@ -1,5 +0,0 @@ -shaders = 1 - -shader0 = shaders/hyllian/crt-hyllian-sinc.slang -filter_linear0 = false -scale_type0 = viewport diff --git a/crt/crt-hyllian.slangp b/crt/crt-hyllian.slangp index ec60e66b..39bea373 100644 --- a/crt/crt-hyllian.slangp +++ b/crt/crt-hyllian.slangp @@ -1,5 +1,40 @@ -shaders = 1 - -shader0 = shaders/hyllian/crt-hyllian.slang -filter_linear0 = false -scale_type0 = viewport +shaders = "3" +feedback_pass = "0" +shader0 = "shaders/hyllian/support/multiLUT-modified.slang" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" +scale_type_x0 = "source" +scale_x0 = "1.000000" +scale_type_y0 = "source" +scale_y0 = "1.000000" +shader1 = "shaders/hyllian/crt-hyllian-pass0.slang" +filter_linear1 = "false" +wrap_mode1 = "clamp_to_border" +mipmap_input1 = "false" +alias1 = "" +float_framebuffer1 = "false" +srgb_framebuffer1 = "true" +scale_type_x1 = "viewport" +scale_x1 = "1.000000" +scale_type_y1 = "source" +scale_y1 = "1.000000" +shader2 = "shaders/hyllian/crt-hyllian-pass1.slang" +filter_linear2 = "false" +wrap_mode2 = "clamp_to_edge" +mipmap_input2 = "false" +alias2 = "" +float_framebuffer2 = "false" +srgb_framebuffer2 = "false" +scale_type_x2 = "source" +scale_x2 = "1.000000" +scale_type_y2 = "viewport" +scale_y2 = "1.000000" +LUT_selector_param = "2.000000" +textures = "SamplerLUT1;SamplerLUT2" +SamplerLUT1 = "shaders/guest/advanced/lut/ntsc-lut.png" +SamplerLUT1_linear = true +SamplerLUT2 = "shaders/hyllian/support/LUT/some-grade.png" +SamplerLUT2_linear = true diff --git a/crt/shaders/hyllian/crt-hyllian-curvature.slang b/crt/shaders/hyllian/crt-hyllian-curvature.slang deleted file mode 100644 index d1e529c7..00000000 --- a/crt/shaders/hyllian/crt-hyllian-curvature.slang +++ /dev/null @@ -1,252 +0,0 @@ -#version 450 - -layout(push_constant) uniform Push -{ - float BEAM_PROFILE; - float HFILTER_PROFILE; - float BEAM_MIN_WIDTH; - float BEAM_MAX_WIDTH; - float SCANLINES_STRENGTH; - float COLOR_BOOST; - float SHARPNESS_HACK; - float PHOSPHOR_LAYOUT; - float MASK_INTENSITY; - float CRT_ANTI_RINGING; - float InputGamma; - float OutputGamma; - float VSCANLINES; - float CRT_CURVATURE; - float CRT_warpX; - float CRT_warpY; - float CRT_cornersize; - float CRT_cornersmooth; -} param; - -#pragma parameter CRT_HYLLIAN "[CRT-HYLLIAN PARAMS]" 0.0 0.0 0.0 0.0 -#pragma parameter BEAM_PROFILE " BEAM PROFILE (BP)" 0.0 0.0 2.0 1.0 -#pragma parameter HFILTER_PROFILE " HORIZONTAL FILTER PROFILE [ HERMITE | CATMULL-ROM ]" 1.0 0.0 1.0 1.0 -#pragma parameter BEAM_MIN_WIDTH " Custom [If BP=0.00] MIN BEAM WIDTH" 0.92 0.0 1.0 0.01 -#pragma parameter BEAM_MAX_WIDTH " Custom [If BP=0.00] MAX BEAM WIDTH" 1.0 0.0 1.0 0.01 -#pragma parameter SCANLINES_STRENGTH " Custom [If BP=0.00] SCANLINES STRENGTH" 0.58 0.0 1.0 0.01 -#pragma parameter COLOR_BOOST " Custom [If BP=0.00] COLOR BOOST" 1.60 1.0 2.0 0.05 -#pragma parameter SHARPNESS_HACK " SHARPNESS_HACK" 1.0 1.0 4.0 1.0 -#pragma parameter PHOSPHOR_LAYOUT " PHOSPHOR LAYOUT" 4.0 0.0 24.0 1.0 -#pragma parameter MASK_INTENSITY " MASK INTENSITY" 0.7 0.0 1.0 0.1 -#pragma parameter CRT_ANTI_RINGING " ANTI RINGING" 1.0 0.0 1.0 0.2 -#pragma parameter InputGamma " INPUT GAMMA" 2.4 0.0 5.0 0.1 -#pragma parameter OutputGamma " OUTPUT GAMMA" 2.2 0.0 5.0 0.1 -#pragma parameter VSCANLINES " VERTICAL SCANLINES [ OFF | ON ]" 0.0 0.0 1.0 1.0 -#pragma parameter CRT_CURVATURE "CRT-Curvature" 1.0 0.0 1.0 1.0 -#pragma parameter CRT_warpX "CRT-Curvature X-Axis" 0.015 0.0 0.125 0.005 -#pragma parameter CRT_warpY "CRT-Curvature Y-Axis" 0.015 0.0 0.125 0.005 -vec2 CRT_Distortion = vec2(param.CRT_warpX, param.CRT_warpY) * 15.; -#pragma parameter CRT_cornersize "CRT-Corner Size" 0.01 0.001 1.0 0.005 -#define cornersize param.CRT_cornersize -#pragma parameter CRT_cornersmooth "CRT-Corner Smoothness" 380.0 80.0 2080.0 100.0 -#define cornersmooth param.CRT_cornersmooth - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; - vec4 OutputSize; - vec4 OriginalSize; - vec4 SourceSize; -} global; - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord * 1.0001; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 1) in vec2 FragCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; - -/* - Hyllian's CRT Shader - - Copyright (C) 2011-2022 Hyllian - sergiogdb@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#include "../../../include/subpixel_masks.h" - -#define GAMMA_IN(color) pow(color, vec3(param.InputGamma, param.InputGamma, param.InputGamma)) -#define GAMMA_OUT(color) pow(color, vec3(1.0 / param.OutputGamma, 1.0 / param.OutputGamma, 1.0 / param.OutputGamma)) - - -const vec2 corner_aspect = vec2(1.0, 0.75); - -float corner(vec2 coord) -{ - coord = (coord - vec2(0.5)) + vec2(0.5, 0.5); - coord = min(coord, vec2(1.0) - coord) * corner_aspect; - vec2 cdist = vec2(cornersize); - coord = (cdist - min(coord, cdist)); - float dist = sqrt(dot(coord, coord)); - - return clamp((cdist.x - dist)*cornersmooth, 0.0, 1.0); -} - - -vec2 Warp(vec2 texCoord){ - - vec2 curvedCoords = texCoord * 2.0 - 1.0; - float curvedCoordsDistance = sqrt(curvedCoords.x*curvedCoords.x+curvedCoords.y*curvedCoords.y); - - curvedCoords = curvedCoords / curvedCoordsDistance; - - curvedCoords = curvedCoords * (1.0-pow(vec2(1.0-(curvedCoordsDistance/1.4142135623730950488016887242097)),(1.0/(1.0+CRT_Distortion*0.2)))); - - curvedCoords = curvedCoords / (1.0-pow(vec2(0.29289321881345247559915563789515),(1.0/(vec2(1.0)+CRT_Distortion*0.2)))); - - curvedCoords = curvedCoords * 0.5 + 0.5; - return curvedCoords; -} - -// Horizontal cubic filter. -// Some known filters use these values: - -// B = 0.0, C = 0.0 => Hermite cubic filter. -// B = 1.0, C = 0.0 => Cubic B-Spline filter. -// B = 0.0, C = 0.5 => Catmull-Rom Spline filter. This is the default used in this shader. -// B = C = 1.0/3.0 => Mitchell-Netravali cubic filter. -// B = 0.3782, C = 0.3109 => Robidoux filter. -// B = 0.2620, C = 0.3690 => Robidoux Sharp filter. - -// Using only Hermite and Catmull-Rom, as the others aren't useful for crt shader. -// For more info, see: http://www.imagemagick.org/Usage/img_diagrams/cubic_survey.gif -mat4x4 get_hfilter_profile() -{ - float bf = 0.0; - float cf = 0.0; - - if (param.HFILTER_PROFILE == 1) {bf = 0.0; cf = 0.5;} - - return mat4x4( (-bf - 6.0*cf)/6.0, (3.0*bf + 12.0*cf)/6.0, (-3.0*bf - 6.0*cf)/6.0, bf/6.0, - (12.0 - 9.0*bf - 6.0*cf)/6.0, (-18.0 + 12.0*bf + 6.0*cf)/6.0, 0.0, (6.0 - 2.0*bf)/6.0, - -(12.0 - 9.0*bf - 6.0*cf)/6.0, (18.0 - 15.0*bf - 12.0*cf)/6.0, (3.0*bf + 6.0*cf)/6.0, bf/6.0, - (bf + 6.0*cf)/6.0, -cf, 0.0, 0.0); - - -} - - -#define scanlines_strength (4.0*profile.x) -#define beam_min_width profile.y -#define beam_max_width profile.z -#define color_boost profile.w - -vec4 get_beam_profile() -{ - vec4 bp = vec4(param.SCANLINES_STRENGTH, param.BEAM_MIN_WIDTH, param.BEAM_MAX_WIDTH, param.COLOR_BOOST); - - if (param.BEAM_PROFILE == 1) bp = vec4(0.62, 1.00, 1.00, 1.40); // Catmull-rom - if (param.BEAM_PROFILE == 2) bp = vec4(0.72, 1.00, 1.00, 1.20); // Catmull-rom - - return bp; -} - - -void main() -{ - vec4 profile = get_beam_profile(); - - vec2 TextureSize = mix(vec2(global.SourceSize.x * param.SHARPNESS_HACK, global.SourceSize.y), vec2(global.SourceSize.x, global.SourceSize.y * param.SHARPNESS_HACK), param.VSCANLINES); - - vec2 dx = mix(vec2(1.0/TextureSize.x, 0.0), vec2(0.0, 1.0/TextureSize.y), param.VSCANLINES); - vec2 dy = mix(vec2(0.0, 1.0/TextureSize.y), vec2(1.0/TextureSize.x, 0.0), param.VSCANLINES); - - vec2 pp = vTexCoord.xy; - pp = (param.CRT_CURVATURE > 0.5) ? Warp(pp) : pp; - - - vec2 pix_coord = pp.xy*TextureSize + vec2(-0.5, 0.5); - - vec2 tc = mix((floor(pix_coord) + vec2(0.5, 0.5))/TextureSize, (floor(pix_coord) + vec2(1.5, -0.5))/TextureSize, param.VSCANLINES); - - vec2 fp = mix(fract(pix_coord), fract(pix_coord.yx), param.VSCANLINES); - - vec3 c00 = GAMMA_IN(texture(Source, tc - dx - dy).xyz); - vec3 c01 = GAMMA_IN(texture(Source, tc - dy).xyz); - vec3 c02 = GAMMA_IN(texture(Source, tc + dx - dy).xyz); - vec3 c03 = GAMMA_IN(texture(Source, tc + 2.0*dx - dy).xyz); - vec3 c10 = GAMMA_IN(texture(Source, tc - dx ).xyz); - vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); - vec3 c12 = GAMMA_IN(texture(Source, tc + dx ).xyz); - vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx ).xyz); - - mat4x4 invX = get_hfilter_profile(); - - mat4x3 color_matrix0 = mat4x3(c00, c01, c02, c03); - mat4x3 color_matrix1 = mat4x3(c10, c11, c12, c13); - - vec4 invX_Px = vec4(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0) * invX; - vec3 color0 = color_matrix0 * invX_Px; - vec3 color1 = color_matrix1 * invX_Px; - - // Get min/max samples - vec3 min_sample0 = min(c01,c02); - vec3 max_sample0 = max(c01,c02); - vec3 min_sample1 = min(c11,c12); - vec3 max_sample1 = max(c11,c12); - - // Anti-ringing - vec3 aux = color0; - color0 = clamp(color0, min_sample0, max_sample0); - color0 = mix(aux, color0, param.CRT_ANTI_RINGING * step(0.0, (c00-c01)*(c02-c03))); - aux = color1; - color1 = clamp(color1, min_sample1, max_sample1); - color1 = mix(aux, color1, param.CRT_ANTI_RINGING * step(0.0, (c10-c11)*(c12-c13))); - - float pos0 = fp.y; - float pos1 = 1 - fp.y; - - vec3 lum0 = mix(vec3(beam_min_width), vec3(beam_max_width), color0); - vec3 lum1 = mix(vec3(beam_min_width), vec3(beam_max_width), color1); - - vec3 d0 = scanlines_strength*pos0/(lum0*lum0+0.0000001); - vec3 d1 = scanlines_strength*pos1/(lum1*lum1+0.0000001); - - d0 = exp(-d0*d0); - d1 = exp(-d1*d1); - - vec3 color = color_boost*(color0*d0+color1*d1); - - vec2 mask_coords =vTexCoord.xy * global.OutputSize.xy; - - mask_coords = mix(mask_coords.xy, mask_coords.yx, param.VSCANLINES); - - color.rgb*=mask_weights(mask_coords, param.MASK_INTENSITY, int(param.PHOSPHOR_LAYOUT)); - - color = GAMMA_OUT(color); - - FragColor = vec4(color, 1.0); - - FragColor *= (param.CRT_CURVATURE > 0.5) ? corner(pp) : 1.0; -} diff --git a/crt/shaders/hyllian/crt-hyllian-glow/crt-hyllian.slang b/crt/shaders/hyllian/crt-hyllian-glow/crt-hyllian.slang deleted file mode 100644 index 175d8538..00000000 --- a/crt/shaders/hyllian/crt-hyllian-glow/crt-hyllian.slang +++ /dev/null @@ -1,185 +0,0 @@ -#version 450 - -layout(push_constant) uniform Push -{ - float PHOSPHOR; - float VSCANLINES; - float InputGamma; - float OutputGamma; - float SHARPNESS; - float COLOR_BOOST; - float RED_BOOST; - float GREEN_BOOST; - float BLUE_BOOST; - float SCANLINES_STRENGTH; - float BEAM_MIN_WIDTH; - float BEAM_MAX_WIDTH; - float CRT_ANTI_RINGING; -} param; - -#pragma parameter PHOSPHOR "CRT - Phosphor ON/OFF" 0.0 0.0 1.0 1.0 -#pragma parameter VSCANLINES "CRT - Scanlines Direction" 0.0 0.0 1.0 1.0 -#pragma parameter InputGamma "CRT - Input gamma" 2.2 0.0 5.0 0.1 -#pragma parameter OutputGamma "CRT - Output Gamma" 2.2 0.0 5.0 0.1 -#pragma parameter SHARPNESS "CRT - Sharpness Hack" 2.0 1.0 5.0 1.0 -#pragma parameter COLOR_BOOST "CRT - Color Boost" 1.3 1.0 2.0 0.05 -#pragma parameter RED_BOOST "CRT - Red Boost" 1.0 1.0 2.0 0.01 -#pragma parameter GREEN_BOOST "CRT - Green Boost" 1.0 1.0 2.0 0.01 -#pragma parameter BLUE_BOOST "CRT - Blue Boost" 1.0 1.0 2.0 0.01 -#pragma parameter SCANLINES_STRENGTH "CRT - Scanline Strength" 1.0 0.0 1.0 0.02 -#pragma parameter BEAM_MIN_WIDTH "CRT - Min Beam Width" 0.60 0.0 1.0 0.02 -#pragma parameter BEAM_MAX_WIDTH "CRT - Max Beam Width" 0.80 0.0 1.0 0.02 -#pragma parameter CRT_ANTI_RINGING "CRT - Anti-Ringing" 0.8 0.0 1.0 0.1 - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; - vec4 OutputSize; - vec4 OriginalSize; - vec4 SourceSize; -} global; - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 1) in vec2 FragCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; - -/* - Hyllian's CRT Shader - - Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#define GAMMA_IN(color) pow(color, vec3(param.InputGamma, param.InputGamma, param.InputGamma)) -#define GAMMA_OUT(color) pow(color, vec3(1.0 / param.OutputGamma, 1.0 / param.OutputGamma, 1.0 / param.OutputGamma)) - -// Horizontal cubic filter. - -// Some known filters use these values: - -// B = 0.0, C = 0.0 => Hermite cubic filter. -// B = 1.0, C = 0.0 => Cubic B-Spline filter. -// B = 0.0, C = 0.5 => Catmull-Rom Spline filter. This is the default used in this shader. -// B = C = 1.0/3.0 => Mitchell-Netravali cubic filter. -// B = 0.3782, C = 0.3109 => Robidoux filter. -// B = 0.2620, C = 0.3690 => Robidoux Sharp filter. -// B = 0.36, C = 0.28 => My best config for ringing elimination in pixel art (Hyllian). - -// For more info, see: http://www.imagemagick.org/Usage/img_diagrams/cubic_survey.gif - -// Change these params to configure the horizontal filter. -float B = 0.0; -float C = 0.5; - -mat4x4 invX = mat4x4( - (-B - 6.0*C)/6.0, (3.0*B + 12.0*C)/6.0, (-3.0*B - 6.0*C)/6.0, B/6.0, - (12.0 - 9.0*B - 6.0*C)/6.0, (-18.0 + 12.0*B + 6.0*C)/6.0, 0.0, (6.0 - 2.0*B)/6.0, - -(12.0 - 9.0*B - 6.0*C)/6.0, (18.0 - 15.0*B - 12.0*C)/6.0, (3.0*B + 6.0*C)/6.0, B/6.0, - (B + 6.0*C)/6.0, -C, 0.0, 0.0 -); - - - -void main() -{ - vec3 color; - - vec2 TextureSize = vec2(param.SHARPNESS*global.SourceSize.x, global.SourceSize.y); - - vec2 dx = mix(vec2(1.0/TextureSize.x, 0.0), vec2(0.0, 1.0/TextureSize.y), param.VSCANLINES); - vec2 dy = mix(vec2(0.0, 1.0/TextureSize.y), vec2(1.0/TextureSize.x, 0.0), param.VSCANLINES); - - vec2 pix_coord = vTexCoord*TextureSize + vec2(-0.5, 0.5); - - vec2 tc = mix((floor(pix_coord) + vec2(0.5, 0.5))/TextureSize, (floor(pix_coord) + vec2(1.0, -0.5))/TextureSize, param.VSCANLINES); - - vec2 fp = mix(fract(pix_coord), fract(pix_coord.yx), param.VSCANLINES); - - vec3 c00 = GAMMA_IN(texture(Source, tc - dx - dy).xyz); - vec3 c01 = GAMMA_IN(texture(Source, tc - dy).xyz); - vec3 c02 = GAMMA_IN(texture(Source, tc + dx - dy).xyz); - vec3 c03 = GAMMA_IN(texture(Source, tc + 2.0*dx - dy).xyz); - vec3 c10 = GAMMA_IN(texture(Source, tc - dx ).xyz); - vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); - vec3 c12 = GAMMA_IN(texture(Source, tc + dx ).xyz); - vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx ).xyz); - - // Get min/max samples - vec3 min_sample = min(min(c01, c11), min(c02, c12)); - vec3 max_sample = max(max(c01, c11), max(c02, c12)); - - mat4x3 color_matrix0 = mat4x3(c00, c01, c02, c03); - mat4x3 color_matrix1 = mat4x3(c10, c11, c12, c13); - - vec4 invX_Px = vec4(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0) * invX; - vec3 color0 = color_matrix0 * invX_Px; - vec3 color1 = color_matrix1 * invX_Px; - - // Anti-ringing - vec3 aux = color0; - color0 = clamp(color0, min_sample, max_sample); - color0 = mix(aux, color0, param.CRT_ANTI_RINGING); - aux = color1; - color1 = clamp(color1, min_sample, max_sample); - color1 = mix(aux, color1, param.CRT_ANTI_RINGING); - - float pos0 = fp.y; - float pos1 = 1 - fp.y; - - vec3 lum0 = mix(vec3(param.BEAM_MIN_WIDTH), vec3(param.BEAM_MAX_WIDTH), color0); - vec3 lum1 = mix(vec3(param.BEAM_MIN_WIDTH), vec3(param.BEAM_MAX_WIDTH), color1); - - vec3 d0 = clamp(pos0/(lum0 + 0.0000001), 0.0, 1.0); - vec3 d1 = clamp(pos1/(lum1 + 0.0000001), 0.0, 1.0); - - d0 = exp(-10.0*param.SCANLINES_STRENGTH*d0*d0); - d1 = exp(-10.0*param.SCANLINES_STRENGTH*d1*d1); - - color = clamp(color0*d0 + color1*d1, 0.0, 1.0); - - color *= param.COLOR_BOOST*vec3(param.RED_BOOST, param.GREEN_BOOST, param.BLUE_BOOST); - - float mod_factor = mix(vTexCoord.x * global.OutputSize.x, vTexCoord.y * global.OutputSize.y, param.VSCANLINES); - - vec3 dotMaskWeights = mix( - vec3(1.0, 0.7, 1.0), - vec3(0.7, 1.0, 0.7), - floor(mod(mod_factor, 2.0)) - ); - - color.rgb *= mix(vec3(1.0), dotMaskWeights, param.PHOSPHOR); - - color = GAMMA_OUT(color); - - FragColor = vec4(color, 1.0); -} diff --git a/crt/shaders/hyllian/crt-hyllian-glow/resolve2.slang b/crt/shaders/hyllian/crt-hyllian-glow/resolve2.slang deleted file mode 100644 index 3631e899..00000000 --- a/crt/shaders/hyllian/crt-hyllian-glow/resolve2.slang +++ /dev/null @@ -1,50 +0,0 @@ -#version 450 - -layout(push_constant) uniform Push -{ - vec4 SourceSize; - vec4 OriginalSize; - vec4 OutputSize; - uint FrameCount; - float BLOOM_STRENGTH; - float SOURCE_BOOST; -} params; - -#pragma parameter BLOOM_STRENGTH "Bloom Strength" 0.45 0.0 1.0 0.01 -#pragma parameter SOURCE_BOOST "Bloom Color Boost" 1.15 1.0 1.3 0.01 - -#define BLOOM_STRENGTH params.BLOOM_STRENGTH -#define SOURCE_BOOST params.SOURCE_BOOST - -#define INV_OUTPUT_GAMMA (1.0 / 2.2) -#define saturate(c) clamp(c, 0.0, 1.0) - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; -} global; - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; -layout(set = 0, binding = 3) uniform sampler2D CRT_PASS; - -void main() -{ - vec3 source = SOURCE_BOOST * texture(CRT_PASS, vTexCoord).rgb; - vec3 bloom = texture(Source, vTexCoord).rgb; - source += BLOOM_STRENGTH * bloom; - FragColor = vec4(pow(saturate(source), vec3(INV_OUTPUT_GAMMA,INV_OUTPUT_GAMMA,INV_OUTPUT_GAMMA)), 1.0); -} \ No newline at end of file diff --git a/crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass0.slang b/crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass0.slang deleted file mode 100644 index f857943e..00000000 --- a/crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass0.slang +++ /dev/null @@ -1,125 +0,0 @@ -#version 450 - -/* - Hyllian's CRT Shader - pass0 - - Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -layout(push_constant) uniform Push -{ - vec4 SourceSize; - vec4 OriginalSize; - vec4 OutputSize; - uint FrameCount; - float SHARPNESS; - float CRT_ANTI_RINGING; - float InputGamma; -} params; - -#pragma parameter SHARPNESS "CRT - Sharpness Hack" 1.0 1.0 5.0 1.0 -#pragma parameter CRT_ANTI_RINGING "CRT - Anti-Ringing" 0.8 0.0 1.0 0.1 -#pragma parameter InputGamma "CRT - Input gamma" 2.5 0.0 5.0 0.1 - -#define SHARPNESS params.SHARPNESS -#define CRT_ANTI_RINGING params.CRT_ANTI_RINGING -#define InputGamma params.InputGamma - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; -} global; - -#define GAMMA_IN(color) pow(color, vec3(InputGamma, InputGamma, InputGamma)) - -// Horizontal cubic filter. - -// Some known filters use these values: - -// B = 0.0, C = 0.0 => Hermite cubic filter. -// B = 1.0, C = 0.0 => Cubic B-Spline filter. -// B = 0.0, C = 0.5 => Catmull-Rom Spline filter. This is the default used in this shader. -// B = C = 1.0/3.0 => Mitchell-Netravali cubic filter. -// B = 0.3782, C = 0.3109 => Robidoux filter. -// B = 0.2620, C = 0.3690 => Robidoux Sharp filter. -// B = 0.36, C = 0.28 => My best config for ringing elimination in pixel art (Hyllian). - - -// For more info, see: http://www.imagemagick.org/Usage/img_diagrams/cubic_survey.gif - -// Change these params to configure the horizontal filter. -const float B = 0.0; -const float C = 0.5; - -const mat4 invX = mat4( (-B - 6.0*C)/6.0, (12.0 - 9.0*B - 6.0*C)/6.0, -(12.0 - 9.0*B - 6.0*C)/6.0, (B + 6.0*C)/6.0, - (3.0*B + 12.0*C)/6.0, (-18.0 + 12.0*B + 6.0*C)/6.0, (18.0 - 15.0*B - 12.0*C)/6.0, -C, - (-3.0*B - 6.0*C)/6.0, 0.0, (3.0*B + 6.0*C)/6.0, 0.0, - B/6.0, (6.0 - 2.0*B)/6.0, B/6.0, 0.0); - - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; - -void main() -{ - vec2 texture_size = vec2(SHARPNESS*params.SourceSize.x, params.SourceSize.y); - - vec3 color; - vec2 dx = vec2(1.0/texture_size.x, 0.0); - vec2 dy = vec2(0.0, 1.0/texture_size.y); - vec2 pix_coord = vTexCoord*texture_size+vec2(-0.5,0.0); - - vec2 tc = (floor(pix_coord)+vec2(0.5,0.001))/texture_size; - - vec2 fp = fract(pix_coord); - - vec3 c10 = GAMMA_IN(texture(Source, tc - dx).xyz); - vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); - vec3 c12 = GAMMA_IN(texture(Source, tc + dx).xyz); - vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx).xyz); - - // Get min/max samples - vec3 min_sample = min(c11,c12); - vec3 max_sample = max(c11,c12); - - mat4x3 color_matrix = mat4x3(c10, c11, c12, c13); - - vec4 lobes = vec4(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0); - - vec4 invX_Px = invX * lobes; - color = color_matrix * invX_Px; - - // Anti-ringing - vec3 aux = color; - color = clamp(color, min_sample, max_sample); - color = mix(aux, color, CRT_ANTI_RINGING); - FragColor = vec4(color, 1.0); -} diff --git a/crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass1.slang b/crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass1.slang deleted file mode 100644 index cb2fba85..00000000 --- a/crt/shaders/hyllian/crt-hyllian-multipass/crt-hyllian-pass1.slang +++ /dev/null @@ -1,127 +0,0 @@ -#version 450 - -/* - Hyllian's CRT Shader - pass1 - - Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -layout(push_constant) uniform Push -{ - vec4 SourceSize; - vec4 OriginalSize; - vec4 OutputSize; - uint FrameCount; - float OutputGamma; - float PHOSPHOR; - float COLOR_BOOST; - float RED_BOOST; - float GREEN_BOOST; - float BLUE_BOOST; - float SCANLINES_STRENGTH; - float BEAM_MIN_WIDTH; - float BEAM_MAX_WIDTH; -} params; - -#pragma parameter OutputGamma "CRT - Output Gamma" 2.2 0.0 5.0 0.1 -#pragma parameter PHOSPHOR "CRT - Phosphor ON/OFF" 1.0 0.0 1.0 1.0 -#pragma parameter COLOR_BOOST "CRT - Color Boost" 1.5 1.0 2.0 0.05 -#pragma parameter RED_BOOST "CRT - Red Boost" 1.0 1.0 2.0 0.01 -#pragma parameter GREEN_BOOST "CRT - Green Boost" 1.0 1.0 2.0 0.01 -#pragma parameter BLUE_BOOST "CRT - Blue Boost" 1.0 1.0 2.0 0.01 -#pragma parameter SCANLINES_STRENGTH "CRT - Scanline Strength" 0.72 0.0 1.0 0.02 -#pragma parameter BEAM_MIN_WIDTH "CRT - Min Beam Width" 0.86 0.0 1.0 0.02 -#pragma parameter BEAM_MAX_WIDTH "CRT - Max Beam Width" 1.0 0.0 1.0 0.02 - -#define OutputGamma params.OutputGamma -#define PHOSPHOR params.PHOSPHOR -#define COLOR_BOOST params.COLOR_BOOST -#define RED_BOOST params.RED_BOOST -#define GREEN_BOOST params.GREEN_BOOST -#define BLUE_BOOST params.BLUE_BOOST -#define SCANLINES_STRENGTH params.SCANLINES_STRENGTH -#define BEAM_MIN_WIDTH params.BEAM_MIN_WIDTH -#define BEAM_MAX_WIDTH params.BEAM_MAX_WIDTH - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; -} global; - -#define GAMMA_OUT(color) pow(color, vec3(1.0 / OutputGamma, 1.0 / OutputGamma, 1.0 / OutputGamma)) - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; - -void main() -{ - vec2 texture_size = params.SourceSize.xy; - - vec3 color; - vec2 dx = vec2(1.0/texture_size.x, 0.0); - vec2 dy = vec2(0.0, 1.0/texture_size.y); - vec2 pix_coord = vTexCoord*texture_size+vec2(0.0,0.5); - - vec2 tc = (floor(pix_coord)+vec2(0.0,0.5))/texture_size; - - vec2 fp = fract(pix_coord); - - vec3 color0 = texture(Source, tc - dy).xyz; - vec3 color1 = texture(Source, tc ).xyz; - - float pos0 = fp.y; - float pos1 = 1 - fp.y; - - vec3 lum0 = mix(vec3(BEAM_MIN_WIDTH), vec3(BEAM_MAX_WIDTH), color0); - vec3 lum1 = mix(vec3(BEAM_MIN_WIDTH), vec3(BEAM_MAX_WIDTH), color1); - - vec3 d0 = clamp(pos0/(lum0+0.0000001), 0.0, 1.0); - vec3 d1 = clamp(pos1/(lum1+0.0000001), 0.0, 1.0); - - d0 = exp(-10.0*SCANLINES_STRENGTH*d0*d0); - d1 = exp(-10.0*SCANLINES_STRENGTH*d1*d1); - - color = clamp(color0*d0+color1*d1, 0.0, 1.0); - - color *= COLOR_BOOST*vec3(RED_BOOST, GREEN_BOOST, BLUE_BOOST); - float mod_factor = vTexCoord.x * params.OutputSize.x; - - vec3 dotMaskWeights = mix( - vec3(1.0, 0.7, 1.0), - vec3(0.7, 1.0, 0.7), - floor(mod(mod_factor, 2.0)) - ); - - color.rgb *= mix(vec3(1.0, 1.0, 1.0), dotMaskWeights, PHOSPHOR); - - color = GAMMA_OUT(color); - FragColor = vec4(color, 1.0); -} \ No newline at end of file diff --git a/crt/shaders/hyllian/crt-hyllian-pass0.slang b/crt/shaders/hyllian/crt-hyllian-pass0.slang new file mode 100644 index 00000000..7ad610d0 --- /dev/null +++ b/crt/shaders/hyllian/crt-hyllian-pass0.slang @@ -0,0 +1,180 @@ +#version 450 + +/* + Hyllian's CRT Shader + + Copyright (C) 2011-2024 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +layout(push_constant) uniform Push +{ + float HFILTER_PROFILE; + float SHARPNESS_HACK; + float CRT_ANTI_RINGING; + float CRT_InputGamma; + float CURVATURE; + float WARP_X; + float WARP_Y; +} params; + +#pragma parameter CRT_HYLLIAN "[CRT-HYLLIAN PARAMS]" 0.0 0.0 0.0 0.0 +#pragma parameter HFILTER_PROFILE " HORIZONTAL FILTER PROFILE [ SHARP1 | SHARP2 ]" 1.0 0.0 1.0 1.0 +#pragma parameter CRT_ANTI_RINGING " ANTI RINGING" 1.0 0.0 1.0 1.0 +#pragma parameter SHARPNESS_HACK " SHARPNESS_HACK" 1.0 1.0 4.0 1.0 +#pragma parameter CRT_InputGamma " INPUT GAMMA" 2.4 1.0 5.0 0.1 +#pragma parameter CRT_OutputGamma "OUTPUT GAMMA" 2.2 1.0 5.0 0.05 +#pragma parameter PHOSPHOR_LAYOUT "PHOSPHOR LAYOUT [1-6 Aperture, 7-10 Shadow, 11-14 Slot]" 1.0 0.0 15.0 1.0 +#pragma parameter MASK_INTENSITY "MASK INTENSITY" 0.65 0.0 1.0 0.01 +#pragma parameter MONITOR_SUBPIXELS "MONITOR SUBPIXELS LAYOUT [0=RGB, 1=BGR]" 0.0 0.0 1.0 1.0 +#pragma parameter BRIGHTBOOST "BRIGHTNESS BOOST" 1.40 1.0 3.0 0.05 +#pragma parameter BEAM_MIN_WIDTH "MIN BEAM WIDTH" 0.86 0.0 1.0 0.02 +#pragma parameter BEAM_MAX_WIDTH "MAX BEAM WIDTH" 1.0 0.0 1.0 0.02 +#pragma parameter SCANLINES_STRENGTH "SCANLINES STRENGTH" 0.72 0.0 1.0 0.01 +#pragma parameter SCANLINES_SHAPE "SCANLINES SHAPE (SINC | GAUSSIAN)" 0.0 0.0 1.0 1.0 +#pragma parameter POST_BRIGHTNESS "POST-BRIGHTNESS" 1.00 1.0 3.0 0.05 +#pragma parameter CURVATURE "ENABLE CURVATURE" 0.0 0.0 1.0 1.0 +#pragma parameter WARP_X " CURVATURE-X" 0.015 0.0 0.125 0.005 +#pragma parameter WARP_Y " CURVATURE-Y" 0.015 0.0 0.125 0.005 +#pragma parameter CORNER_SIZE " CORNER SIZE" 0.02 0.001 1.0 0.005 +#pragma parameter CORNER_SMOOTHNESS " CORNER SMOOTHNESS" 1.10 1.0 2.2 0.02 + +#define HFILTER_PROFILE params.HFILTER_PROFILE +#define CRT_ANTI_RINGING params.CRT_ANTI_RINGING +#define SHARPNESS_HACK params.SHARPNESS_HACK +#define CRT_InputGamma params.CRT_InputGamma +#define CURVATURE params.CURVATURE +#define WARP_X params.WARP_X +#define WARP_Y params.WARP_Y + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} global; + + +#define GAMMA_IN(color) pow(color, vec3(CRT_InputGamma, CRT_InputGamma, CRT_InputGamma)) + +/* Curvature code. Credits to torridgristle! */ +vec2 CRT_Distortion = vec2(WARP_X, 0.0) * 15.; + +#define SQRT_OF_2 1.4142135623730950488016887242097 + +// Radius of Convergence = 1.0 - SQRT_OF_2 / 2 + +#define CONVERGENCE_RADIUS 0.29289321881345247559915563789515 + +vec2 Warp(vec2 texCoord) +{ + vec2 cCoords = texCoord * 2.0 - 1.0; + float cCoordsDist = sqrt(cCoords.x * cCoords.x + cCoords.y * cCoords.y); + cCoords = cCoords / cCoordsDist; + cCoords = cCoords * (1.0 - pow(vec2(1.0 - (cCoordsDist/SQRT_OF_2)),(1.0/(1.0+CRT_Distortion*0.2)))); + cCoords = cCoords / (1.0-pow(vec2(CONVERGENCE_RADIUS),(1.0/(vec2(1.0)+CRT_Distortion*0.2)))); + cCoords = cCoords * 0.5 + 0.5; + + return cCoords; +} + +// Horizontal cubic filter. +// Some known filters use these values: + +// B = 0.5, C = 0.0 => A sharp almost gaussian filter. +// B = 0.0, C = 0.0 => Hermite cubic filter. +// B = 1.0, C = 0.0 => Cubic B-Spline filter. +// B = 0.0, C = 0.5 => Catmull-Rom Spline filter. +// B = C = 1.0/3.0 => Mitchell-Netravali cubic filter. +// B = 0.3782, C = 0.3109 => Robidoux filter. +// B = 0.2620, C = 0.3690 => Robidoux Sharp filter. + +// For more info, see: http://www.imagemagick.org/Usage/img_diagrams/cubic_survey.gif + +mat4 get_hfilter_profile() +{ + float bf = 0.0; + float cf = 0.0; + + if (HFILTER_PROFILE > 0.5) {bf = 0.0; cf = 0.5;} + + return mat4( ( -bf - 6.0*cf)/6.0, (3.0*bf + 12.0*cf)/6.0, (-3.0*bf - 6.0*cf)/6.0, bf/6.0, + (12.0 - 9.0*bf - 6.0*cf)/6.0, (-18.0 + 12.0*bf + 6.0*cf)/6.0, 0.0, (6.0 - 2.0*bf)/6.0, + -(12.0 - 9.0*bf - 6.0*cf)/6.0, (18.0 - 15.0*bf - 12.0*cf)/6.0, (3.0*bf + 6.0*cf)/6.0, bf/6.0, + ( bf + 6.0*cf)/6.0, -cf, 0.0, 0.0); +} + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord*1.0001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 FragCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ + vec2 texture_size = vec2(SHARPNESS_HACK*global.SourceSize.x, global.SourceSize.y); + + vec2 dx = vec2(1.0/texture_size.x, 0.0); + + vec2 WarpedTexCoord = vTexCoord.xy; + + WarpedTexCoord = (CURVATURE > 0.5) ? Warp(WarpedTexCoord) : WarpedTexCoord; + + vec2 pix_coord = WarpedTexCoord.xy*texture_size + vec2(-0.5, 0.0); + + vec2 tc = (floor(pix_coord) + vec2(0.5,0.5))/texture_size; + + vec2 fp = fract(pix_coord); + + vec3 c10 = GAMMA_IN(texture(Source, tc - dx).xyz); + vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); + vec3 c12 = GAMMA_IN(texture(Source, tc + dx).xyz); + vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx).xyz); + + mat4x3 color_matrix = mat4x3(c10, c11, c12, c13); + + mat4 invX = get_hfilter_profile(); + vec4 lobes = vec4(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0); + vec4 invX_Px = lobes * invX; + vec3 color = color_matrix * invX_Px; + + // Anti-ringing + // Get min/max samples + vec3 min_sample = min(c11,c12); + vec3 max_sample = max(c11,c12); + + vec3 aux = color; + color = clamp(color, min_sample, max_sample); + color = mix(aux, color, CRT_ANTI_RINGING); + + FragColor = vec4(color, 1.0); +} diff --git a/crt/shaders/hyllian/crt-hyllian-pass1.slang b/crt/shaders/hyllian/crt-hyllian-pass1.slang new file mode 100644 index 00000000..cdab835f --- /dev/null +++ b/crt/shaders/hyllian/crt-hyllian-pass1.slang @@ -0,0 +1,435 @@ +#version 450 + +/* + Hyllian's CRT Shader + + Copyright (C) 2011-2024 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float CRT_OutputGamma; + float PHOSPHOR_LAYOUT; + float MASK_INTENSITY; + float MONITOR_SUBPIXELS; + float BRIGHTBOOST; + float SCANLINES_SHAPE; + float SCANLINES_STRENGTH; + float BEAM_MIN_WIDTH; + float BEAM_MAX_WIDTH; + float POST_BRIGHTNESS; + float CURVATURE; + float WARP_X; + float WARP_Y; + float CORNER_SIZE; + float CORNER_SMOOTHNESS; +} params; + +#pragma parameter CRT_OutputGamma "OUTPUT GAMMA" 2.2 1.0 5.0 0.05 +#pragma parameter PHOSPHOR_LAYOUT "PHOSPHOR LAYOUT [1-6 Aperture, 7-10 Shadow, 11-14 Slot]" 1.0 0.0 15.0 1.0 +#pragma parameter MASK_INTENSITY "MASK INTENSITY" 0.65 0.0 1.0 0.01 +#pragma parameter MONITOR_SUBPIXELS "MONITOR SUBPIXELS LAYOUT [0=RGB, 1=BGR]" 0.0 0.0 1.0 1.0 +#pragma parameter BRIGHTBOOST "BRIGHTNESS BOOST" 1.40 1.0 3.0 0.05 +#pragma parameter BEAM_MIN_WIDTH "MIN BEAM WIDTH" 0.86 0.0 1.0 0.02 +#pragma parameter BEAM_MAX_WIDTH "MAX BEAM WIDTH" 1.0 0.0 1.0 0.02 +#pragma parameter SCANLINES_STRENGTH "SCANLINES STRENGTH" 0.72 0.0 1.0 0.01 +#pragma parameter SCANLINES_SHAPE "SCANLINES SHAPE (SINC | GAUSSIAN)" 0.0 0.0 1.0 1.0 +#pragma parameter POST_BRIGHTNESS "POST-BRIGHTNESS" 1.00 1.0 3.0 0.05 +#pragma parameter CURVATURE "ENABLE CURVATURE" 0.0 0.0 1.0 1.0 +#pragma parameter WARP_X " CURVATURE-X" 0.015 0.0 0.125 0.005 +#pragma parameter WARP_Y " CURVATURE-Y" 0.015 0.0 0.125 0.005 +#pragma parameter CORNER_SIZE " CORNER SIZE" 0.02 0.001 1.0 0.005 +#pragma parameter CORNER_SMOOTHNESS " CORNER SMOOTHNESS" 1.10 1.0 2.2 0.02 + + +#define CRT_OutputGamma params.CRT_OutputGamma +#define BRIGHTBOOST (params.BRIGHTBOOST+1.1) +#define SCANLINES_SHAPE params.SCANLINES_SHAPE +#define SCANLINES_STRENGTH (-0.16*SCANLINES_SHAPE+params.SCANLINES_STRENGTH) +#define BEAM_MIN_WIDTH params.BEAM_MIN_WIDTH +#define BEAM_MAX_WIDTH params.BEAM_MAX_WIDTH +#define POST_BRIGHTNESS params.POST_BRIGHTNESS +#define CURVATURE params.CURVATURE +#define WARP_X params.WARP_X +#define WARP_Y params.WARP_Y +#define CORNER_SIZE params.CORNER_SIZE +#define CORNER_SMOOTHNESS (80.0*pow(params.CORNER_SMOOTHNESS,10.0)) + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#define GAMMA_OUT(color) pow(color, vec3(1.0 / CRT_OutputGamma, 1.0 / CRT_OutputGamma, 1.0 / CRT_OutputGamma)) + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord*1.0001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 FragCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + + +const vec2 corner_aspect = vec2(1.0, 0.75); + +float corner(vec2 coord) +{ + coord = (coord - vec2(0.5)) + vec2(0.5, 0.5); + coord = min(coord, vec2(1.0) - coord) * corner_aspect; + vec2 cdist = vec2(CORNER_SIZE); + coord = (cdist - min(coord, cdist)); + float dist = sqrt(dot(coord, coord)); + + return clamp((cdist.x - dist)*CORNER_SMOOTHNESS, 0.0, 1.0); +} + +/* Curvature code. Credits to torridgristle! */ +vec2 CRT_Distortion = vec2(0.0, WARP_Y) * 15.; + +#define SQRT_OF_2 1.4142135623730950488016887242097 + +// Radius of Convergence = 1.0 - SQRT_OF_2 / 2 + +#define CONVERGENCE_RADIUS 0.29289321881345247559915563789515 + +vec2 Warp(vec2 texCoord) +{ + vec2 cCoords = texCoord * 2.0 - 1.0; + float cCoordsDist = sqrt(cCoords.x * cCoords.x + cCoords.y * cCoords.y); + cCoords = cCoords / cCoordsDist; + cCoords = cCoords * (1.0 - pow(vec2(1.0 - (cCoordsDist/SQRT_OF_2)),(1.0/(1.0+CRT_Distortion*0.2)))); + cCoords = cCoords / (1.0-pow(vec2(CONVERGENCE_RADIUS),(1.0/(vec2(1.0)+CRT_Distortion*0.2)))); + cCoords = cCoords * 0.5 + 0.5; + + return cCoords; +} + +/* Mask code pasted from subpixel_masks.h. Masks 3 and 4 added. */ +vec3 mask_weights(vec2 coord, float mask_intensity, int phosphor_layout, float monitor_subpixels){ + vec3 weights = vec3(1.,1.,1.); + float on = 1.; + float off = 1.-mask_intensity; + vec3 red = monitor_subpixels==1.0 ? vec3(on, off, off) : vec3(off, off, on ); + vec3 green = vec3(off, on, off); + vec3 blue = monitor_subpixels==1.0 ? vec3(off, off, on ) : vec3(on, off, off); + vec3 magenta = vec3(on, off, on ); + vec3 yellow = monitor_subpixels==1.0 ? vec3(on, on, off) : vec3(off, on, on ); + vec3 cyan = monitor_subpixels==1.0 ? vec3(off, on, on ) : vec3(on, on, off); + vec3 black = vec3(off, off, off); + vec3 white = vec3(on, on, on ); + int w, z = 0; + + // This pattern is used by a few layouts, so we'll define it here + vec3 aperture_weights = mix(magenta, green, floor(mod(coord.x, 2.0))); + + if(phosphor_layout == 0) return weights; + + else if(phosphor_layout == 1){ + // classic aperture for RGB panels; good for 1080p, too small for 4K+ + // aka aperture_1_2_bgr + weights = aperture_weights; + return weights; + } + + else if(phosphor_layout == 2){ + // Classic RGB layout; good for 1080p and lower + vec3 bw3[3] = vec3[](red, green, blue); +// vec3 bw3[3] = vec3[](black, yellow, blue); + + z = int(floor(mod(coord.x, 3.0))); + + weights = bw3[z]; + return weights; + } + + else if(phosphor_layout == 3){ + // black and white aperture; good for weird subpixel layouts and low brightness; good for 1080p and lower + vec3 bw3[3] = vec3[](black, white, black); + + z = int(floor(mod(coord.x, 3.0))); + + weights = bw3[z]; + return weights; + } + + else if(phosphor_layout == 4){ + // reduced TVL aperture for RGB panels. Good for 4k. + // aperture_2_4_rgb + + vec3 big_ap_rgb[4] = vec3[](red, yellow, cyan, blue); + + w = int(floor(mod(coord.x, 4.0))); + + weights = big_ap_rgb[w]; + return weights; + } + + else if(phosphor_layout == 5){ + // black and white aperture; good for weird subpixel layouts and low brightness; good for 4k + vec3 bw4[4] = vec3[](black, black, white, white); + + z = int(floor(mod(coord.x, 4.0))); + + weights = bw4[z]; + return weights; + } + + else if(phosphor_layout == 6){ + // aperture_1_4_rgb; good for simulating lower + vec3 ap4[4] = vec3[](red, green, blue, black); + + z = int(floor(mod(coord.x, 4.0))); + + weights = ap4[z]; + return weights; + } + + else if(phosphor_layout == 7){ + // 2x2 shadow mask for RGB panels; good for 1080p, too small for 4K+ + // aka delta_1_2x1_bgr + vec3 inverse_aperture = mix(green, magenta, floor(mod(coord.x, 2.0))); + weights = mix(aperture_weights, inverse_aperture, floor(mod(coord.y, 2.0))); + return weights; + } + + else if(phosphor_layout == 8){ + // delta_2_4x1_rgb + vec3 delta[2][4] = { + {red, yellow, cyan, blue}, + {cyan, blue, red, yellow} + }; + + w = int(floor(mod(coord.y, 2.0))); + z = int(floor(mod(coord.x, 4.0))); + + weights = delta[w][z]; + return weights; + } + + else if(phosphor_layout == 9){ + // delta_1_4x1_rgb; dunno why this is called 4x1 when it's obviously 4x2 /shrug + vec3 delta1[2][4] = { + {red, green, blue, black}, + {blue, black, red, green} + }; + + w = int(floor(mod(coord.y, 2.0))); + z = int(floor(mod(coord.x, 4.0))); + + weights = delta1[w][z]; + return weights; + } + + else if(phosphor_layout == 10){ + // delta_2_4x2_rgb + vec3 delta[4][4] = { + {red, yellow, cyan, blue}, + {red, yellow, cyan, blue}, + {cyan, blue, red, yellow}, + {cyan, blue, red, yellow} + }; + + w = int(floor(mod(coord.y, 4.0))); + z = int(floor(mod(coord.x, 4.0))); + + weights = delta[w][z]; + return weights; + } + + else if(phosphor_layout == 11){ + // slot mask for RGB panels; looks okay at 1080p, looks better at 4K + vec3 slotmask[4][6] = { + {red, green, blue, red, green, blue,}, + {red, green, blue, black, black, black}, + {red, green, blue, red, green, blue,}, + {black, black, black, red, green, blue,} + }; + + w = int(floor(mod(coord.y, 4.0))); + z = int(floor(mod(coord.x, 6.0))); + + // use the indexes to find which color to apply to the current pixel + weights = slotmask[w][z]; + return weights; + } + + else if(phosphor_layout == 12){ + // slot mask for RGB panels; looks okay at 1080p, looks better at 4K + vec3 slotmask[4][6] = { + {black, white, black, black, white, black,}, + {black, white, black, black, black, black}, + {black, white, black, black, white, black,}, + {black, black, black, black, white, black,} + }; + + w = int(floor(mod(coord.y, 4.0))); + z = int(floor(mod(coord.x, 6.0))); + + // use the indexes to find which color to apply to the current pixel + weights = slotmask[w][z]; + return weights; + } + + else if(phosphor_layout == 13){ + // based on MajorPainInTheCactus' HDR slot mask + vec3 slot[4][8] = { + {red, green, blue, black, red, green, blue, black}, + {red, green, blue, black, black, black, black, black}, + {red, green, blue, black, red, green, blue, black}, + {black, black, black, black, red, green, blue, black} + }; + + w = int(floor(mod(coord.y, 4.0))); + z = int(floor(mod(coord.x, 8.0))); + + weights = slot[w][z]; + return weights; + } + + else if(phosphor_layout == 14){ + // same as above but for RGB panels + vec3 slot2[4][10] = { + {red, yellow, green, blue, blue, red, yellow, green, blue, blue }, + {black, green, green, blue, blue, red, red, black, black, black}, + {red, yellow, green, blue, blue, red, yellow, green, blue, blue }, + {red, red, black, black, black, black, green, green, blue, blue } + }; + + w = int(floor(mod(coord.y, 4.0))); + z = int(floor(mod(coord.x, 10.0))); + + weights = slot2[w][z]; + return weights; + } + + else if(phosphor_layout == 15){ + // slot_3_7x6_rgb + vec3 slot[6][14] = { + {red, red, yellow, green, cyan, blue, blue, red, red, yellow, green, cyan, blue, blue}, + {red, red, yellow, green, cyan, blue, blue, red, red, yellow, green, cyan, blue, blue}, + {red, red, yellow, green, cyan, blue, blue, black, black, black, black, black, black, black}, + {red, red, yellow, green, cyan, blue, blue, red, red, yellow, green, cyan, blue, blue}, + {red, red, yellow, green, cyan, blue, blue, red, red, yellow, green, cyan, blue, blue}, + {black, black, black, black, black, black, black, black, red, red, yellow, green, cyan, blue} + }; + + w = int(floor(mod(coord.y, 6.0))); + z = int(floor(mod(coord.x, 14.0))); + + weights = slot[w][z]; + return weights; + } + + + + else return weights; +} + + + + +#define pi 3.1415926535897932384626433832795 +#define wa (0.5*pi) +#define wb (pi) + +vec3 resampler3(vec3 x) +{ + vec3 res; + + res.x = (x.x<=0.001) ? 1.0 : sin(x.x*wa)*sin(x.x*wb)/(wa*wb*x.x*x.x); + res.y = (x.y<=0.001) ? 1.0 : sin(x.y*wa)*sin(x.y*wb)/(wa*wb*x.y*x.y); + res.z = (x.z<=0.001) ? 1.0 : sin(x.z*wa)*sin(x.z*wb)/(wa*wb*x.z*x.z); + + return res; +} + +vec3 get_scanlines(vec3 d0, vec3 d1, vec3 color0, vec3 color1) +{ + if (SCANLINES_SHAPE > 0.5) { + d0 = exp(-16.0*d0*d0); + d1 = exp(-16.0*d1*d1); + } + else { + d0 = clamp(2.0*d0, 0.0, 1.0); + d1 = clamp(2.0*d1, 0.0, 1.0); + d0 = resampler3(d0); + d1 = resampler3(d1); + } + + return (color0*d0+color1*d1); +} + +void main() +{ + vec2 texture_size = params.SourceSize.xy; + + vec3 color; + vec2 dy = vec2(0.0, 1.0/texture_size.y); + + vec2 WarpedTexCoord = vTexCoord.xy; + + WarpedTexCoord = (CURVATURE > 0.5) ? Warp(WarpedTexCoord) : WarpedTexCoord; + + vec2 pix_coord = WarpedTexCoord.xy*texture_size + vec2(0.0, -0.5); + + vec2 tc = (floor(pix_coord)+vec2(0.5,0.5))/texture_size; + + vec2 fp = fract(pix_coord); + + vec3 color0 = texture(Source, tc ).xyz; + vec3 color1 = texture(Source, tc + dy).xyz; + + float pos0 = fp.y; + float pos1 = 1 - fp.y; + + vec3 lum0 = mix(vec3(BEAM_MIN_WIDTH), vec3(BEAM_MAX_WIDTH), color0); + vec3 lum1 = mix(vec3(BEAM_MIN_WIDTH), vec3(BEAM_MAX_WIDTH), color1); + + vec3 d0 = SCANLINES_STRENGTH*pos0/(lum0*lum0+0.0000001); + vec3 d1 = SCANLINES_STRENGTH*pos1/(lum1*lum1+0.0000001); + + color = BRIGHTBOOST*get_scanlines(d0, d1, color0, color1); + + color = GAMMA_OUT(color); + + vec2 mask_coords =vTexCoord.xy * params.OutputSize.xy; + + color.rgb*=GAMMA_OUT(mask_weights(mask_coords, params.MASK_INTENSITY, int(params.PHOSPHOR_LAYOUT), params.MONITOR_SUBPIXELS)); + + FragColor = vec4(POST_BRIGHTNESS*color, 1.0); + + FragColor *= (CURVATURE > 0.5) ? corner(WarpedTexCoord) : 1.0; +} diff --git a/crt/shaders/hyllian/crt-hyllian-sinc-curvature.slang b/crt/shaders/hyllian/crt-hyllian-sinc-curvature.slang deleted file mode 100644 index 7b6d3ec1..00000000 --- a/crt/shaders/hyllian/crt-hyllian-sinc-curvature.slang +++ /dev/null @@ -1,260 +0,0 @@ -#version 450 - -layout(push_constant) uniform Push -{ - float BEAM_MIN_WIDTH; - float BEAM_MAX_WIDTH; - float SCANLINES_STRENGTH; - float COLOR_BOOST; - float SHARPNESS_HACK; - float PHOSPHOR_LAYOUT; - float MASK_INTENSITY; - float InputGamma; - float OutputGamma; - float VSCANLINES; - float CRT_ANTI_RINGING; - float CRT_CURVATURE; - float CRT_warpX; - float CRT_warpY; - float CRT_cornersize; - float CRT_cornersmooth; -} param; - -#pragma parameter CRT_HYLLIAN_SINC "[CRT-HYLLIAN-SINC PARAMS]" 0.0 0.0 0.0 0.0 -#pragma parameter BEAM_MIN_WIDTH " MIN BEAM WIDTH" 0.92 0.0 1.0 0.01 -#pragma parameter BEAM_MAX_WIDTH " MAX BEAM WIDTH" 1.0 0.0 1.0 0.01 -#pragma parameter SCANLINES_STRENGTH " SCANLINES STRENGTH" 0.72 0.0 1.0 0.01 -#pragma parameter COLOR_BOOST " COLOR BOOST" 1.60 1.0 2.0 0.05 -#pragma parameter SHARPNESS_HACK " SHARPNESS_HACK" 1.0 1.0 4.0 1.0 -#pragma parameter PHOSPHOR_LAYOUT " PHOSPHOR LAYOUT" 4.0 0.0 24.0 1.0 -#pragma parameter MASK_INTENSITY " MASK INTENSITY" 0.7 0.0 1.0 0.1 -#pragma parameter InputGamma " INPUT GAMMA" 2.4 0.0 5.0 0.1 -#pragma parameter OutputGamma " OUTPUT GAMMA" 2.2 0.0 5.0 0.1 -#pragma parameter VSCANLINES " SCANLINES DIRECTION" 0.0 0.0 1.0 1.0 -#pragma parameter CRT_CURVATURE "CRT-Curvature" 1.0 0.0 1.0 1.0 -#pragma parameter CRT_warpX "CRT-Curvature X-Axis" 0.015 0.0 0.125 0.005 -#pragma parameter CRT_warpY "CRT-Curvature Y-Axis" 0.015 0.0 0.125 0.005 -vec2 CRT_Distortion = vec2(param.CRT_warpX, param.CRT_warpY) * 15.; -#pragma parameter CRT_cornersize "CRT-Corner Size" 0.01 0.001 1.0 0.005 -#define cornersize param.CRT_cornersize -#pragma parameter CRT_cornersmooth "CRT-Corner Smoothness" 380.0 80.0 2080.0 100.0 -#define cornersmooth param.CRT_cornersmooth - - -#pragma parameter CRT_ANTI_RINGING "CRT Anti-Ringing [ OFF | ON ]" 1.0 0.0 1.0 1.0 - -#define CRT_ANTI_RINGING param.CRT_ANTI_RINGING - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; - vec4 OutputSize; - vec4 OriginalSize; - vec4 SourceSize; -} global; - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 1) in vec2 FragCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; - -/* - Hyllian's CRT Shader - Sinc/Spline16 version - - Copyright (C) 2011-2022 Hyllian - sergiogdb@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#include "../../../include/subpixel_masks.h" - -#define GAMMA_IN(color) pow(color, vec3(param.InputGamma, param.InputGamma, param.InputGamma)) -#define GAMMA_OUT(color) pow(color, vec3(1.0 / param.OutputGamma, 1.0 / param.OutputGamma, 1.0 / param.OutputGamma)) - -#define scanlines_strength (2.0*param.SCANLINES_STRENGTH) -#define beam_min_width param.BEAM_MIN_WIDTH -#define beam_max_width param.BEAM_MAX_WIDTH -#define color_boost param.COLOR_BOOST - -#define pi 3.1415926535897932384626433832795 -#define wa (0.5*pi) -#define wb (pi) - -const vec2 corner_aspect = vec2(1.0, 0.75); - -float corner(vec2 coord) -{ - coord = (coord - vec2(0.5)) + vec2(0.5, 0.5); - coord = min(coord, vec2(1.0) - coord) * corner_aspect; - vec2 cdist = vec2(cornersize); - coord = (cdist - min(coord, cdist)); - float dist = sqrt(dot(coord, coord)); - - return clamp((cdist.x - dist)*cornersmooth, 0.0, 1.0); -} - - -vec2 Warp(vec2 texCoord){ - - vec2 curvedCoords = texCoord * 2.0 - 1.0; - float curvedCoordsDistance = sqrt(curvedCoords.x*curvedCoords.x+curvedCoords.y*curvedCoords.y); - - curvedCoords = curvedCoords / curvedCoordsDistance; - - curvedCoords = curvedCoords * (1.0-pow(vec2(1.0-(curvedCoordsDistance/1.4142135623730950488016887242097)),(1.0/(1.0+CRT_Distortion*0.2)))); - - curvedCoords = curvedCoords / (1.0-pow(vec2(0.29289321881345247559915563789515),(1.0/(vec2(1.0)+CRT_Distortion*0.2)))); - - curvedCoords = curvedCoords * 0.5 + 0.5; - return curvedCoords; -} - -float weight(float x) -{ - x = abs(x); - - if (x < 1.0) - { - return - ( - ((x - 9.0 / 5.0) * x - 1.0 / 5.0 ) * x + 1.0 - ); - } - else if ((x >= 1.0) && (x < 2.0)) - { - return - ( - (( -1.0 / 3.0 * (x - 1) + 4.0 / 5.0 ) * (x - 1) - 7.0 / 15.0 ) * (x - 1) - ); - } - else - { - return 0.0; - } -} - -vec4 weight4(float x) -{ - return vec4( - weight(x - 2.0), - weight(x - 1.0), - weight(x), - weight(x + 1.0) - ); -} - - -vec3 resampler3(vec3 x) -{ - vec3 res; - res.x = (x.x<=0.001) ? wa*wb : sin(x.x*wa)*sin(x.x*wb)/(x.x*x.x); - res.y = (x.y<=0.001) ? wa*wb : sin(x.y*wa)*sin(x.y*wb)/(x.y*x.y); - res.z = (x.z<=0.001) ? wa*wb : sin(x.z*wa)*sin(x.z*wb)/(x.z*x.z); - return res; -} - -void main() -{ - vec2 TextureSize = mix(vec2(global.SourceSize.x * param.SHARPNESS_HACK, global.SourceSize.y), vec2(global.SourceSize.x, global.SourceSize.y * param.SHARPNESS_HACK), param.VSCANLINES); - - vec2 dx = mix(vec2(1.0/TextureSize.x, 0.0), vec2(0.0, 1.0/TextureSize.y), param.VSCANLINES); - vec2 dy = mix(vec2(0.0, 1.0/TextureSize.y), vec2(1.0/TextureSize.x, 0.0), param.VSCANLINES); - - vec2 pp = vTexCoord.xy; - pp = (param.CRT_CURVATURE > 0.5) ? Warp(pp) : pp; - - vec2 pix_coord = pp.xy*TextureSize + vec2(-0.5, 0.5); - - vec2 tc = mix((floor(pix_coord) + vec2(0.5, 0.5))/TextureSize, (floor(pix_coord) + vec2(1.5, -0.5))/TextureSize, param.VSCANLINES); - - vec2 fp = mix(fract(pix_coord), fract(pix_coord.yx), param.VSCANLINES); - - vec3 c00 = GAMMA_IN(texture(Source, tc - dx - dy).xyz); - vec3 c01 = GAMMA_IN(texture(Source, tc - dy).xyz); - vec3 c02 = GAMMA_IN(texture(Source, tc + dx - dy).xyz); - vec3 c03 = GAMMA_IN(texture(Source, tc + 2.0*dx - dy).xyz); - vec3 c10 = GAMMA_IN(texture(Source, tc - dx ).xyz); - vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); - vec3 c12 = GAMMA_IN(texture(Source, tc + dx ).xyz); - vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx ).xyz); - - mat4x3 color_matrix0 = mat4x3(c00, c01, c02, c03); - mat4x3 color_matrix1 = mat4x3(c10, c11, c12, c13); - - // Get weights for spline16 horizontal filter - vec4 weights = weight4(1.0 - fp.x); - - // Spline16 horizontal filter - vec3 color0 = (color_matrix0 * weights)/dot(weights, vec4(1.0)); - vec3 color1 = (color_matrix1 * weights)/dot(weights, vec4(1.0)); - - // Get min/max samples - vec3 min_sample0 = min(c01,c02); - vec3 max_sample0 = max(c01,c02); - vec3 min_sample1 = min(c11,c12); - vec3 max_sample1 = max(c11,c12); - - // Anti-ringing - vec3 aux = color0; - color0 = clamp(color0, min_sample0, max_sample0); - color0 = mix(aux, color0, CRT_ANTI_RINGING * step(0.0, (c00-c01)*(c02-c03))); - aux = color1; - color1 = clamp(color1, min_sample1, max_sample1); - color1 = mix(aux, color1, CRT_ANTI_RINGING * step(0.0, (c10-c11)*(c12-c13))); - - // Apply scanlines. Sinc filter vertically. - float pos0 = fp.y; - float pos1 = 1 - fp.y; - - vec3 lum0 = mix(vec3(beam_min_width), vec3(beam_max_width), color0); - vec3 lum1 = mix(vec3(beam_min_width), vec3(beam_max_width), color1); - - vec3 d0 = clamp(scanlines_strength*pos0/(lum0*lum0+0.0000001), 0.0, 1.0); - vec3 d1 = clamp(scanlines_strength*pos1/(lum1*lum1+0.0000001), 0.0, 1.0); - - d0 = resampler3(d0); - d1 = resampler3(d1); - - // Apply color enhancement, scanlines orientation, mask and gamma. - vec3 color = color_boost*(color0*d0+color1*d1)/(wa*wb); - - vec2 mask_coords = vTexCoord.xy * global.OutputSize.xy; - - mask_coords = mix(mask_coords.xy, mask_coords.yx, param.VSCANLINES); - - color.rgb*=mask_weights(mask_coords, param.MASK_INTENSITY, int(param.PHOSPHOR_LAYOUT)); - - color = GAMMA_OUT(color); - - FragColor = vec4(color, 1.0); - - FragColor *= (param.CRT_CURVATURE > 0.5) ? corner(pp) : 1.0; -} diff --git a/crt/shaders/hyllian/crt-hyllian-sinc-pass0.slang b/crt/shaders/hyllian/crt-hyllian-sinc-pass0.slang new file mode 100644 index 00000000..3ea00b3d --- /dev/null +++ b/crt/shaders/hyllian/crt-hyllian-sinc-pass0.slang @@ -0,0 +1,208 @@ +#version 450 + +/* + Hyllian's CRT-sinc Shader + + Copyright (C) 2011-2024 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +layout(push_constant) uniform Push +{ + float HFILTER_PROFILE; + float SHARPNESS_HACK; + float SHP; + float RADIUS; + float CRT_ANTI_RINGING; + float CRT_InputGamma; + float CURVATURE; + float WARP_X; + float WARP_Y; +} params; + +#pragma parameter HFILTER_PROFILE "H-FILTER [ Custom | Composite1 | Composite2 ]" 0.0 0.0 2.0 1.0 +#pragma parameter SHP " CUSTOM H-FILTER SHARPNESS" 1.0 0.50 1.0 0.01 +#pragma parameter RADIUS " CUSTOM H-FILTER RADIUS" 4.0 2.0 4.0 0.1 +#pragma parameter CRT_ANTI_RINGING "ANTI RINGING" 1.0 0.0 1.0 0.1 +#pragma parameter SHARPNESS_HACK "SHARPNESS HACK" 1.0 1.0 4.0 1.0 +#pragma parameter CRT_InputGamma "INPUT GAMMA" 2.4 1.0 5.0 0.1 +#pragma parameter CRT_OutputGamma "OUTPUT GAMMA" 2.2 1.0 5.0 0.05 +#pragma parameter PHOSPHOR_LAYOUT "PHOSPHOR LAYOUT [1-6 Aperture, 7-10 Shadow, 11-14 Slot]" 1.0 0.0 15.0 1.0 +#pragma parameter MASK_INTENSITY "MASK INTENSITY" 0.65 0.0 1.0 0.01 +#pragma parameter MONITOR_SUBPIXELS "MONITOR SUBPIXELS LAYOUT [0=RGB, 1=BGR]" 0.0 0.0 1.0 1.0 +#pragma parameter BRIGHTBOOST "BRIGHTNESS BOOST" 1.40 1.0 3.0 0.05 +#pragma parameter BEAM_MIN_WIDTH "MIN BEAM WIDTH" 0.86 0.0 1.0 0.02 +#pragma parameter BEAM_MAX_WIDTH "MAX BEAM WIDTH" 1.0 0.0 1.0 0.02 +#pragma parameter SCANLINES_STRENGTH "SCANLINES STRENGTH" 0.72 0.0 1.0 0.01 +#pragma parameter SCANLINES_SHAPE "SCANLINES SHAPE (SINC | GAUSSIAN)" 0.0 0.0 1.0 1.0 +#pragma parameter POST_BRIGHTNESS "POST-BRIGHTNESS" 1.00 1.0 3.0 0.05 +#pragma parameter CURVATURE "ENABLE CURVATURE" 0.0 0.0 1.0 1.0 +#pragma parameter WARP_X " CURVATURE-X" 0.015 0.0 0.125 0.005 +#pragma parameter WARP_Y " CURVATURE-Y" 0.015 0.0 0.125 0.005 +#pragma parameter CORNER_SIZE " CORNER SIZE" 0.02 0.001 1.0 0.005 +#pragma parameter CORNER_SMOOTHNESS " CORNER SMOOTHNESS" 1.10 1.0 2.2 0.02 + +#define HFILTER_PROFILE params.HFILTER_PROFILE +#define SHP params.SHP +#define RADIUS params.RADIUS +#define CRT_ANTI_RINGING params.CRT_ANTI_RINGING +#define SHARPNESS_HACK params.SHARPNESS_HACK +#define CRT_InputGamma params.CRT_InputGamma +#define CURVATURE params.CURVATURE +#define WARP_X params.WARP_X +#define WARP_Y params.WARP_Y + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} global; + + +#define GAMMA_IN(color) pow(color, vec3(CRT_InputGamma, CRT_InputGamma, CRT_InputGamma)) + +#define pi 3.1415926535897932384626433832795 + +#define AR_MOD 3.0 + + +/* Curvature code. Credits to torridgristle! */ +vec2 CRT_Distortion = vec2(WARP_X, 0.0) * 15.; + +#define SQRT_OF_2 1.4142135623730950488016887242097 + +// Radius of Convergence = 1.0 - SQRT_OF_2 / 2 + +#define CONVERGENCE_RADIUS 0.29289321881345247559915563789515 + +vec2 Warp(vec2 texCoord) +{ + vec2 cCoords = texCoord * 2.0 - 1.0; + float cCoordsDist = sqrt(cCoords.x * cCoords.x + cCoords.y * cCoords.y); + cCoords = cCoords / cCoordsDist; + cCoords = cCoords * (1.0 - pow(vec2(1.0 - (cCoordsDist/SQRT_OF_2)),(1.0/(1.0+CRT_Distortion*0.2)))); + cCoords = cCoords / (1.0-pow(vec2(CONVERGENCE_RADIUS),(1.0/(vec2(1.0)+CRT_Distortion*0.2)))); + cCoords = cCoords * 0.5 + 0.5; + + return cCoords; +} + + +vec2 get_hfilter_profile() +{ + vec2 hf_profile = vec2(SHP, RADIUS); + + if (HFILTER_PROFILE == 1.0) hf_profile = vec2(0.86, 4.0); + else if (HFILTER_PROFILE == 2.0) hf_profile = vec2(0.75, 4.0); + + return hf_profile; +} + +/* Some window functions for tests. */ +vec4 sinc(vec4 x) { return sin(pi*x)/(pi*x+0.00001); } +vec4 hann_window(vec4 x) { return 0.5 * ( 1.0 - cos( 0.5 * pi * ( x + 2.0 ) ) ); } +vec4 blackman_window(vec4 x) { return 0.42 - 0.5*cos(0.5*pi*(x+2.0)) + 0.08*cos(pi*(x+2.0)); } +vec4 lanczos(vec4 x, float a) { return sinc(x) * sinc(x / a); } +vec4 blackman(vec4 x, float a) { return sinc(x) * blackman_window(x); } +vec4 hann(vec4 x, float a) { return sinc(x) * hann_window(x); } + +vec4 resampler4(vec4 x, vec2 hfp) +{ + return lanczos(x * hfp.x, hfp.y); +} + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord * 1.0001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 FragCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ + vec3 color; + + vec2 texture_size = vec2(SHARPNESS_HACK*global.SourceSize.x, global.SourceSize.y); + + vec2 dx = vec2(1.0/texture_size.x, 0.0); + + vec2 WarpedTexCoord = vTexCoord.xy; + + WarpedTexCoord = (CURVATURE > 0.5) ? Warp(WarpedTexCoord) : WarpedTexCoord; + + vec2 pix_coord = WarpedTexCoord.xy*texture_size + vec2(-0.5, 0.0); + + vec2 tc = (floor(pix_coord) + vec2(0.5,0.5))/texture_size; + + vec2 fp = fract(pix_coord); + + vec3 c0 = GAMMA_IN(texture(Source, tc - 3.0*dx).xyz); + vec3 c1 = GAMMA_IN(texture(Source, tc - 2.0*dx).xyz); + vec3 c2 = GAMMA_IN(texture(Source, tc - dx).xyz); + vec3 c3 = GAMMA_IN(texture(Source, tc ).xyz); + vec3 c4 = GAMMA_IN(texture(Source, tc + dx).xyz); + vec3 c5 = GAMMA_IN(texture(Source, tc + 2.0*dx).xyz); + vec3 c6 = GAMMA_IN(texture(Source, tc + 3.0*dx).xyz); + vec3 c7 = GAMMA_IN(texture(Source, tc + 4.0*dx).xyz); + + // Anti-ringing pre filtering + vec3 min_sample = min(min(c2,c3),min(c4,c5)); + vec3 max_sample = max(max(c2,c3),max(c4,c5)); + + vec3 mins = (1.0/AR_MOD) * min_sample; + vec3 maxs = AR_MOD * max_sample; + + c0 = clamp(c0, mins, maxs); + c1 = clamp(c1, mins, maxs); + c6 = clamp(c6, mins, maxs); + c7 = clamp(c7, mins, maxs); + + mat4x3 color_matrix0 = mat4x3(c0, c1, c2, c3); + mat4x3 color_matrix1 = mat4x3(c4, c5, c6, c7); + + vec2 hfp = get_hfilter_profile(); + + vec4 wgt0 = resampler4(vec4(3.0+fp.x, 2.0+fp.x, 1.0+fp.x, fp.x), hfp); + vec4 wgt1 = resampler4(vec4(1.0-fp.x, 2.0-fp.x, 3.0-fp.x, 4.0-fp.x), hfp); + + float wgt_sum = (dot(wgt0, vec4(1.0))+dot(wgt1, vec4(1.0))); + + wgt0 /= wgt_sum; + wgt1 /= wgt_sum; + + color = color_matrix0 * wgt0 + color_matrix1 * wgt1; + + // Anti-ringing post filtering + color = mix(color, clamp(color, min_sample, max_sample), CRT_ANTI_RINGING); + + FragColor = vec4(color, 1.0); +} diff --git a/crt/shaders/hyllian/crt-hyllian-sinc.slang b/crt/shaders/hyllian/crt-hyllian-sinc.slang deleted file mode 100644 index adc3e785..00000000 --- a/crt/shaders/hyllian/crt-hyllian-sinc.slang +++ /dev/null @@ -1,214 +0,0 @@ -#version 450 - -layout(push_constant) uniform Push -{ - float BEAM_MIN_WIDTH; - float BEAM_MAX_WIDTH; - float SCANLINES_STRENGTH; - float COLOR_BOOST; - float SHARPNESS_HACK; - float PHOSPHOR_LAYOUT; - float MASK_INTENSITY; - float InputGamma; - float OutputGamma; - float VSCANLINES; - float CRT_ANTI_RINGING; -} param; - -#pragma parameter CRT_HYLLIAN_SINC "[CRT-HYLLIAN-SINC PARAMS]" 0.0 0.0 0.0 0.0 -#pragma parameter BEAM_MIN_WIDTH " MIN BEAM WIDTH" 0.92 0.0 1.0 0.01 -#pragma parameter BEAM_MAX_WIDTH " MAX BEAM WIDTH" 1.0 0.0 1.0 0.01 -#pragma parameter SCANLINES_STRENGTH " SCANLINES STRENGTH" 0.72 0.0 1.0 0.01 -#pragma parameter COLOR_BOOST " COLOR BOOST" 1.60 1.0 2.0 0.05 -#pragma parameter SHARPNESS_HACK " SHARPNESS_HACK" 1.0 1.0 4.0 1.0 -#pragma parameter PHOSPHOR_LAYOUT " PHOSPHOR LAYOUT" 4.0 0.0 24.0 1.0 -#pragma parameter MASK_INTENSITY " MASK INTENSITY" 0.7 0.0 1.0 0.1 -#pragma parameter InputGamma " INPUT GAMMA" 2.4 0.0 5.0 0.1 -#pragma parameter OutputGamma " OUTPUT GAMMA" 2.2 0.0 5.0 0.1 -#pragma parameter VSCANLINES " SCANLINES DIRECTION" 0.0 0.0 1.0 1.0 - -#pragma parameter CRT_ANTI_RINGING "Spline16 Anti-Ringing [ OFF | ON ]" 0.0 0.0 1.0 1.0 - -#define CRT_ANTI_RINGING param.CRT_ANTI_RINGING - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; - vec4 OutputSize; - vec4 OriginalSize; - vec4 SourceSize; -} global; - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 1) in vec2 FragCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; - -/* - Hyllian's CRT Shader - Sinc/Spline16 version - - Copyright (C) 2011-2022 Hyllian - sergiogdb@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#include "../../../include/subpixel_masks.h" - -#define GAMMA_IN(color) pow(color, vec3(param.InputGamma, param.InputGamma, param.InputGamma)) -#define GAMMA_OUT(color) pow(color, vec3(1.0 / param.OutputGamma, 1.0 / param.OutputGamma, 1.0 / param.OutputGamma)) - -#define scanlines_strength (2.0*param.SCANLINES_STRENGTH) -#define beam_min_width param.BEAM_MIN_WIDTH -#define beam_max_width param.BEAM_MAX_WIDTH -#define color_boost param.COLOR_BOOST - -#define pi 3.1415926535897932384626433832795 -#define wa (0.5*pi) -#define wb (pi) - -//#define CRT_ANTI_RINGING 1.0 - -float weight(float x) -{ - x = abs(x); - - if (x < 1.0) - { - return - ( - ((x - 9.0 / 5.0) * x - 1.0 / 5.0 ) * x + 1.0 - ); - } - else if ((x >= 1.0) && (x < 2.0)) - { - return - ( - (( -1.0 / 3.0 * (x - 1) + 4.0 / 5.0 ) * (x - 1) - 7.0 / 15.0 ) * (x - 1) - ); - } - else - { - return 0.0; - } -} - -vec4 weight4(float x) -{ - return vec4( - weight(x - 2.0), - weight(x - 1.0), - weight(x), - weight(x + 1.0) - ); -} - - -vec3 resampler3(vec3 x) -{ - vec3 res; - res.x = (x.x<=0.001) ? wa*wb : sin(x.x*wa)*sin(x.x*wb)/(x.x*x.x); - res.y = (x.y<=0.001) ? wa*wb : sin(x.y*wa)*sin(x.y*wb)/(x.y*x.y); - res.z = (x.z<=0.001) ? wa*wb : sin(x.z*wa)*sin(x.z*wb)/(x.z*x.z); - return res; -} - -void main() -{ - vec2 TextureSize = mix(vec2(global.SourceSize.x * param.SHARPNESS_HACK, global.SourceSize.y), vec2(global.SourceSize.x, global.SourceSize.y * param.SHARPNESS_HACK), param.VSCANLINES); - - vec2 dx = mix(vec2(1.0/TextureSize.x, 0.0), vec2(0.0, 1.0/TextureSize.y), param.VSCANLINES); - vec2 dy = mix(vec2(0.0, 1.0/TextureSize.y), vec2(1.0/TextureSize.x, 0.0), param.VSCANLINES); - - vec2 pix_coord = vTexCoord*TextureSize + vec2(-0.5, 0.5); - - vec2 tc = mix((floor(pix_coord) + vec2(0.5, 0.5))/TextureSize, (floor(pix_coord) + vec2(1.5, -0.5))/TextureSize, param.VSCANLINES); - - vec2 fp = mix(fract(pix_coord), fract(pix_coord.yx), param.VSCANLINES); - - vec3 c00 = GAMMA_IN(texture(Source, tc - dx - dy).xyz); - vec3 c01 = GAMMA_IN(texture(Source, tc - dy).xyz); - vec3 c02 = GAMMA_IN(texture(Source, tc + dx - dy).xyz); - vec3 c03 = GAMMA_IN(texture(Source, tc + 2.0*dx - dy).xyz); - vec3 c10 = GAMMA_IN(texture(Source, tc - dx ).xyz); - vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); - vec3 c12 = GAMMA_IN(texture(Source, tc + dx ).xyz); - vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx ).xyz); - - mat4x3 color_matrix0 = mat4x3(c00, c01, c02, c03); - mat4x3 color_matrix1 = mat4x3(c10, c11, c12, c13); - - // Get weights for spline16 horizontal filter - vec4 weights = weight4(1.0 - fp.x); - - // Spline16 horizontal filter - vec3 color0 = (color_matrix0 * weights)/dot(weights, vec4(1.0)); - vec3 color1 = (color_matrix1 * weights)/dot(weights, vec4(1.0)); - - // Get min/max samples - vec3 min_sample0 = min(c01,c02); - vec3 max_sample0 = max(c01,c02); - vec3 min_sample1 = min(c11,c12); - vec3 max_sample1 = max(c11,c12); - - // Anti-ringing - vec3 aux = color0; - color0 = clamp(color0, min_sample0, max_sample0); - color0 = mix(aux, color0, CRT_ANTI_RINGING * step(0.0, (c00-c01)*(c02-c03))); - aux = color1; - color1 = clamp(color1, min_sample1, max_sample1); - color1 = mix(aux, color1, CRT_ANTI_RINGING * step(0.0, (c10-c11)*(c12-c13))); - - // Apply scanlines. Sinc filter vertically. - float pos0 = fp.y; - float pos1 = 1 - fp.y; - - vec3 lum0 = mix(vec3(beam_min_width), vec3(beam_max_width), color0); - vec3 lum1 = mix(vec3(beam_min_width), vec3(beam_max_width), color1); - - vec3 d0 = clamp(scanlines_strength*pos0/(lum0*lum0+0.0000001), 0.0, 1.0); - vec3 d1 = clamp(scanlines_strength*pos1/(lum1*lum1+0.0000001), 0.0, 1.0); - - d0 = resampler3(d0); - d1 = resampler3(d1); - - // Apply color enhancement, scanlines orientation, mask and gamma. - vec3 color = color_boost*(color0*d0+color1*d1)/(wa*wb); - - vec2 mask_coords = vTexCoord.xy * global.OutputSize.xy; - - mask_coords = mix(mask_coords.xy, mask_coords.yx, param.VSCANLINES); - - color.rgb*=mask_weights(mask_coords, param.MASK_INTENSITY, int(param.PHOSPHOR_LAYOUT)); - - color = GAMMA_OUT(color); - - FragColor = vec4(color, 1.0); -} diff --git a/crt/shaders/hyllian/crt-hyllian.slang b/crt/shaders/hyllian/crt-hyllian.slang deleted file mode 100644 index c185d202..00000000 --- a/crt/shaders/hyllian/crt-hyllian.slang +++ /dev/null @@ -1,207 +0,0 @@ -#version 450 - -layout(push_constant) uniform Push -{ - float BEAM_PROFILE; - float HFILTER_PROFILE; - float BEAM_MIN_WIDTH; - float BEAM_MAX_WIDTH; - float SCANLINES_STRENGTH; - float COLOR_BOOST; - float SHARPNESS_HACK; - float PHOSPHOR_LAYOUT; - float MASK_INTENSITY; - float CRT_ANTI_RINGING; - float InputGamma; - float OutputGamma; - float VSCANLINES; -} param; - -#pragma parameter CRT_HYLLIAN "[CRT-HYLLIAN PARAMS]" 0.0 0.0 0.0 0.0 -#pragma parameter BEAM_PROFILE " BEAM PROFILE (BP)" 0.0 0.0 2.0 1.0 -#pragma parameter HFILTER_PROFILE " HORIZONTAL FILTER PROFILE [ HERMITE | CATMULL-ROM ]" 0.0 0.0 1.0 1.0 -#pragma parameter BEAM_MIN_WIDTH " Custom [If BP=0.00] MIN BEAM WIDTH" 1.0 0.0 1.0 0.01 -#pragma parameter BEAM_MAX_WIDTH " Custom [If BP=0.00] MAX BEAM WIDTH" 1.0 0.0 1.0 0.01 -#pragma parameter SCANLINES_STRENGTH " Custom [If BP=0.00] SCANLINES STRENGTH" 0.58 0.0 1.0 0.01 -#pragma parameter COLOR_BOOST " Custom [If BP=0.00] COLOR BOOST" 1.30 1.0 2.0 0.05 -#pragma parameter SHARPNESS_HACK " SHARPNESS_HACK" 1.0 1.0 4.0 1.0 -#pragma parameter PHOSPHOR_LAYOUT " PHOSPHOR LAYOUT" 4.0 0.0 24.0 1.0 -#pragma parameter MASK_INTENSITY " MASK INTENSITY" 0.7 0.0 1.0 0.1 -#pragma parameter CRT_ANTI_RINGING " ANTI RINGING" 1.0 0.0 1.0 0.2 -#pragma parameter InputGamma " INPUT GAMMA" 2.4 0.0 5.0 0.1 -#pragma parameter OutputGamma " OUTPUT GAMMA" 2.2 0.0 5.0 0.1 -#pragma parameter VSCANLINES " VERTICAL SCANLINES [ OFF | ON ]" 0.0 0.0 1.0 1.0 - - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; - vec4 OutputSize; - vec4 OriginalSize; - vec4 SourceSize; -} global; - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord * 1.0001; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 1) in vec2 FragCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; - -/* - Hyllian's CRT Shader - - Copyright (C) 2011-2022 Hyllian - sergiogdb@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#include "../../../include/subpixel_masks.h" - -#define GAMMA_IN(color) pow(color, vec3(param.InputGamma, param.InputGamma, param.InputGamma)) -#define GAMMA_OUT(color) pow(color, vec3(1.0 / param.OutputGamma, 1.0 / param.OutputGamma, 1.0 / param.OutputGamma)) - - - - -// Horizontal cubic filter. -// Some known filters use these values: - -// B = 0.0, C = 0.0 => Hermite cubic filter. -// B = 1.0, C = 0.0 => Cubic B-Spline filter. -// B = 0.0, C = 0.5 => Catmull-Rom Spline filter. This is the default used in this shader. -// B = C = 1.0/3.0 => Mitchell-Netravali cubic filter. -// B = 0.3782, C = 0.3109 => Robidoux filter. -// B = 0.2620, C = 0.3690 => Robidoux Sharp filter. - -// Using only Hermite and Catmull-Rom, as the others aren't useful for crt shader. -// For more info, see: http://www.imagemagick.org/Usage/img_diagrams/cubic_survey.gif -mat4x4 get_hfilter_profile() -{ - float bf = 0.0; - float cf = 0.0; - - if (param.HFILTER_PROFILE == 1) {bf = 0.0; cf = 0.5;} - - return mat4x4( (-bf - 6.0*cf)/6.0, (3.0*bf + 12.0*cf)/6.0, (-3.0*bf - 6.0*cf)/6.0, bf/6.0, - (12.0 - 9.0*bf - 6.0*cf)/6.0, (-18.0 + 12.0*bf + 6.0*cf)/6.0, 0.0, (6.0 - 2.0*bf)/6.0, - -(12.0 - 9.0*bf - 6.0*cf)/6.0, (18.0 - 15.0*bf - 12.0*cf)/6.0, (3.0*bf + 6.0*cf)/6.0, bf/6.0, - (bf + 6.0*cf)/6.0, -cf, 0.0, 0.0); - - -} - - -#define scanlines_strength (4.0*profile.x) -#define beam_min_width profile.y -#define beam_max_width profile.z -#define color_boost profile.w - -vec4 get_beam_profile() -{ - vec4 bp = vec4(param.SCANLINES_STRENGTH, param.BEAM_MIN_WIDTH, param.BEAM_MAX_WIDTH, param.COLOR_BOOST); - - if (param.BEAM_PROFILE == 1) bp = vec4(0.62, 1.00, 1.00, 1.40); // Catmull-rom - if (param.BEAM_PROFILE == 2) bp = vec4(0.72, 1.00, 1.00, 1.20); // Catmull-rom - - return bp; -} - - -void main() -{ - vec4 profile = get_beam_profile(); - - vec2 TextureSize = mix(vec2(global.SourceSize.x * param.SHARPNESS_HACK, global.SourceSize.y), vec2(global.SourceSize.x, global.SourceSize.y * param.SHARPNESS_HACK), param.VSCANLINES); - - vec2 dx = mix(vec2(1.0/TextureSize.x, 0.0), vec2(0.0, 1.0/TextureSize.y), param.VSCANLINES); - vec2 dy = mix(vec2(0.0, 1.0/TextureSize.y), vec2(1.0/TextureSize.x, 0.0), param.VSCANLINES); - - vec2 pix_coord = vTexCoord.xy*TextureSize + vec2(-0.5, 0.5); - - vec2 tc = mix((floor(pix_coord) + vec2(0.5, 0.5))/TextureSize, (floor(pix_coord) + vec2(1.5, -0.5))/TextureSize, param.VSCANLINES); - - vec2 fp = mix(fract(pix_coord), fract(pix_coord.yx), param.VSCANLINES); - - vec3 c00 = GAMMA_IN(texture(Source, tc - dx - dy).xyz); - vec3 c01 = GAMMA_IN(texture(Source, tc - dy).xyz); - vec3 c02 = GAMMA_IN(texture(Source, tc + dx - dy).xyz); - vec3 c03 = GAMMA_IN(texture(Source, tc + 2.0*dx - dy).xyz); - vec3 c10 = GAMMA_IN(texture(Source, tc - dx ).xyz); - vec3 c11 = GAMMA_IN(texture(Source, tc ).xyz); - vec3 c12 = GAMMA_IN(texture(Source, tc + dx ).xyz); - vec3 c13 = GAMMA_IN(texture(Source, tc + 2.0*dx ).xyz); - - mat4x4 invX = get_hfilter_profile(); - - mat4x3 color_matrix0 = mat4x3(c00, c01, c02, c03); - mat4x3 color_matrix1 = mat4x3(c10, c11, c12, c13); - - vec4 invX_Px = vec4(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0) * invX; - vec3 color0 = color_matrix0 * invX_Px; - vec3 color1 = color_matrix1 * invX_Px; - - // Get min/max samples - vec3 min_sample0 = min(c01,c02); - vec3 max_sample0 = max(c01,c02); - vec3 min_sample1 = min(c11,c12); - vec3 max_sample1 = max(c11,c12); - - // Anti-ringing - vec3 aux = color0; - color0 = clamp(color0, min_sample0, max_sample0); - color0 = mix(aux, color0, param.CRT_ANTI_RINGING * step(0.0, (c00-c01)*(c02-c03))); - aux = color1; - color1 = clamp(color1, min_sample1, max_sample1); - color1 = mix(aux, color1, param.CRT_ANTI_RINGING * step(0.0, (c10-c11)*(c12-c13))); - - float pos0 = fp.y; - float pos1 = 1 - fp.y; - - vec3 lum0 = mix(vec3(beam_min_width), vec3(beam_max_width), color0); - vec3 lum1 = mix(vec3(beam_min_width), vec3(beam_max_width), color1); - - vec3 d0 = scanlines_strength*pos0/(lum0*lum0+0.0000001); - vec3 d1 = scanlines_strength*pos1/(lum1*lum1+0.0000001); - - d0 = exp(-d0*d0); - d1 = exp(-d1*d1); - - vec3 color = color_boost*(color0*d0+color1*d1); - - vec2 mask_coords =vTexCoord.xy * global.OutputSize.xy; - - mask_coords = mix(mask_coords.xy, mask_coords.yx, param.VSCANLINES); - - color.rgb*=mask_weights(mask_coords, param.MASK_INTENSITY, int(param.PHOSPHOR_LAYOUT)); - - color = GAMMA_OUT(color); - - FragColor = vec4(color, 1.0); -} diff --git a/crt/shaders/hyllian/support/LUT/some-grade.png b/crt/shaders/hyllian/support/LUT/some-grade.png new file mode 100644 index 00000000..f149b62d Binary files /dev/null and b/crt/shaders/hyllian/support/LUT/some-grade.png differ diff --git a/crt/shaders/hyllian/support/delinearize.slang b/crt/shaders/hyllian/support/delinearize.slang new file mode 100644 index 00000000..bf3bc256 --- /dev/null +++ b/crt/shaders/hyllian/support/delinearize.slang @@ -0,0 +1,42 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float OutputGamma; +} params; + +#pragma parameter OutputGamma "OUTPUT GAMMA" 2.0 1.0 3.0 0.05 + +#define OutputGamma params.OutputGamma +#define GAMMA_OUT(color) pow(color, vec3(1.0 / OutputGamma, 1.0 / OutputGamma, 1.0 / OutputGamma)) + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ +// FragColor = pow(vec4(texture(Source, vTexCoord).rgb, 1.0), vec4(1.0 / 2.2)); + FragColor = vec4(GAMMA_OUT(texture(Source, vTexCoord).rgb), 1.0); +} diff --git a/crt/shaders/hyllian/support/linearize.slang b/crt/shaders/hyllian/support/linearize.slang new file mode 100644 index 00000000..cae8fab3 --- /dev/null +++ b/crt/shaders/hyllian/support/linearize.slang @@ -0,0 +1,43 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float InputGamma; +} params; + +#pragma parameter InputGamma "INPUT GAMMA" 2.0 1.0 3.0 0.05 + +#define InputGamma params.InputGamma + +#define GAMMA_IN(color) pow(color, vec3(InputGamma, InputGamma, InputGamma)) + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ +// FragColor = pow(vec4(texture(Source, vTexCoord).rgb, 1.0), vec4(2.2)); + FragColor = vec4(GAMMA_IN(texture(Source, vTexCoord).rgb), 1.0); +} diff --git a/crt/shaders/hyllian/support/multiLUT-modified.slang b/crt/shaders/hyllian/support/multiLUT-modified.slang new file mode 100644 index 00000000..9fb39a05 --- /dev/null +++ b/crt/shaders/hyllian/support/multiLUT-modified.slang @@ -0,0 +1,81 @@ +#version 450 + +// A version of the LUT shader that loads 2 LUTs. +// Can turn LUT off too. + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float LUT_selector_param; +} params; + +#pragma parameter LUT_selector_param "LUT [ Off | NTSC | Grade ]" 1.0 0.0 2.0 1.0 +int LUT_selector = int(params.LUT_selector_param); + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord * 1.0001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D SamplerLUT1; +layout(set = 0, binding = 4) uniform sampler2D SamplerLUT2; + +// This shouldn't be necessary but it seems some undefined values can +// creep in and each GPU vendor handles that differently. This keeps +// all values within a safe range +vec4 mixfix(vec4 a, vec4 b, float c) +{ + return (a.z < 1.0) ? mix(a, b, c) : a; +} + +void main() +{ + vec4 imgColor = texture(Source, vTexCoord.xy); + + if (LUT_selector == 0.0) { + FragColor = imgColor; + } + else { + + float LUT_Size = mix(textureSize(SamplerLUT1, 0).y, textureSize(SamplerLUT2, 0).y, params.LUT_selector_param - 1.0); + vec4 color1, color2 = vec4(0.,0.,0.,0.); + float red, green, blue1, blue2, mixer = 0.0; + + red = ( imgColor.r * (LUT_Size - 1.0) + 0.4999 ) / (LUT_Size * LUT_Size); + green = ( imgColor.g * (LUT_Size - 1.0) + 0.4999 ) / LUT_Size; + blue1 = (floor( imgColor.b * (LUT_Size - 1.0) ) / LUT_Size) + red; + blue2 = (ceil( imgColor.b * (LUT_Size - 1.0) ) / LUT_Size) + red; + mixer = clamp(max((imgColor.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0); + + if(LUT_selector == 1) + { + color1 = texture( SamplerLUT1, vec2( blue1, green )); + color2 = texture( SamplerLUT1, vec2( blue2, green )); + } + else + { + color1 = texture( SamplerLUT2, vec2( blue1, green )); + color2 = texture( SamplerLUT2, vec2( blue2, green )); + } + FragColor = mixfix(color1, color2, mixer); + } + +} diff --git a/crt/shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass1.slang b/crt/shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass1.slang new file mode 100644 index 00000000..3ad525af --- /dev/null +++ b/crt/shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass1.slang @@ -0,0 +1,133 @@ +#version 450 + +// NTSC-Adaptive-Lite - Faster for 2-Phase games (only 15 taps!) +// based on Themaister's NTSC shader + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; + uint FrameCount; + float quality, ntsc_sat, cust_fringing, cust_artifacting, ntsc_bright, ntsc_scale, ntsc_fields, ntsc_phase, ntsc_artifacting_rainbow; +} global; + +#pragma parameter quality "NTSC Preset (Svideo=0 Composite=1 RF=2 Custom=-1)" 1.0 -1.0 2.0 1.0 +#pragma parameter ntsc_fields "NTSC Merge Fields" 0.0 0.0 1.0 1.0 +#pragma parameter ntsc_phase "NTSC Phase: Auto | 2 phase | 3 phase" 1.0 1.0 3.0 1.0 +#pragma parameter ntsc_scale "NTSC Resolution Scaling" 1.0 0.20 3.0 0.05 +#pragma parameter ntsc_sat "NTSC Color Saturation" 1.0 0.0 2.0 0.01 +#pragma parameter ntsc_bright "NTSC Brightness" 1.0 0.0 1.5 0.01 +#pragma parameter cust_fringing "NTSC Custom Fringing Value" 0.0 0.0 5.0 0.1 +#pragma parameter cust_artifacting "NTSC Custom Artifacting Value" 0.0 0.0 5.0 0.1 +#pragma parameter ntsc_artifacting_rainbow "NTSC Artifacting Rainbow Effect" 0.0 -1.0 1.0 0.1 + +#define PI 3.14159265 + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out vec2 pix_no; +layout(location = 2) out float phase; +layout(location = 3) out float BRIGHTNESS; +layout(location = 4) out float SATURATION; +layout(location = 5) out float FRINGING; +layout(location = 6) out float ARTIFACTING; +layout(location = 7) out float CHROMA_MOD_FREQ; +layout(location = 8) out float MERGE; + +void main() +{ + float res = global.ntsc_scale; + float OriginalSize = global.OriginalSize.x; + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; + if (res < 1.0) pix_no = TexCoord * global.SourceSize.xy * (res * global.OutputSize.xy / global.SourceSize.xy); else + pix_no = TexCoord * global.SourceSize.xy * ( global.OutputSize.xy / global.SourceSize.xy); + phase = (global.ntsc_phase < 1.5) ? ((OriginalSize > 300.0) ? 2.0 : 3.0) : ((global.ntsc_phase > 2.5) ? 3.0 : 2.0); + + res = max(res, 1.0); + CHROMA_MOD_FREQ = (phase < 2.5) ? (4.0 * PI / 15.0) : (PI / 3.0); + ARTIFACTING = (global.quality > -0.5) ? global.quality * 0.5*(res+1.0) : global.cust_artifacting; + FRINGING = (global.quality > -0.5) ? global.quality : global.cust_fringing; + SATURATION = global.ntsc_sat; + BRIGHTNESS = global.ntsc_bright; + pix_no.x = pix_no.x * res; + + MERGE = (int(global.quality) == 2 || phase < 2.5) ? 0.0 : 1.0; + MERGE = (int(global.quality) == -1) ? global.ntsc_fields : MERGE; + +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 pix_no; +layout(location = 2) in float phase; +layout(location = 3) in float BRIGHTNESS; +layout(location = 4) in float SATURATION; +layout(location = 5) in float FRINGING; +layout(location = 6) in float ARTIFACTING; +layout(location = 7) in float CHROMA_MOD_FREQ; +layout(location = 8) in float MERGE; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +#define mix_mat mat3(BRIGHTNESS, FRINGING, FRINGING, ARTIFACTING, 2.0 * SATURATION, 0.0, ARTIFACTING, 0.0, 2.0 * SATURATION) + +const mat3 yiq2rgb_mat = mat3( + 1.0, 0.956, 0.6210, + 1.0, -0.2720, -0.6474, + 1.0, -1.1060, 1.7046); + +vec3 yiq2rgb(vec3 yiq) +{ + return yiq * yiq2rgb_mat; +} + +const mat3 yiq_mat = mat3( + 0.2989, 0.5870, 0.1140, + 0.5959, -0.2744, -0.3216, + 0.2115, -0.5229, 0.3114 +); + +vec3 rgb2yiq(vec3 col) +{ + return col * yiq_mat; +} + +void main() +{ + vec3 col = texture(Source, vTexCoord).rgb; + vec3 yiq = rgb2yiq(col); + vec3 yiq2 = yiq; + + float mod1 = 2.0; + float mod2 = 3.0; + +if (MERGE > 0.5) +{ + float chroma_phase2 = (phase < 2.5) ? PI * (mod(pix_no.y, mod1) + mod(global.FrameCount+1, 2.)) : 0.6667 * PI * (mod(pix_no.y, mod2) + mod(global.FrameCount+1, 2.)); + float mod_phase2 = (global.ntsc_artifacting_rainbow + 1.0) * chroma_phase2 + pix_no.x * CHROMA_MOD_FREQ; + float i_mod2 = cos(mod_phase2); + float q_mod2 = sin(mod_phase2); + yiq2.yz *= vec2(i_mod2, q_mod2); // Modulate. + yiq2 *= mix_mat; // Cross-talk. + yiq2.yz *= vec2(i_mod2, q_mod2); // Demodulate. +} + + float chroma_phase = (phase < 2.5) ? PI * (mod(pix_no.y, mod1) + mod(global.FrameCount, 2.)) : 0.6667 * PI * (mod(pix_no.y, mod2) + mod(global.FrameCount, 2.)); + float mod_phase = (global.ntsc_artifacting_rainbow + 1.0) * chroma_phase + pix_no.x * CHROMA_MOD_FREQ; + + float i_mod = cos(mod_phase); + float q_mod = sin(mod_phase); + + yiq.yz *= vec2(i_mod, q_mod); // Modulate. + yiq *= mix_mat; // Cross-talk. + yiq.yz *= vec2(i_mod, q_mod); // Demodulate. + + yiq = (MERGE < 0.5) ? yiq : 0.5*(yiq+yiq2); + + FragColor = vec4(yiq, 1.0); +} diff --git a/crt/shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass2.slang b/crt/shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass2.slang new file mode 100644 index 00000000..ee2e6920 --- /dev/null +++ b/crt/shaders/hyllian/support/ntsc/shaders/ntsc-adaptive-lite/ntsc-lite-pass2.slang @@ -0,0 +1,269 @@ +#version 450 + +// NTSC-Adaptive-Lite +// based on Themaister's NTSC shader + + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; + float linearize; + float ntsc_scale; + float ntsc_phase; + float auto_res; + float chroma_scale; +} global; + +#pragma parameter chroma_scale "NTSC Chroma Scaling" 1.0 0.2 4.0 0.1 +#pragma parameter ntsc_scale "NTSC Resolution Scaling" 1.0 0.20 3.0 0.05 +#pragma parameter ntsc_phase "NTSC Phase: Auto | 2 phase | 3 phase" 1.0 1.0 3.0 1.0 +#pragma parameter linearize "NTSC Linearize Output Gamma" 0.0 0.0 1.0 1.0 + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord - vec2(0.5 / global.SourceSize.x, 0.0); // Compensate for decimate-by-2. +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +//layout(set = 0, binding = 3) uniform sampler2D orig; + +vec3 fetch_offset(float offset, vec2 one_x) +{ + /* Insert chroma scaling. Thanks to guest.r ideas. */ + + vec3 yiq; + + yiq.x = texture(Source, vTexCoord + vec2((offset) * (one_x.x), 0.0)).x; + yiq.yz = texture(Source, vTexCoord + vec2((offset) * (one_x.y), 0.0)).yz; + + return yiq; + +/* Old code + return texture(Source, vTexCoord + vec2((offset) * (one_x), 0.0)).xyz; +*/ +} + +const mat3 yiq2rgb_mat = mat3( + 1.0, 0.956, 0.6210, + 1.0, -0.2720, -0.6474, + 1.0, -1.1060, 1.7046); + +vec3 yiq2rgb(vec3 yiq) +{ + return yiq * yiq2rgb_mat; +} + +const mat3 yiq_mat = mat3( + 0.2989, 0.5870, 0.1140, + 0.5959, -0.2744, -0.3216, + 0.2115, -0.5229, 0.3114 +); + +vec3 rgb2yiq(vec3 col) +{ + return col * yiq_mat; +} + + +/* These are accurate and normalized coeffs. */ +const int TAPS_3_phase = 24; +const float luma_filter_3_phase[25] = float[25]( +-0.0000120203033684164, +-0.0000221465589348544, +-0.0000131553320142694, +-0.0000120203033684164, +-0.0000499802614018372, +-0.000113942875690297, +-0.000122153082899506, +-5.61214E-06, +0.000170520303591422, +0.000237204986579451, +0.000169644281482376, +0.000285695210375719, +0.000984598849305758, +0.0020187339488074, +0.00200232553469184, +-0.000909904964181485, +-0.00704925890919635, +-0.0132231937269633, +-0.0126072491817548, +0.00246092210875218, +0.0358691302651096, +0.0840185734607569, +0.135566921437963, +0.175265691355518, +0.190181351796957); + +/* These are accurate and normalized coeffs. */ +const float chroma_filter_3_phase[25] = float[25]( +-0.000135741056915795, +-0.000568115749081878, +-0.00130605691082327, +-0.00231369942971182, +-0.00350569685928248, +-0.00474731062446688, +-0.00585980203774502, +-0.00663114046295865, +-0.00683148404964774, +-0.00623234997205773, +-0.00462792764511295, +-0.00185665431957684, +0.00217899013894782, +0.00749647783836479, +0.0140227874371299, +0.021590863169257, +0.0299437436530477, +0.0387464461271303, +0.0476049759842373, +0.0560911497485196, +0.0637713405314321, +0.0702368383153846, +0.0751333078160781, +0.0781868487834974, +0.0792244191487085); + + +/* These are accurate and normalized coeffs. Though they don't produce ideal smooth vertical lines transparency. */ +const int TAPS_2_phase = 15; +const float luma_filter_2_phase[16] = float[16]( +0.00134372867555492, +0.00294231678339247, +0.00399617683765551, +0.00303632635732925, +-0.00110556727614119, +-0.00839970341605087, +-0.0169515379999301, +-0.0229874881474188, +-0.0217113019865528, +-0.00889151239892142, +0.0173269874254282, +0.0550969075027442, +0.098655909675851, +0.139487291941771, +0.168591277052964, +0.17914037794465); + + +/* + +Use these coeffs if you want smoother transparencies (vertical lines genesis dithering). + +const int TAPS_2_phase = 15; +const float luma_filter_2_phase[16] = float[16]( +0.00358674124928555, +0.00516185579845568, +0.00480461826123886, +0.00132260688600227, +-0.00546931642681805, +-0.014242227285043, +-0.0221097992725951, +-0.025171977770877, +-0.0195669333236999, +-0.00275082885707516, +0.0253995033240388, +0.0620582992351114, +0.101744778642171, +0.137437283264631, +0.162237083549672, +0.171116625451004); + +*/ + +/* These are accurate and normalized coeffs. */ +const float chroma_filter_2_phase[16] = float[16]( +0.00406084767413046, +0.00578573638571078, +0.00804447474387669, +0.0109152541019797, +0.0144533032717188, +0.0186765858322351, +0.0235518468184291, +0.0289834149989225, +0.034807373222651, +0.0407934139180355, +0.0466558344725586, +0.0520737649339226, +0.0567190701585739, +0.0602887575746322, +0.0625375226221969, +0.0633055985408521); + + +void main() +{ + float res = global.ntsc_scale; + float OriginalSize = global.OriginalSize.x; + vec3 signal = vec3(0.0); + float phase = (global.ntsc_phase < 1.5) ? ((OriginalSize > 300.0) ? 2.0 : 3.0) : ((global.ntsc_phase > 2.5) ? 3.0 : 2.0); + + float chroma_scale = phase > 2.5 ? min(global.chroma_scale, 2.2) : global.chroma_scale/2.0; + vec2 one_x = (global.SourceSize.z / res) * vec2(1.0, 1.0 / chroma_scale); + + + if(phase < 2.5) + { + vec3 sums = fetch_offset(0.0 - 15.0, one_x) + fetch_offset(15.0 - 0.0, one_x); + signal += sums * vec3(luma_filter_2_phase[0], chroma_filter_2_phase[0], chroma_filter_2_phase[0]); + sums = fetch_offset(1.0 - 15.0, one_x) + fetch_offset(15.0 - 1.0, one_x); + signal += sums * vec3(luma_filter_2_phase[1], chroma_filter_2_phase[1], chroma_filter_2_phase[1]); + sums = fetch_offset(2.0 - 15.0, one_x) + fetch_offset(15.0 - 2.0, one_x); + signal += sums * vec3(luma_filter_2_phase[2], chroma_filter_2_phase[2], chroma_filter_2_phase[2]); + sums = fetch_offset(3.0 - 15.0, one_x) + fetch_offset(15.0 - 3.0, one_x); + signal += sums * vec3(luma_filter_2_phase[3], chroma_filter_2_phase[3], chroma_filter_2_phase[3]); + sums = fetch_offset(4.0 - 15.0, one_x) + fetch_offset(15.0 - 4.0, one_x); + signal += sums * vec3(luma_filter_2_phase[4], chroma_filter_2_phase[4], chroma_filter_2_phase[4]); + sums = fetch_offset(5.0 - 15.0, one_x) + fetch_offset(15.0 - 5.0, one_x); + signal += sums * vec3(luma_filter_2_phase[5], chroma_filter_2_phase[5], chroma_filter_2_phase[5]); + sums = fetch_offset(6.0 - 15.0, one_x) + fetch_offset(15.0 - 6.0, one_x); + signal += sums * vec3(luma_filter_2_phase[6], chroma_filter_2_phase[6], chroma_filter_2_phase[6]); + sums = fetch_offset(7.0 - 15.0, one_x) + fetch_offset(15.0 - 7.0, one_x); + signal += sums * vec3(luma_filter_2_phase[7], chroma_filter_2_phase[7], chroma_filter_2_phase[7]); + sums = fetch_offset(8.0 - 15.0, one_x) + fetch_offset(15.0 - 8.0, one_x); + signal += sums * vec3(luma_filter_2_phase[8], chroma_filter_2_phase[8], chroma_filter_2_phase[8]); + sums = fetch_offset(9.0 - 15.0, one_x) + fetch_offset(15.0 - 9.0, one_x); + signal += sums * vec3(luma_filter_2_phase[9], chroma_filter_2_phase[9], chroma_filter_2_phase[9]); + sums = fetch_offset(10.0 - 15.0, one_x) + fetch_offset(15.0 - 10.0, one_x); + signal += sums * vec3(luma_filter_2_phase[10], chroma_filter_2_phase[10], chroma_filter_2_phase[10]); + sums = fetch_offset(11.0 - 15.0, one_x) + fetch_offset(15.0 - 11.0, one_x); + signal += sums * vec3(luma_filter_2_phase[11], chroma_filter_2_phase[11], chroma_filter_2_phase[11]); + sums = fetch_offset(12.0 - 15.0, one_x) + fetch_offset(15.0 - 12.0, one_x); + signal += sums * vec3(luma_filter_2_phase[12], chroma_filter_2_phase[12], chroma_filter_2_phase[12]); + sums = fetch_offset(13.0 - 15.0, one_x) + fetch_offset(15.0 - 13.0, one_x); + signal += sums * vec3(luma_filter_2_phase[13], chroma_filter_2_phase[13], chroma_filter_2_phase[13]); + sums = fetch_offset(14.0 - 15.0, one_x) + fetch_offset(15.0 - 14.0, one_x); + signal += sums * vec3(luma_filter_2_phase[14], chroma_filter_2_phase[14], chroma_filter_2_phase[14]); + + signal += texture(Source, vTexCoord).xyz * + vec3(luma_filter_2_phase[TAPS_2_phase], chroma_filter_2_phase[TAPS_2_phase], chroma_filter_2_phase[TAPS_2_phase]); + } + else if(phase > 2.5) + { + for (int i = 0; i < TAPS_3_phase; i++) + { + float offset = float(i); + + vec3 sums = fetch_offset(offset - float(TAPS_3_phase), one_x) + + fetch_offset(float(TAPS_3_phase) - offset, one_x); + signal += sums * vec3(luma_filter_3_phase[i], chroma_filter_3_phase[i], chroma_filter_3_phase[i]); + } + signal += texture(Source, vTexCoord).xyz * + vec3(luma_filter_3_phase[TAPS_3_phase], chroma_filter_3_phase[TAPS_3_phase], chroma_filter_3_phase[TAPS_3_phase]); + } + + vec3 rgb = yiq2rgb(signal); + FragColor = vec4(rgb, 1.0); + if(global.linearize < 0.5) return; + else FragColor = pow(FragColor, vec4(2.2)); +}