Merge pull request #267 from hunterk/master
big update to crt-guest shaders
|
@ -10,12 +10,12 @@ SamplerLUT3_linear = true
|
||||||
SamplerLUT4 = shaders/guest/advanced/lut/ntsc-lut.png
|
SamplerLUT4 = shaders/guest/advanced/lut/ntsc-lut.png
|
||||||
SamplerLUT4_linear = true
|
SamplerLUT4_linear = true
|
||||||
|
|
||||||
shader0 = ../stock.slang
|
shader0 = shaders/guest/fast/stock.slang
|
||||||
filter_linear0 = false
|
filter_linear0 = false
|
||||||
scale_type0 = source
|
scale_type0 = source
|
||||||
scale0 = 1.0
|
scale0 = 1.0
|
||||||
|
|
||||||
shader1 = ../stock.slang
|
shader1 = shaders/guest/fast/stock.slang
|
||||||
filter_linear1 = false
|
filter_linear1 = false
|
||||||
scale_type1 = source
|
scale_type1 = source
|
||||||
scale1 = 1.0
|
scale1 = 1.0
|
||||||
|
@ -34,33 +34,35 @@ scale3 = 1.0
|
||||||
float_framebuffer3 = true
|
float_framebuffer3 = true
|
||||||
alias3 = LinearizePass
|
alias3 = LinearizePass
|
||||||
|
|
||||||
shader4 = shaders/guest/fast/bloom_horizontal.slang
|
shader4 = shaders/guest/fast/crt-guest-advanced-pass1.slang
|
||||||
filter_linear4 = true
|
filter_linear4 = true
|
||||||
scale_type_x4 = absolute
|
scale_type_x4 = viewport
|
||||||
scale_x4 = 800.0
|
scale_x4 = 1.0
|
||||||
scale_type_y4 = source
|
scale_type_y4 = source
|
||||||
scale_y4 = 1.0
|
scale_y4 = 1.0
|
||||||
float_framebuffer4 = true
|
float_framebuffer4 = true
|
||||||
|
alias4 = Pass1
|
||||||
|
|
||||||
shader5 = shaders/guest/fast/bloom_vertical.slang
|
shader5 = shaders/guest/fast/bloom_horizontal.slang
|
||||||
filter_linear5 = true
|
filter_linear5 = true
|
||||||
scale_type_x5 = source
|
scale_type_x5 = absolute
|
||||||
scale_x5 = 1.0
|
scale_x5 = 640.0
|
||||||
scale_type_y5 = source
|
scale_type_y5 = source
|
||||||
scale_y5 = 2.0
|
scale_y5 = 1.0
|
||||||
float_framebuffer5 = true
|
float_framebuffer5 = true
|
||||||
alias5 = BloomPass
|
|
||||||
|
|
||||||
shader6 = shaders/guest/fast/crt-guest-advanced-pass1.slang
|
shader6 = shaders/guest/fast/bloom_vertical.slang
|
||||||
filter_linear6 = true
|
filter_linear6 = true
|
||||||
scale_type_x6 = viewport
|
scale_type_x6 = source
|
||||||
scale_x6 = 1.0
|
scale_x6 = 1.0
|
||||||
scale_type_y6 = source
|
scale_type_y6 = absolute
|
||||||
scale_y6 = 0.5
|
scale_y6 = 480.0
|
||||||
float_framebuffer6 = true
|
float_framebuffer6 = true
|
||||||
|
alias6 = BloomPass
|
||||||
|
|
||||||
shader7 = shaders/guest/fast/crt-guest-advanced-pass2.slang
|
shader7 = shaders/guest/fast/crt-guest-advanced-pass2.slang
|
||||||
filter_linear7 = true
|
filter_linear7 = true
|
||||||
|
float_framebuffer7 = true
|
||||||
scale_type7 = viewport
|
scale_type7 = viewport
|
||||||
scale_x7 = 1.0
|
scale_x7 = 1.0
|
||||||
scale_y7 = 1.0
|
scale_y7 = 1.0
|
||||||
|
|
|
@ -1,29 +1,5 @@
|
||||||
shaders = 10
|
shaders = 10
|
||||||
|
|
||||||
shader0 = ../stock.slang
|
|
||||||
filter_linear0 = false
|
|
||||||
scale_type0 = source
|
|
||||||
scale0 = 1.0
|
|
||||||
|
|
||||||
shader1 = ../stock.slang
|
|
||||||
filter_linear1 = false
|
|
||||||
scale_type1 = source
|
|
||||||
scale1 = 1.0
|
|
||||||
alias1 = StockPass
|
|
||||||
|
|
||||||
shader2 = shaders/guest/advanced/afterglow0.slang
|
|
||||||
filter_linear2 = false
|
|
||||||
scale_type2 = source
|
|
||||||
scale2 = 1.0
|
|
||||||
alias2 = AfterglowPass
|
|
||||||
|
|
||||||
shader3 = shaders/guest/advanced/pre-shaders-afterglow.slang
|
|
||||||
filter_linear3 = false
|
|
||||||
scale_type3 = source
|
|
||||||
scale3 = 1.0
|
|
||||||
mipmap_input3 = true
|
|
||||||
alias3 = PrePass
|
|
||||||
|
|
||||||
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
|
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
|
||||||
SamplerLUT1 = shaders/guest/advanced/lut/trinitron-lut.png
|
SamplerLUT1 = shaders/guest/advanced/lut/trinitron-lut.png
|
||||||
SamplerLUT1_linear = true
|
SamplerLUT1_linear = true
|
||||||
|
@ -34,21 +10,47 @@ SamplerLUT3_linear = true
|
||||||
SamplerLUT4 = shaders/guest/advanced/lut/ntsc-lut.png
|
SamplerLUT4 = shaders/guest/advanced/lut/ntsc-lut.png
|
||||||
SamplerLUT4_linear = true
|
SamplerLUT4_linear = true
|
||||||
|
|
||||||
shader4 = shaders/guest/advanced/avg-lum-hires.slang
|
shader0 = shaders/guest/hd/stock.slang
|
||||||
|
filter_linear0 = false
|
||||||
|
scale_type0 = source
|
||||||
|
scale0 = 1.0
|
||||||
|
|
||||||
|
shader1 = shaders/guest/hd/stock.slang
|
||||||
|
filter_linear1 = false
|
||||||
|
scale_type1 = source
|
||||||
|
scale1 = 1.0
|
||||||
|
alias1 = StockPass
|
||||||
|
|
||||||
|
shader2 = shaders/guest/hd/afterglow0.slang
|
||||||
|
filter_linear2 = false
|
||||||
|
scale_type2 = source
|
||||||
|
scale2 = 1.0
|
||||||
|
alias2 = AfterglowPass
|
||||||
|
|
||||||
|
shader3 = shaders/guest/hd/pre-shaders-afterglow.slang
|
||||||
|
filter_linear3 = false
|
||||||
|
scale_type3 = source
|
||||||
|
mipmap_input3 = true
|
||||||
|
scale3 = 1.0
|
||||||
|
alias3 = PrePass
|
||||||
|
|
||||||
|
shader4 = shaders/guest/hd/linearize-hd.slang
|
||||||
filter_linear4 = true
|
filter_linear4 = true
|
||||||
scale_type4 = source
|
scale_type4 = source
|
||||||
scale4 = 1.0
|
scale4 = 1.0
|
||||||
mipmap_input4 = true
|
float_framebuffer4 = true
|
||||||
alias4 = AvgLumPass
|
alias4 = LinearizePass
|
||||||
|
|
||||||
shader5 = shaders/guest/advanced/linearize-hires.slang
|
shader5 = shaders/guest/hd/crt-guest-advanced-hd-pass1.slang
|
||||||
filter_linear5 = true
|
filter_linear5 = true
|
||||||
scale_type5 = source
|
scale_type_x5 = viewport
|
||||||
scale5 = 1.0
|
scale_x5 = 1.0
|
||||||
alias5 = LinearizePass
|
scale_type_y5 = source
|
||||||
|
scale_y5 = 1.0
|
||||||
float_framebuffer5 = true
|
float_framebuffer5 = true
|
||||||
|
alias5 = Pass1
|
||||||
|
|
||||||
shader6 = shaders/guest/advanced/bloom_horizontal_ntsc.slang
|
shader6 = shaders/guest/hd/bloom_horizontal.slang
|
||||||
filter_linear6 = true
|
filter_linear6 = true
|
||||||
scale_type_x6 = absolute
|
scale_type_x6 = absolute
|
||||||
scale_x6 = 800.0
|
scale_x6 = 800.0
|
||||||
|
@ -56,22 +58,23 @@ scale_type_y6 = source
|
||||||
scale_y6 = 1.0
|
scale_y6 = 1.0
|
||||||
float_framebuffer6 = true
|
float_framebuffer6 = true
|
||||||
|
|
||||||
shader7 = shaders/guest/advanced/bloom_vertical_ntsc.slang
|
shader7 = shaders/guest/hd/bloom_vertical.slang
|
||||||
filter_linear7 = true
|
filter_linear7 = true
|
||||||
scale_type_x7 = absolute
|
scale_type_x7 = source
|
||||||
scale_x7 = 800.0
|
scale_x7 = 1.0
|
||||||
scale_type_y7 = absolute
|
scale_type_y7 = absolute
|
||||||
scale_y7 = 600.0
|
scale_y7 = 600.0
|
||||||
float_framebuffer7 = true
|
float_framebuffer7 = true
|
||||||
alias7 = GlowPass
|
alias7 = BloomPass
|
||||||
|
|
||||||
shader8 = shaders/guest/advanced/crt-guest-advanced-hires.slang
|
shader8 = shaders/guest/hd/crt-guest-advanced-hd-pass2.slang
|
||||||
filter_linear8 = true
|
filter_linear8 = true
|
||||||
|
float_framebuffer8 = true
|
||||||
scale_type8 = viewport
|
scale_type8 = viewport
|
||||||
scale_x8 = 1.0
|
scale_x8 = 1.0
|
||||||
scale_y8 = 1.0
|
scale_y8 = 1.0
|
||||||
|
|
||||||
shader9 = shaders/guest/advanced/deconvergence.slang
|
shader9 = shaders/guest/hd/deconvergence-hd.slang
|
||||||
filter_linear9 = true
|
filter_linear9 = true
|
||||||
scale_type9 = viewport
|
scale_type9 = viewport
|
||||||
scale_x9 = 1.0
|
scale_x9 = 1.0
|
147
crt/crt-guest-advanced-ntsc.slangp
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
shaders = 18
|
||||||
|
|
||||||
|
|
||||||
|
shader0 = shaders/guest/advanced/stock.slang
|
||||||
|
filter_linear0 = false
|
||||||
|
scale_type0 = source
|
||||||
|
scale0 = 1.0
|
||||||
|
|
||||||
|
shader1 = shaders/guest/advanced/stock.slang
|
||||||
|
filter_linear1 = false
|
||||||
|
scale_type1 = source
|
||||||
|
scale1 = 1.0
|
||||||
|
alias1 = StockPass
|
||||||
|
|
||||||
|
shader2 = shaders/guest/advanced/afterglow0.slang
|
||||||
|
filter_linear2 = true
|
||||||
|
scale_type2 = source
|
||||||
|
scale2 = 1.0
|
||||||
|
alias2 = AfterglowPass
|
||||||
|
|
||||||
|
shader3 = shaders/guest/advanced/pre-shaders-afterglow.slang
|
||||||
|
filter_linear3 = true
|
||||||
|
scale_type3 = source
|
||||||
|
scale3 = 1.0
|
||||||
|
alias3 = PrePass0
|
||||||
|
|
||||||
|
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
|
||||||
|
SamplerLUT1 = shaders/guest/advanced/lut/trinitron-lut.png
|
||||||
|
SamplerLUT1_linear = true
|
||||||
|
SamplerLUT2 = shaders/guest/advanced/lut/inv-trinitron-lut.png
|
||||||
|
SamplerLUT2_linear = true
|
||||||
|
SamplerLUT3 = shaders/guest/advanced/lut/nec-lut.png
|
||||||
|
SamplerLUT3_linear = true
|
||||||
|
SamplerLUT4 = shaders/guest/advanced/lut/ntsc-lut.png
|
||||||
|
SamplerLUT4_linear = true
|
||||||
|
|
||||||
|
# custom ntsc shaders
|
||||||
|
|
||||||
|
shader4 = shaders/guest/advanced/ntsc/ntsc-pass1.slang
|
||||||
|
shader5 = shaders/guest/advanced/ntsc/ntsc-pass2.slang
|
||||||
|
|
||||||
|
alias4 = NPass1
|
||||||
|
|
||||||
|
filter_linear4 = false
|
||||||
|
filter_linear5 = true
|
||||||
|
|
||||||
|
scale_type_x4 = source
|
||||||
|
scale_type_y4 = source
|
||||||
|
scale_x4 = 4.0
|
||||||
|
scale_y4 = 1.0
|
||||||
|
float_framebuffer4 = true
|
||||||
|
float_framebuffer5 = true
|
||||||
|
|
||||||
|
scale_type5 = source
|
||||||
|
scale_x5 = 0.5
|
||||||
|
scale_y5 = 1.0
|
||||||
|
|
||||||
|
shader6 = shaders/guest/advanced/ntsc/ntsc-pass3.slang
|
||||||
|
filter_linear6 = true
|
||||||
|
scale_type6 = source
|
||||||
|
scale_x6 = 1.0
|
||||||
|
scale_y6 = 1.0
|
||||||
|
|
||||||
|
shader7 = shaders/guest/advanced/custom-fast-sharpen.slang
|
||||||
|
filter_linear7 = true
|
||||||
|
scale_type7 = source
|
||||||
|
scale_x7 = 1.0
|
||||||
|
scale_y7 = 1.0
|
||||||
|
alias7 = NtscPass
|
||||||
|
|
||||||
|
shader8 = shaders/guest/advanced/stock.slang
|
||||||
|
filter_linear8 = true
|
||||||
|
scale_type8 = source
|
||||||
|
scale_x8 = 1.0
|
||||||
|
scale_y8 = 1.0
|
||||||
|
alias8 = PrePass
|
||||||
|
mipmap_input8 = true
|
||||||
|
|
||||||
|
shader9 = shaders/guest/advanced/avg-lum-ntsc.slang
|
||||||
|
filter_linear9 = true
|
||||||
|
scale_type9 = source
|
||||||
|
scale9 = 1.0
|
||||||
|
mipmap_input9 = true
|
||||||
|
alias9 = AvgLumPass
|
||||||
|
|
||||||
|
shader10 = shaders/guest/advanced/linearize-ntsc.slang
|
||||||
|
filter_linear10 = true
|
||||||
|
scale_type10 = source
|
||||||
|
scale10 = 1.0
|
||||||
|
alias10 = LinearizePass
|
||||||
|
float_framebuffer10 = true
|
||||||
|
|
||||||
|
shader11 = shaders/guest/advanced/crt-guest-advanced-ntsc-pass1.slang
|
||||||
|
filter_linear11 = true
|
||||||
|
scale_type_x11 = viewport
|
||||||
|
scale_x11 = 1.0
|
||||||
|
scale_type_y11 = source
|
||||||
|
scale_y11 = 1.0
|
||||||
|
float_framebuffer11 = true
|
||||||
|
alias11 = Pass1
|
||||||
|
|
||||||
|
shader12 = shaders/guest/advanced/gaussian_horizontal.slang
|
||||||
|
filter_linear12 = true
|
||||||
|
scale_type_x12 = absolute
|
||||||
|
scale_x12 = 800.0
|
||||||
|
scale_type_y12 = source
|
||||||
|
scale_y12 = 1.0
|
||||||
|
float_framebuffer12 = true
|
||||||
|
|
||||||
|
shader13 = shaders/guest/advanced/gaussian_vertical.slang
|
||||||
|
filter_linear13 = true
|
||||||
|
scale_type_x13 = absolute
|
||||||
|
scale_x13 = 800.0
|
||||||
|
scale_type_y13 = absolute
|
||||||
|
scale_y13 = 600.0
|
||||||
|
float_framebuffer13 = true
|
||||||
|
alias13 = GlowPass
|
||||||
|
|
||||||
|
shader14 = shaders/guest/advanced/bloom_horizontal.slang
|
||||||
|
filter_linear14 = true
|
||||||
|
scale_type_x14 = absolute
|
||||||
|
scale_x14 = 800.0
|
||||||
|
scale_type_y14 = absolute
|
||||||
|
scale_y14 = 600.0
|
||||||
|
float_framebuffer14 = true
|
||||||
|
|
||||||
|
shader15 = shaders/guest/advanced/bloom_vertical.slang
|
||||||
|
filter_linear15 = true
|
||||||
|
scale_type_x15 = absolute
|
||||||
|
scale_x15 = 800.0
|
||||||
|
scale_type_y15 = absolute
|
||||||
|
scale_y15 = 600.0
|
||||||
|
float_framebuffer15 = true
|
||||||
|
alias15 = BloomPass
|
||||||
|
|
||||||
|
shader16 = shaders/guest/advanced/crt-guest-advanced-ntsc-pass2.slang
|
||||||
|
filter_linear16 = true
|
||||||
|
float_framebuffer16 = true
|
||||||
|
scale_type16 = viewport
|
||||||
|
scale_x16 = 1.0
|
||||||
|
scale_y16 = 1.0
|
||||||
|
|
||||||
|
shader17 = shaders/guest/advanced/deconvergence-ntsc.slang
|
||||||
|
filter_linear17 = true
|
||||||
|
scale_type17 = viewport
|
||||||
|
scale_x17 = 1.0
|
||||||
|
scale_y17 = 1.0
|
|
@ -1,11 +1,11 @@
|
||||||
shaders = 12
|
shaders = 12
|
||||||
|
|
||||||
shader0 = ../stock.slang
|
shader0 = shaders/guest/advanced/stock.slang
|
||||||
filter_linear0 = false
|
filter_linear0 = false
|
||||||
scale_type0 = source
|
scale_type0 = source
|
||||||
scale0 = 1.0
|
scale0 = 1.0
|
||||||
|
|
||||||
shader1 = ../stock.slang
|
shader1 = shaders/guest/advanced/stock.slang
|
||||||
filter_linear1 = false
|
filter_linear1 = false
|
||||||
scale_type1 = source
|
scale_type1 = source
|
||||||
scale1 = 1.0
|
scale1 = 1.0
|
||||||
|
@ -84,6 +84,7 @@ alias9 = BloomPass
|
||||||
|
|
||||||
shader10 = shaders/guest/advanced/crt-guest-advanced.slang
|
shader10 = shaders/guest/advanced/crt-guest-advanced.slang
|
||||||
filter_linear10 = true
|
filter_linear10 = true
|
||||||
|
float_framebuffer10 = true
|
||||||
scale_type10 = viewport
|
scale_type10 = viewport
|
||||||
scale_x10 = 1.0
|
scale_x10 = 1.0
|
||||||
scale_y10 = 1.0
|
scale_y10 = 1.0
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
shaders = 5
|
|
||||||
|
|
||||||
shader0 = shaders/guest/lut/lut.slang
|
|
||||||
filter_linear0 = false
|
|
||||||
scale_type0 = source
|
|
||||||
scale0 = 1.0
|
|
||||||
|
|
||||||
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3"
|
|
||||||
SamplerLUT1 = shaders/guest/lut/sony_trinitron1.png
|
|
||||||
SamplerLUT1_linear = true
|
|
||||||
SamplerLUT2 = shaders/guest/lut/sony_trinitron2.png
|
|
||||||
SamplerLUT2_linear = true
|
|
||||||
SamplerLUT3 = shaders/guest/lut/other1.png
|
|
||||||
SamplerLUT3_linear = true
|
|
||||||
|
|
||||||
shader1 = shaders/guest/fast/smoothing.slang
|
|
||||||
filter_linear1 = false
|
|
||||||
scale_type1 = source
|
|
||||||
scale1 = 1.0
|
|
||||||
alias1 = SmoothPass
|
|
||||||
|
|
||||||
shader2 = shaders/guest/fast/linearize-multipass.slang
|
|
||||||
filter_linear2 = false
|
|
||||||
scale_type2 = source
|
|
||||||
scale2 = 1.0
|
|
||||||
float_framebuffer2 = true
|
|
||||||
|
|
||||||
shader3 = shaders/guest/fast/crt-guest-dr-venom-pass1.slang
|
|
||||||
filter_linear3 = false
|
|
||||||
scale_type_x3 = viewport
|
|
||||||
scale_x3 = 1.0
|
|
||||||
scale_type_y3 = source
|
|
||||||
scale_y3 = 1.0
|
|
||||||
float_framebuffer3 = true
|
|
||||||
|
|
||||||
shader4 = shaders/guest/fast/crt-guest-dr-venom-pass2.slang
|
|
||||||
filter_linear4 = false
|
|
||||||
scale_type4 = viewport
|
|
||||||
scale_x4 = 1.0
|
|
||||||
scale_y4 = 1.0
|
|
|
@ -1,71 +0,0 @@
|
||||||
shaders = 10
|
|
||||||
|
|
||||||
shader0 = shaders/guest/lut/lut.slang
|
|
||||||
filter_linear0 = false
|
|
||||||
scale_type0 = source
|
|
||||||
scale0 = 1.0
|
|
||||||
|
|
||||||
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3"
|
|
||||||
SamplerLUT1 = shaders/guest/lut/sony_trinitron1.png
|
|
||||||
SamplerLUT1_linear = true
|
|
||||||
SamplerLUT2 = shaders/guest/lut/sony_trinitron2.png
|
|
||||||
SamplerLUT2_linear = true
|
|
||||||
SamplerLUT3 = shaders/guest/lut/other1.png
|
|
||||||
SamplerLUT3_linear = true
|
|
||||||
|
|
||||||
shader1 = shaders/guest/color-profiles.slang
|
|
||||||
filter_linear1 = true
|
|
||||||
scale_type1 = source
|
|
||||||
scale1 = 1.0
|
|
||||||
|
|
||||||
shader2 = shaders/guest/d65-d50.slang
|
|
||||||
filter_linear2 = true
|
|
||||||
scale_type2 = source
|
|
||||||
scale2 = 1.0
|
|
||||||
alias2 = WhitePointPass
|
|
||||||
|
|
||||||
shader3 = shaders/guest/afterglow.slang
|
|
||||||
filter_linear3 = true
|
|
||||||
scale_type3 = source
|
|
||||||
scale3 = 1.0
|
|
||||||
alias3 = AfterglowPass
|
|
||||||
|
|
||||||
shader4 = shaders/guest/avg-lum.slang
|
|
||||||
filter_linear4 = true
|
|
||||||
scale_type4 = source
|
|
||||||
scale4 = 1.0
|
|
||||||
mipmap_input4 = true
|
|
||||||
float_framebuffer4 = true
|
|
||||||
alias4 = AvgLumPass
|
|
||||||
|
|
||||||
shader5 = shaders/guest/linearize.slang
|
|
||||||
filter_linear5 = true
|
|
||||||
scale_type5 = source
|
|
||||||
scale5 = 1.0
|
|
||||||
float_framebuffer5 = true
|
|
||||||
alias5 = LinearizePass
|
|
||||||
|
|
||||||
shader6 = shaders/guest/blur_horiz.slang
|
|
||||||
filter_linear6 = true
|
|
||||||
scale_type6 = source
|
|
||||||
scale6 = 1.0
|
|
||||||
float_framebuffer6 = true
|
|
||||||
|
|
||||||
shader7 = shaders/guest/blur_vert.slang
|
|
||||||
filter_linear7 = true
|
|
||||||
scale_type7 = source
|
|
||||||
scale7 = 1.0
|
|
||||||
float_framebuffer7 = true
|
|
||||||
alias7 = GlowPass
|
|
||||||
|
|
||||||
shader8 = shaders/guest/linearize_scanlines.slang
|
|
||||||
filter_linear8 = true
|
|
||||||
scale_type8 = source
|
|
||||||
scale8 = 1.0
|
|
||||||
float_framebuffer8 = true
|
|
||||||
|
|
||||||
shader9 = shaders/guest/crt-guest-dr-venom.slang
|
|
||||||
filter_linear9 = true
|
|
||||||
scale_type9 = viewport
|
|
||||||
scale_x9 = 1.0
|
|
||||||
scale_y9 = 1.0
|
|
|
@ -1,46 +0,0 @@
|
||||||
# This shader supports Vertical games.
|
|
||||||
# Auto rotation must be turned OFF in Core Options.
|
|
||||||
# Per-game presets can be saved, so it should work out OK.
|
|
||||||
|
|
||||||
shaders = 6
|
|
||||||
|
|
||||||
shader0 = shaders/guest/crt-sm/d65-d50-sm.slang
|
|
||||||
filter_linear0 = true
|
|
||||||
scale_type0 = source
|
|
||||||
scale0 = 1.0
|
|
||||||
alias0 = WpPass
|
|
||||||
|
|
||||||
shader1 = shaders/guest/crt-sm/crt-guest-sm-rot0.slang
|
|
||||||
float_framebuffer1 = true
|
|
||||||
filter_linear1 = true
|
|
||||||
scale_type_x1 = source
|
|
||||||
scale_type_y1 = source
|
|
||||||
scale_x1 = 1.0
|
|
||||||
scale_y1 = 3.0
|
|
||||||
alias1 = RotPass
|
|
||||||
|
|
||||||
shader2 = shaders/guest/crt-sm/linearize-sm.slang
|
|
||||||
float_framebuffer2 = true
|
|
||||||
filter_linear2 = true
|
|
||||||
scale_type2 = source
|
|
||||||
scale2 = 1.0
|
|
||||||
alias2 = LinPass
|
|
||||||
|
|
||||||
shader3 = shaders/guest/crt-sm/blur_horiz-sm.slang
|
|
||||||
float_framebuffer3 = true
|
|
||||||
filter_linear3 = true
|
|
||||||
scale_type3 = source
|
|
||||||
scale3 = 1.0
|
|
||||||
|
|
||||||
shader4 = shaders/guest/crt-sm/blur_vert-sm.slang
|
|
||||||
float_framebuffer4 = true
|
|
||||||
filter_linear4 = true
|
|
||||||
scale_type4 = source
|
|
||||||
scale4 = 1.0
|
|
||||||
|
|
||||||
shader5 = shaders/guest/crt-sm/crt-guest-sm.slang
|
|
||||||
filter_linear5 = true
|
|
||||||
scale_type_x5 = viewport
|
|
||||||
scale_type_y5 = viewport
|
|
||||||
scale_x5 = 1.0
|
|
||||||
scale_y5 = 1.0
|
|
|
@ -27,9 +27,9 @@ layout(push_constant) uniform Push
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
#pragma parameter bogus_afterglow "[ AFTERGLOW SETTINGS ]:" 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_afterglow "[ AFTERGLOW SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
#pragma parameter PR " Persistence Red" 0.25 0.0 0.50 0.01
|
#pragma parameter PR " Persistence Red" 0.32 0.0 0.50 0.01
|
||||||
#pragma parameter PG " Persistence Green" 0.25 0.0 0.50 0.01
|
#pragma parameter PG " Persistence Green" 0.32 0.0 0.50 0.01
|
||||||
#pragma parameter PB " Persistence Blue" 0.25 0.0 0.50 0.01
|
#pragma parameter PB " Persistence Blue" 0.32 0.0 0.50 0.01
|
||||||
|
|
||||||
#define PR params.PR
|
#define PR params.PR
|
||||||
#define PG params.PG
|
#define PG params.PG
|
||||||
|
@ -68,9 +68,9 @@ void main()
|
||||||
vec3 accumulate = COMPAT_TEXTURE(AfterglowPassFeedback, TEX0.xy).rgb;
|
vec3 accumulate = COMPAT_TEXTURE(AfterglowPassFeedback, TEX0.xy).rgb;
|
||||||
|
|
||||||
float w = 1.0;
|
float w = 1.0;
|
||||||
if ((color.r + color.g + color.b < 1.5/255.0)) { w = 0.0; }
|
if ((color.r + color.g + color.b < 5.0/255.0)) { w = 0.0; }
|
||||||
|
|
||||||
vec3 result = mix( max(mix(color, accumulate, 0.49 + vec3(PR, PG, PB))- 3.0/255.0, 0.0), color, w);
|
vec3 result = mix( max(mix(color, accumulate, 0.49 + vec3(PR, PG, PB))- 2.0/255.0, 0.0), color, w);
|
||||||
|
|
||||||
FragColor = vec4(result, w);
|
FragColor = vec4(result, w);
|
||||||
}
|
}
|
|
@ -1,87 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Average Luminance Shader
|
|
||||||
|
|
||||||
Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Thanks to HunterK for the mipmap hint. :D
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
uint FrameCount;
|
|
||||||
vec4 SourceSize;
|
|
||||||
float lsmooth;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter lsmooth "Raster Bloom Effect Smoothing" 0.70 0.50 0.99 0.01
|
|
||||||
|
|
||||||
#define lsmooth params.lsmooth
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
#define InputSize SourceSize
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
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 PrePass;
|
|
||||||
layout(set = 0, binding = 3) uniform sampler2D AvgLumPassFeedback;
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
if (vTexCoord.x > 0.2 || vTexCoord.y > 0.2) discard;
|
|
||||||
|
|
||||||
float m = max(log2(SourceSize.x), log2(SourceSize.y));
|
|
||||||
m = floor(max(m, 1.0));
|
|
||||||
|
|
||||||
float ltotal = 0.0;
|
|
||||||
|
|
||||||
ltotal+= length(textureLod(PrePass, vec2(0.25, 0.25), m).rgb);
|
|
||||||
ltotal+= length(textureLod(PrePass, vec2(0.25, 0.75), m).rgb);
|
|
||||||
ltotal+= length(textureLod(PrePass, vec2(0.75, 0.25), m).rgb);
|
|
||||||
ltotal+= length(textureLod(PrePass, vec2(0.75, 0.75), m).rgb);
|
|
||||||
|
|
||||||
ltotal*=0.25;
|
|
||||||
|
|
||||||
ltotal = pow(0.577350269 * ltotal, 0.65);
|
|
||||||
|
|
||||||
float lhistory = texture(AvgLumPassFeedback, vec2(0.1,0.1)).a;
|
|
||||||
|
|
||||||
ltotal = mix(ltotal, lhistory, lsmooth);
|
|
||||||
|
|
||||||
FragColor = vec4(ltotal);
|
|
||||||
}
|
|
|
@ -75,7 +75,7 @@ float dist(vec3 A, vec3 B)
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float m = max(log2(SourceSize.x), log2(SourceSize.y));
|
float m = max(log2(SourceSize.x), log2(SourceSize.y));
|
||||||
m = floor(max(m, 1.0));
|
m = floor(max(m, 1.0))-1.0;
|
||||||
|
|
||||||
vec2 dx = vec2(1.0/SourceSize.x, 0.0);
|
vec2 dx = vec2(1.0/SourceSize.x, 0.0);
|
||||||
vec2 dy = vec2(0.0, 1.0/SourceSize.y);
|
vec2 dy = vec2(0.0, 1.0/SourceSize.y);
|
||||||
|
@ -84,14 +84,14 @@ void main()
|
||||||
|
|
||||||
float ltotal = 0.0;
|
float ltotal = 0.0;
|
||||||
|
|
||||||
ltotal+= length(textureLod(Source, vec2(0.25, 0.25), m).rgb);
|
ltotal+= length(textureLod(Source, vec2(0.3, 0.3), m).rgb);
|
||||||
ltotal+= length(textureLod(Source, vec2(0.25, 0.75), m).rgb);
|
ltotal+= length(textureLod(Source, vec2(0.3, 0.7), m).rgb);
|
||||||
ltotal+= length(textureLod(Source, vec2(0.75, 0.25), m).rgb);
|
ltotal+= length(textureLod(Source, vec2(0.7, 0.3), m).rgb);
|
||||||
ltotal+= length(textureLod(Source, vec2(0.75, 0.75), m).rgb);
|
ltotal+= length(textureLod(Source, vec2(0.7, 0.7), m).rgb);
|
||||||
|
|
||||||
ltotal*=0.25;
|
ltotal*=0.25;
|
||||||
|
|
||||||
ltotal = pow(0.577350269 * ltotal, 0.65);
|
ltotal = pow(0.577350269 * ltotal, 0.70);
|
||||||
|
|
||||||
float lhistory = texture(AvgLumPassFeedback, vec2(0.5,0.5)).a;
|
float lhistory = texture(AvgLumPassFeedback, vec2(0.5,0.5)).a;
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ float dist(vec3 A, vec3 B)
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float m = max(log2(SourceSize.x), log2(SourceSize.y));
|
float m = max(log2(SourceSize.x), log2(SourceSize.y));
|
||||||
m = floor(max(m, 1.0));
|
m = floor(max(m, 1.0))-1.0;
|
||||||
|
|
||||||
vec2 dx = vec2(1.0/SourceSize.x, 0.0);
|
vec2 dx = vec2(1.0/SourceSize.x, 0.0);
|
||||||
vec2 dy = vec2(0.0, 1.0/SourceSize.y);
|
vec2 dy = vec2(0.0, 1.0/SourceSize.y);
|
||||||
|
@ -84,14 +84,14 @@ void main()
|
||||||
|
|
||||||
float ltotal = 0.0;
|
float ltotal = 0.0;
|
||||||
|
|
||||||
ltotal+= length(textureLod(Source, vec2(0.25, 0.25), m).rgb);
|
ltotal+= length(textureLod(Source, vec2(0.3, 0.3), m).rgb);
|
||||||
ltotal+= length(textureLod(Source, vec2(0.25, 0.75), m).rgb);
|
ltotal+= length(textureLod(Source, vec2(0.3, 0.7), m).rgb);
|
||||||
ltotal+= length(textureLod(Source, vec2(0.75, 0.25), m).rgb);
|
ltotal+= length(textureLod(Source, vec2(0.7, 0.3), m).rgb);
|
||||||
ltotal+= length(textureLod(Source, vec2(0.75, 0.75), m).rgb);
|
ltotal+= length(textureLod(Source, vec2(0.7, 0.7), m).rgb);
|
||||||
|
|
||||||
ltotal*=0.25;
|
ltotal*=0.25;
|
||||||
|
|
||||||
ltotal = pow(0.577350269 * ltotal, 0.65);
|
ltotal = pow(0.577350269 * ltotal, 0.70);
|
||||||
|
|
||||||
float lhistory = texture(AvgLumPassFeedback, vec2(0.5,0.5)).a;
|
float lhistory = texture(AvgLumPassFeedback, vec2(0.5,0.5)).a;
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,10 @@ layout(push_constant) uniform Push
|
||||||
|
|
||||||
#pragma parameter bogus_bloom "[ BLOOM/HALATION/(GLOW) PASS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_bloom "[ BLOOM/HALATION/(GLOW) PASS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter SIZEHB " Horizontal Bloom/Halation/(Glow) Radius" 4.0 1.0 50.0 1.0
|
#pragma parameter SIZEHB " Horizontal Bloom/Halation/(Glow) Radius" 3.0 1.0 50.0 1.0
|
||||||
#define SIZEHB params.SIZEHB
|
#define SIZEHB params.SIZEHB
|
||||||
|
|
||||||
#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/(Glow) Sigma" 0.70 0.25 15.0 0.05
|
#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/(Glow) Sigma" 0.75 0.25 15.0 0.05
|
||||||
#define SIGMA_HB params.SIGMA_HB
|
#define SIGMA_HB params.SIGMA_HB
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Gaussian blur - horizontal pass, dynamic range, resizable
|
|
||||||
|
|
||||||
Copyright (C) 2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 LinearizePassSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float SIZEHB;
|
|
||||||
float SIGMA_HB;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter bogus_bloom "[ BLOOM/HALATION/(GLOW) PASS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter SIZEHB " Horizontal Bloom/Halation/(Glow) Radius" 6.0 1.0 50.0 1.0
|
|
||||||
#define SIZEHB params.SIZEHB
|
|
||||||
|
|
||||||
#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/(Glow) Sigma" 1.0 0.20 15.0 0.10
|
|
||||||
#define SIGMA_HB params.SIGMA_HB
|
|
||||||
|
|
||||||
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 LinearizePass;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
float invsqrsigma = 1.0/(2.0*SIGMA_HB*SIGMA_HB);
|
|
||||||
|
|
||||||
float gaussian(float x)
|
|
||||||
{
|
|
||||||
return exp(-x*x*invsqrsigma);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 SourceSize1 = params.OriginalSize;
|
|
||||||
float f = fract(SourceSize1.x * vTexCoord.x);
|
|
||||||
f = 0.5 - f;
|
|
||||||
vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw;
|
|
||||||
vec4 color = vec4(0.0);
|
|
||||||
vec2 dx = vec2(SourceSize1.z, 0.0);
|
|
||||||
|
|
||||||
float w;
|
|
||||||
float wsum = 0.0;
|
|
||||||
vec4 pixel;
|
|
||||||
float n = -SIZEHB;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx);
|
|
||||||
w = gaussian(n+f);
|
|
||||||
pixel.a = max(max(pixel.r, pixel.g),pixel.b);
|
|
||||||
pixel.a*=pixel.a*pixel.a;
|
|
||||||
color = color + w * pixel;
|
|
||||||
wsum = wsum + w;
|
|
||||||
n = n + 1.0;
|
|
||||||
|
|
||||||
} while (n <= SIZEHB);
|
|
||||||
|
|
||||||
color = color / wsum;
|
|
||||||
|
|
||||||
FragColor = vec4(color.rgb, pow(color.a, 0.333333));
|
|
||||||
}
|
|
|
@ -32,10 +32,10 @@ layout(push_constant) uniform Push
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter SIZEVB " Vertical Bloom/Halation/(Glow) Radius" 4.0 1.0 50.0 1.0
|
#pragma parameter SIZEVB " Vertical Bloom/Halation/(Glow) Radius" 3.0 1.0 50.0 1.0
|
||||||
#define SIZEVB params.SIZEVB
|
#define SIZEVB params.SIZEVB
|
||||||
|
|
||||||
#pragma parameter SIGMA_VB " Vertical Bloom/Halation/(Glow) Sigma" 0.70 0.25 15.0 0.05
|
#pragma parameter SIGMA_VB " Vertical Bloom/Halation/(Glow) Sigma" 0.60 0.25 15.0 0.05
|
||||||
#define SIGMA_VB params.SIGMA_VB
|
#define SIGMA_VB params.SIGMA_VB
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Gaussian blur - vertical pass, dynamic range, resizable
|
|
||||||
|
|
||||||
Copyright (C) 2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float SIZEVB;
|
|
||||||
float SIGMA_VB;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter SIZEVB " Vertical Bloom/Halation/(Glow) Radius" 6.0 1.0 50.0 1.0
|
|
||||||
#define SIZEVB params.SIZEVB
|
|
||||||
|
|
||||||
#pragma parameter SIGMA_VB " Vertical Bloom/Halation/(Glow) Sigma" 1.0 0.20 15.0 0.10
|
|
||||||
#define SIGMA_VB params.SIGMA_VB
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
float invsqrsigma = 1.0/(2.0*SIGMA_VB*SIGMA_VB);
|
|
||||||
|
|
||||||
float gaussian(float x)
|
|
||||||
{
|
|
||||||
return exp(-x*x*invsqrsigma);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 SourceSize1 = params.SourceSize;
|
|
||||||
SourceSize1.yw = params.OriginalSize.yw;
|
|
||||||
|
|
||||||
float f = fract(SourceSize1.y * vTexCoord.y);
|
|
||||||
f = 0.5 - f;
|
|
||||||
vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw;
|
|
||||||
vec4 color = vec4(0.0);
|
|
||||||
vec2 dy = vec2(0.0, SourceSize1.w);
|
|
||||||
|
|
||||||
float w;
|
|
||||||
float wsum = 0.0;
|
|
||||||
vec4 pixel;
|
|
||||||
float n = -SIZEVB;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
pixel = COMPAT_TEXTURE(Source, tex + n*dy);
|
|
||||||
w = gaussian(n+f);
|
|
||||||
pixel.a*=pixel.a*pixel.a;
|
|
||||||
color = color + w * pixel;
|
|
||||||
wsum = wsum + w;
|
|
||||||
n = n + 1.0;
|
|
||||||
|
|
||||||
} while (n <= SIZEVB);
|
|
||||||
|
|
||||||
color = color / wsum;
|
|
||||||
|
|
||||||
FragColor = vec4(color.rgb, pow(color.a, 0.175));
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float blendMode;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter blendMode "NTSC Blend Mode (Main Mode Control)" 1.0 0.0 2.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 PrePass0;
|
|
||||||
|
|
||||||
vec3 plant (vec3 tar, float r)
|
|
||||||
{
|
|
||||||
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
|
||||||
return tar * r / t;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 dx = vec2(params.SourceSize.z * 0.5, 0.0);
|
|
||||||
vec3 col1 = texture(Source, vTexCoord -dx).rgb;
|
|
||||||
vec3 col2 = texture(Source, vTexCoord +dx).rgb;
|
|
||||||
vec3 colc = max(col1, col2);
|
|
||||||
vec3 col = plant(sqrt(col1*col2), max(max(colc.r, colc.g),colc.b));
|
|
||||||
|
|
||||||
vec3 orig = texture(PrePass0, vTexCoord).rgb;
|
|
||||||
vec3 res = normalize(col + 0.00001) * min(length(col), length(orig));
|
|
||||||
|
|
||||||
float k2 = 1.0/(dot(col1 - res, col1 - res) + 0.0001);
|
|
||||||
float k3 = 1.0/(dot(col2 - res, col2 - res) + 0.0001);
|
|
||||||
|
|
||||||
vec3 res1 = (k2 * col1 + k3 * col2) / (k2 + k3);
|
|
||||||
res1 = clamp(res1, min(col1,col2), max(col1, col2));
|
|
||||||
|
|
||||||
if ( params.blendMode == 1.0) res = res1;
|
|
||||||
|
|
||||||
FragColor = vec4(res, 1.0);
|
|
||||||
}
|
|
|
@ -1,775 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - Advanced (Hi-Res version)
|
|
||||||
|
|
||||||
Copyright (C) 2018-2021 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
|
||||||
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
|
||||||
h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask,
|
|
||||||
slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike, intres;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float bloom;
|
|
||||||
float halation;
|
|
||||||
float mclip;
|
|
||||||
float scans;
|
|
||||||
float scansub;
|
|
||||||
float slotms;
|
|
||||||
float gamma_c;
|
|
||||||
float mask_gamma;
|
|
||||||
float gamma_out;
|
|
||||||
float overscanX;
|
|
||||||
float overscanY;
|
|
||||||
float c_shape;
|
|
||||||
float barspeed;
|
|
||||||
float barintensity;
|
|
||||||
float bardir;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
|
||||||
#define glow params.glow // Glow Strength
|
|
||||||
|
|
||||||
#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05
|
|
||||||
#define bloom global.bloom // bloom effect
|
|
||||||
|
|
||||||
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
|
||||||
#define halation global.halation // halation effect
|
|
||||||
|
|
||||||
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
|
||||||
#define gamma_c global.gamma_c // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05
|
|
||||||
#define brightboost params.brightboost // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025
|
|
||||||
#define brightboost1 params.brightboost1 // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
|
||||||
#define gsl params.gsl // Alternate scanlines
|
|
||||||
|
|
||||||
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 0.0 20.0 0.5
|
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 3.0 40.0 1.0
|
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 0.05
|
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
|
||||||
|
|
||||||
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 2.5 0.05
|
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
|
||||||
|
|
||||||
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
|
||||||
#define beam_size params.beam_size // increased max. beam size
|
|
||||||
|
|
||||||
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
|
||||||
#define vertmask params.vertmask // Scanline deconvergence colors
|
|
||||||
|
|
||||||
#pragma parameter scans " Scanline Saturation" 0.60 0.0 1.0 0.05
|
|
||||||
#define scans global.scans // scanline saturation
|
|
||||||
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// #pragma parameter scansub " Scanline darken 'edges'" 0.0 0.0 0.30 0.005
|
|
||||||
// #define scansub global.scansub // scanline substraction
|
|
||||||
|
|
||||||
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
|
||||||
#define spike params.spike
|
|
||||||
|
|
||||||
#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.10
|
|
||||||
#define h_sharp params.h_sharp // pixel sharpness
|
|
||||||
|
|
||||||
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
|
||||||
#define s_sharp params.s_sharp // substractive sharpness
|
|
||||||
|
|
||||||
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with linearize pass, values must match
|
|
||||||
#define intres params.intres // interlace resolution
|
|
||||||
|
|
||||||
#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0
|
|
||||||
#define TATE params.TATE // Screen orientation
|
|
||||||
|
|
||||||
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
|
||||||
#define IOS params.IOS // Smart Integer Scaling
|
|
||||||
|
|
||||||
#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
|
|
||||||
#define OS params.OS // Do overscan
|
|
||||||
|
|
||||||
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
|
||||||
#define BLOOM params.BLOOM // Bloom overscan percentage
|
|
||||||
|
|
||||||
#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01
|
|
||||||
#define csize params.csize // corner size
|
|
||||||
|
|
||||||
#pragma parameter bsize " Border smoothness" 600.0 100.0 700.0 10.0
|
|
||||||
#define bsize params.bsize // border smoothness
|
|
||||||
|
|
||||||
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01
|
|
||||||
|
|
||||||
#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
|
||||||
#define warpX params.warpX // Curvature X
|
|
||||||
|
|
||||||
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01
|
|
||||||
#define warpY params.warpY // Curvature Y
|
|
||||||
|
|
||||||
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
|
||||||
#define c_shape global.c_shape // curvature shape
|
|
||||||
|
|
||||||
#pragma parameter overscanX " Overscan X original pixels" 0.0 -50.0 50.0 1.0
|
|
||||||
#define overscanX global.overscanX // OverscanX pixels
|
|
||||||
|
|
||||||
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -50.0 50.0 1.0
|
|
||||||
#define overscanY global.overscanY // OverscanY pixels
|
|
||||||
|
|
||||||
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0
|
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
|
||||||
|
|
||||||
#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05
|
|
||||||
#define maskstr params.maskstr // maskstr Mask Strength
|
|
||||||
|
|
||||||
#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05
|
|
||||||
#define mcut params.mcut // Mask 5-7 dark color strength
|
|
||||||
|
|
||||||
#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0
|
|
||||||
#define masksize params.masksize // Mask Size
|
|
||||||
|
|
||||||
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
|
||||||
#define maskDark params.maskDark // Dark "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05
|
|
||||||
#define mask_gamma global.mask_gamma // Mask application gamma
|
|
||||||
|
|
||||||
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask params.slotmask
|
|
||||||
|
|
||||||
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask1 params.slotmask1
|
|
||||||
|
|
||||||
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 6.0 0.5
|
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
|
||||||
|
|
||||||
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
|
||||||
|
|
||||||
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
|
||||||
#define slotms global.slotms // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter mclip " Keep Mask effect with clipping" 0.5 0.0 1.0 0.05
|
|
||||||
#define mclip global.mclip // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05
|
|
||||||
#define gamma_out global.gamma_out // output gamma
|
|
||||||
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
#define OutputSize global.OutputSize
|
|
||||||
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
|
||||||
|
|
||||||
#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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma stage fragment
|
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
|
||||||
layout(location = 0) out vec4 FragColor;
|
|
||||||
layout(set = 0, binding = 2) uniform sampler2D LinearizePass;
|
|
||||||
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
|
||||||
layout(set = 0, binding = 4) uniform sampler2D GlowPass;
|
|
||||||
layout(set = 0, binding = 5) uniform sampler2D PrePass;
|
|
||||||
|
|
||||||
#define eps 1e-10
|
|
||||||
|
|
||||||
float st(float x)
|
|
||||||
{
|
|
||||||
return exp2(-10.0*x*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw0(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix(beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
ex = (gsl > -0.5) ? ex*ex : mix(ex*ex, ex*ex*ex, 0.4);
|
|
||||||
return exp2(-scanline*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw1(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
x = mix (x, beam_min*x, max(x-0.4*color,0.0));
|
|
||||||
float tmp = mix(1.2*beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw2(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix((2.5-0.5*color)*beam_min, beam_max, color);
|
|
||||||
tmp = mix(beam_max, tmp, pow(x, color+0.3));
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shadow mask (1-4 from PD CRT Lottes shader).
|
|
||||||
|
|
||||||
vec3 Mask(vec2 pos, float mx)
|
|
||||||
{
|
|
||||||
pos = floor(pos/masksize);
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 0.0) + 1.0, 1.0, mx);
|
|
||||||
float mc = 1.0 - max(maskstr, 0.0);
|
|
||||||
|
|
||||||
// No mask
|
|
||||||
if (shadowMask == -1.0)
|
|
||||||
{
|
|
||||||
mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phosphor.
|
|
||||||
else if (shadowMask == 0.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x*0.5);
|
|
||||||
if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
|
||||||
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very compressed TV style shadow mask.
|
|
||||||
else if (shadowMask == 1.0)
|
|
||||||
{
|
|
||||||
float line = maskLight;
|
|
||||||
float odd = 0.0;
|
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
|
||||||
odd = 1.0;
|
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
|
||||||
line = maskDark;
|
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
|
|
||||||
mask*=line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aperture-grille.
|
|
||||||
else if (shadowMask == 2.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stretched VGA style shadow mask (same as prior shaders).
|
|
||||||
else if (shadowMask == 3.0)
|
|
||||||
{
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA style shadow mask.
|
|
||||||
else if (shadowMask == 4.0)
|
|
||||||
{
|
|
||||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 5
|
|
||||||
else if (shadowMask == 5.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5)
|
|
||||||
{ mask.r = 1.0;
|
|
||||||
mask.b = 1.0;
|
|
||||||
}
|
|
||||||
else mask.g = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 6
|
|
||||||
else if (shadowMask == 6.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
if (pos.x < 0.333) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.666) mask.g = 1.0;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BW Trinitron mask 7
|
|
||||||
else if (shadowMask == 7.0)
|
|
||||||
{
|
|
||||||
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
mask = vec3(maskTmp);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5) mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4k mask
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mask = vec3(mc);
|
|
||||||
pos.x = fract(pos.x * 0.25);
|
|
||||||
if (pos.x < 0.2) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
|
||||||
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SlotMask(vec2 pos, float m)
|
|
||||||
{
|
|
||||||
if ((slotmask + slotmask1) == 0.0) return 1.0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pos = floor(pos/slotms);
|
|
||||||
float mlen = slotwidth*2.0;
|
|
||||||
float px = fract(pos.x/mlen);
|
|
||||||
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
|
||||||
float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m);
|
|
||||||
float slot = 1.0;
|
|
||||||
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
|
||||||
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Warp(vec2 pos)
|
|
||||||
{
|
|
||||||
pos = pos*2.0-1.0;
|
|
||||||
pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape);
|
|
||||||
return pos*0.5 + 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Overscan(vec2 pos, float dx, float dy){
|
|
||||||
pos=pos*2.0-1.0;
|
|
||||||
pos*=vec2(dx,dy);
|
|
||||||
return pos*0.5+0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
float humbar(float pos)
|
|
||||||
{
|
|
||||||
if (global.barintensity == 0.0) return 1.0; else
|
|
||||||
{
|
|
||||||
pos = (global.barintensity >= 0.0) ? pos : (1.0-pos);
|
|
||||||
pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0));
|
|
||||||
pos = (global.barintensity < 0.0) ? pos : (1.0-pos);
|
|
||||||
return (1.0-global.barintensity) + global.barintensity*pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Borrowed from maskstr's crt-geom, under GPL
|
|
||||||
|
|
||||||
float corner(vec2 coord)
|
|
||||||
{
|
|
||||||
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
|
|
||||||
vec2 cdist = vec2(max(csize/3.0, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002)));
|
|
||||||
coord = (cdist - min(coord,cdist));
|
|
||||||
float dist = sqrt(dot(coord,coord));
|
|
||||||
return clamp((cdist.x-dist)*bsize,0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 gc(vec3 c)
|
|
||||||
{
|
|
||||||
float mc = max(max(c.r,c.g),c.b);
|
|
||||||
float mg = pow(mc, 1.0/gamma_c);
|
|
||||||
return c * mg/(mc + eps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 SourceSize = global.OriginalSize;
|
|
||||||
|
|
||||||
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.1,0.1)).a;
|
|
||||||
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
|
||||||
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
|
||||||
bool interb = (intera < 0.75);
|
|
||||||
|
|
||||||
bool notate = (TATE < 0.5);
|
|
||||||
|
|
||||||
float SourceY = mix(SourceSize.y, SourceSize.x, TATE);
|
|
||||||
float sy = 1.0;
|
|
||||||
if (intres == 0.5) sy = SourceY/224.0; else
|
|
||||||
if (intres == 1.0) sy = SourceY/240.0; else
|
|
||||||
if (intres > 1.25) sy = intres;
|
|
||||||
if (notate) SourceSize.yw*=vec2(1.0/sy, sy); else SourceSize.xz*=vec2(1.0/sy, sy);
|
|
||||||
|
|
||||||
// Calculating texel coordinates
|
|
||||||
|
|
||||||
vec2 texcoord = TEX0.xy;
|
|
||||||
if (IOS > 0.0){
|
|
||||||
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
|
||||||
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
|
||||||
vec2 diff = ofactor/intfactor;
|
|
||||||
float scan = mix(diff.y, diff.x, TATE);
|
|
||||||
texcoord = Overscan(texcoord, scan, scan);
|
|
||||||
if (IOS == 1.0 || IOS == 3.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
|
||||||
texcoord = Overscan(texcoord, factor, factor);
|
|
||||||
texcoord = Overscan(texcoord, (SourceSize.x - overscanX)/SourceSize.x, (SourceSize.y - overscanY)/SourceSize.y);
|
|
||||||
vec2 pos = Warp(texcoord);
|
|
||||||
vec2 pos0 = Warp(TEX0.xy);
|
|
||||||
|
|
||||||
vec2 coffset = vec2(0.5, 0.5);
|
|
||||||
|
|
||||||
vec2 ps = SourceSize.zw;
|
|
||||||
vec2 OGL2Pos = pos * SourceSize.xy - coffset;
|
|
||||||
vec2 fp = fract(OGL2Pos);
|
|
||||||
|
|
||||||
vec2 dx = vec2(ps.x,0.0);
|
|
||||||
vec2 dy = vec2(0.0, ps.y);
|
|
||||||
|
|
||||||
// Reading the texels
|
|
||||||
vec2 x2 = 2.0*dx;
|
|
||||||
vec2 y2 = 2.0*dy;
|
|
||||||
|
|
||||||
vec2 offx = dx;
|
|
||||||
vec2 off2 = x2;
|
|
||||||
vec2 offy = dy;
|
|
||||||
float fpx = fp.x;
|
|
||||||
if(!notate)
|
|
||||||
{
|
|
||||||
offx = dy;
|
|
||||||
off2 = y2;
|
|
||||||
offy = dx;
|
|
||||||
fpx = fp.y;
|
|
||||||
}
|
|
||||||
float f = (notate) ? fp.y : fp.x;
|
|
||||||
|
|
||||||
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
|
|
||||||
|
|
||||||
if (interb) pC4.y = pos.y;
|
|
||||||
|
|
||||||
float h_sharp1 = pow(h_sharp, 1.4);
|
|
||||||
|
|
||||||
float zero = exp2(-h_sharp1);
|
|
||||||
|
|
||||||
float sharp1 = s_sharp * zero;
|
|
||||||
|
|
||||||
float wl5 = 4.0 + fpx; wl5*=0.5;
|
|
||||||
float wl4 = 3.0 + fpx; wl4*=0.5;
|
|
||||||
float wl3 = 2.0 + fpx; wl3*=0.5;
|
|
||||||
float wl2 = 1.0 + fpx; wl2*=0.5;
|
|
||||||
float wl1 = fpx; wl1*=0.5;
|
|
||||||
float wr1 = 1.0 - fpx; wr1*=0.5;
|
|
||||||
float wr2 = 2.0 - fpx; wr2*=0.5;
|
|
||||||
float wr3 = 3.0 - fpx; wr3*=0.5;
|
|
||||||
float wr4 = 4.0 - fpx; wr4*=0.5;
|
|
||||||
float wr5 = 5.0 - fpx; wr5*=0.5;
|
|
||||||
|
|
||||||
wl5*=wl5; wl5 = exp2(-h_sharp1*wl5);
|
|
||||||
wl4*=wl4; wl4 = exp2(-h_sharp1*wl4);
|
|
||||||
wl3*=wl3; wl3 = exp2(-h_sharp1*wl3);
|
|
||||||
wl2*=wl2; wl2 = exp2(-h_sharp1*wl2);
|
|
||||||
wl1*=wl1; wl1 = exp2(-h_sharp1*wl1);
|
|
||||||
wr1*=wr1; wr1 = exp2(-h_sharp1*wr1);
|
|
||||||
wr2*=wr2; wr2 = exp2(-h_sharp1*wr2);
|
|
||||||
wr3*=wr3; wr3 = exp2(-h_sharp1*wr3);
|
|
||||||
wr4*=wr4; wr4 = exp2(-h_sharp1*wr4);
|
|
||||||
wr5*=wr5; wr5 = exp2(-h_sharp1*wr5);
|
|
||||||
|
|
||||||
float fp1 = 1.-fpx;
|
|
||||||
|
|
||||||
float twl5 = max(wl5 - sharp1, 0.0);
|
|
||||||
float twl4 = max(wl4 - sharp1, mix(0.0,mix(-0.03, 0.00, fpx),float(s_sharp > 0.05))); float swl4 = max(wl4 - sharp1, 0.0);
|
|
||||||
float twl3 = max(wl3 - sharp1, mix(0.0,mix(-0.10, -0.03, fpx),float(s_sharp > 0.05))); float swl3 = max(wl3 - sharp1, 0.0);
|
|
||||||
float twl2 = max(wl2 - sharp1, 0.0);
|
|
||||||
float twl1 = max(wl1 - sharp1, 0.0);
|
|
||||||
float twr1 = max(wr1 - sharp1, 0.0);
|
|
||||||
float twr2 = max(wr2 - sharp1, 0.0);
|
|
||||||
float twr3 = max(wr3 - sharp1, mix(0.0,mix(-0.10, -0.03, fp1),float(s_sharp > 0.05))); float swr3 = max(wr3 - sharp1, 0.0);
|
|
||||||
float twr4 = max(wr4 - sharp1, mix(0.0,mix(-0.03, 0.00, fp1),float(s_sharp > 0.05))); float swr4 = max(wr4 - sharp1, 0.0);
|
|
||||||
float twr5 = max(wr5 - sharp1, 0.0);
|
|
||||||
|
|
||||||
float wtt = 1.0/(twl5+twl4+twl3+twl2+twl1+twr1+twr2+twr3+twr4+twr5);
|
|
||||||
float wt = 1.0/(swl3+twl2+twl1+twr1+twr2+swr3);
|
|
||||||
bool sharp = (s_sharp > 0.05);
|
|
||||||
|
|
||||||
vec3 l5 = COMPAT_TEXTURE(LinearizePass, pC4 -2.0*off2).xyz;
|
|
||||||
vec3 l4 = COMPAT_TEXTURE(LinearizePass, pC4 -3.0*offx).xyz;
|
|
||||||
vec3 l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).xyz;
|
|
||||||
vec3 l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).xyz;
|
|
||||||
vec3 l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).xyz;
|
|
||||||
vec3 r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).xyz;
|
|
||||||
vec3 r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).xyz;
|
|
||||||
vec3 r3 = COMPAT_TEXTURE(LinearizePass, pC4 +3.0*offx).xyz;
|
|
||||||
vec3 r4 = COMPAT_TEXTURE(LinearizePass, pC4 +4.0*offx).xyz;
|
|
||||||
vec3 r5 = COMPAT_TEXTURE(LinearizePass, pC4 +5.0*offx).xyz;
|
|
||||||
|
|
||||||
vec3 sl3 = l3*l3*l3; sl3*=sl3;
|
|
||||||
vec3 sl2 = l2*l2*l2; sl2*=sl2;
|
|
||||||
vec3 sl1 = l1*l1*l1; sl1*=sl1;
|
|
||||||
vec3 sr1 = r1*r1*r1; sr1*=sr1;
|
|
||||||
vec3 sr2 = r2*r2*r2; sr2*=sr2;
|
|
||||||
vec3 sr3 = r3*r3*r3; sr3*=sr3;
|
|
||||||
|
|
||||||
vec3 color1 = (l5*twl5+l4*twl4+l3*twl3+l2*twl2+l1*twl1+r1*twr1+r2*twr2+r3*twr3+r4*twr4+r5*twr5)*wtt;
|
|
||||||
|
|
||||||
vec3 colmin1 = min(min(l1,r1), min(l2,r2));
|
|
||||||
vec3 colmax1 = max(max(l1,r1), max(l2,r2));
|
|
||||||
vec3 colmin2 = min(min(l3,r3), min(l4,r4));
|
|
||||||
vec3 colmax2 = max(max(l3,r3), max(l4,r4));
|
|
||||||
vec3 colmin = min(colmin1, colmin2);
|
|
||||||
vec3 colmax = max(colmax1, colmax2);
|
|
||||||
|
|
||||||
if (sharp) color1 = clamp(color1, colmin, colmax);
|
|
||||||
|
|
||||||
vec3 gtmp = vec3(1.0/6.0);
|
|
||||||
|
|
||||||
vec3 scolor1 = (sl3*swl3 + sl2*twl2 + sl1*twl1 + sr1*twr1 + sr2*twr2 + sr3*swr3)*wt;
|
|
||||||
scolor1 = pow(scolor1, gtmp); vec3 mcolor1 = scolor1;
|
|
||||||
scolor1 = min(mix(color1, scolor1, spike),1.0);
|
|
||||||
|
|
||||||
vec3 color2, scolor2, mcolor2;
|
|
||||||
|
|
||||||
if (!interb)
|
|
||||||
{
|
|
||||||
pC4+=offy;
|
|
||||||
|
|
||||||
l5 = COMPAT_TEXTURE(LinearizePass, pC4 -2.0*off2).xyz;
|
|
||||||
l4 = COMPAT_TEXTURE(LinearizePass, pC4 -3.0*offx).xyz;
|
|
||||||
l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).xyz;
|
|
||||||
l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).xyz;
|
|
||||||
l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).xyz;
|
|
||||||
r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).xyz;
|
|
||||||
r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).xyz;
|
|
||||||
r3 = COMPAT_TEXTURE(LinearizePass, pC4 +3.0*offx).xyz;
|
|
||||||
r4 = COMPAT_TEXTURE(LinearizePass, pC4 +4.0*offx).xyz;
|
|
||||||
r5 = COMPAT_TEXTURE(LinearizePass, pC4 +5.0*offx).xyz;
|
|
||||||
|
|
||||||
sl3 = l3*l3*l3; sl3*=sl3;
|
|
||||||
sl2 = l2*l2*l2; sl2*=sl2;
|
|
||||||
sl1 = l1*l1*l1; sl1*=sl1;
|
|
||||||
sr1 = r1*r1*r1; sr1*=sr1;
|
|
||||||
sr2 = r2*r2*r2; sr2*=sr2;
|
|
||||||
sr3 = r3*r3*r3; sr3*=sr3;
|
|
||||||
|
|
||||||
color2 = (l5*twl5+l4*twl4+l3*twl3+l2*twl2+l1*twl1+r1*twr1+r2*twr2+r3*twr3+r4*twr4+r5*twr5)*wtt;
|
|
||||||
|
|
||||||
colmin1 = min(min(l1,r1), min(l2,r2));
|
|
||||||
colmax1 = max(max(l1,r1), max(l2,r2));
|
|
||||||
colmin2 = min(min(l3,r3), min(l3,r3));
|
|
||||||
colmax2 = max(max(l4,r4), max(l4,r4));
|
|
||||||
colmin = min(colmin1, colmin2);
|
|
||||||
colmax = max(colmax1, colmax2);
|
|
||||||
|
|
||||||
if (sharp) color2 = clamp(color2, colmin, colmax);
|
|
||||||
|
|
||||||
scolor2 = (sl3*swl3 + sl2*twl2 + sl1*twl1 + sr1*twr1 + sr2*twr2 + sr3*swr3)*wt;
|
|
||||||
scolor2 = pow(scolor2, gtmp); mcolor2 = scolor2;
|
|
||||||
scolor2 = min(mix(color2, scolor2, spike),1.0);
|
|
||||||
}
|
|
||||||
// calculating scanlines
|
|
||||||
|
|
||||||
vec3 ctmp; vec3 mcolor; float w3; vec3 color;
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
|
|
||||||
if (!interb)
|
|
||||||
{
|
|
||||||
float shape1 = mix(scanline1, scanline2, f);
|
|
||||||
float shape2 = mix(scanline1, scanline2, 1.0-f);
|
|
||||||
|
|
||||||
float wt1 = st(f);
|
|
||||||
float wt2 = st(1.0-f);
|
|
||||||
|
|
||||||
vec3 color00 = color1*wt1 + color2*wt2;
|
|
||||||
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
|
||||||
mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2);
|
|
||||||
|
|
||||||
ctmp = color00/(wt1+wt2);
|
|
||||||
vec3 sctmp = scolor0/(wt1+wt2);
|
|
||||||
|
|
||||||
float wf1, wf2;
|
|
||||||
|
|
||||||
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b);
|
|
||||||
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b);
|
|
||||||
|
|
||||||
float f1 = f;
|
|
||||||
float f2 = 1.0-f;
|
|
||||||
|
|
||||||
if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else
|
|
||||||
if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else
|
|
||||||
{ wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);}
|
|
||||||
|
|
||||||
if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; }
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// float ws1 = max(wf1 - scansub, 0.2*wf1*wf2); wf1 = ws1/(1.0 - wf1 + ws1);
|
|
||||||
// float ws2 = max(wf2 - scansub, 0.2*wf2*wf1); wf2 = ws2/(1.0 - wf2 + ws2);
|
|
||||||
|
|
||||||
// Scanline saturation application
|
|
||||||
|
|
||||||
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
|
||||||
w3 = wf1+wf2;
|
|
||||||
|
|
||||||
cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001);
|
|
||||||
cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001);
|
|
||||||
|
|
||||||
w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1);
|
|
||||||
w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2);
|
|
||||||
|
|
||||||
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
|
||||||
|
|
||||||
float v_high1 = 1.0 + 0.3*vm;
|
|
||||||
float v_high2 = 1.0 + 0.6*vm;
|
|
||||||
float v_low = 1.0 - vm;
|
|
||||||
|
|
||||||
float ds1 = min(max(1.0-w3*w3, 2.5*f1), 1.0);
|
|
||||||
float ds2 = min(max(1.0-w3*w3, 2.5*f2), 1.0);
|
|
||||||
|
|
||||||
if (vertmask < 0.0)
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2);
|
|
||||||
}
|
|
||||||
|
|
||||||
color = gc(color1)*w1*cd1 + gc(color2)*w2*cd2;
|
|
||||||
color = min(color, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interb)
|
|
||||||
{
|
|
||||||
color = gc(color1);
|
|
||||||
mcolor = mcolor1;
|
|
||||||
}
|
|
||||||
|
|
||||||
float mx = max(max(mcolor.r,mcolor.g),mcolor.b);
|
|
||||||
mx = pow(mx, 1.20/gamma_in);
|
|
||||||
|
|
||||||
// Apply Mask
|
|
||||||
|
|
||||||
vec3 orig1 = color;
|
|
||||||
vec3 cmask = one;
|
|
||||||
|
|
||||||
vec2 maskcoord = gl_FragCoord.yx * 1.000001;
|
|
||||||
if (notate) maskcoord = maskcoord.yx;
|
|
||||||
|
|
||||||
float smask = SlotMask(maskcoord, mx);
|
|
||||||
cmask*= Mask(maskcoord, mx);
|
|
||||||
|
|
||||||
color = pow(color, vec3(mask_gamma/gamma_in));
|
|
||||||
color = color*cmask;
|
|
||||||
color = min(color,1.0);
|
|
||||||
color = color*smask;
|
|
||||||
color = pow(color, vec3(gamma_in/mask_gamma));
|
|
||||||
|
|
||||||
cmask = min(cmask*smask, 1.0);
|
|
||||||
|
|
||||||
if (interb) ctmp = color;
|
|
||||||
float colmx = pow( max( max(ctmp.r, ctmp.g), ctmp.b), 1.40/gamma_out);
|
|
||||||
float bb = mix(brightboost, brightboost1, colmx);
|
|
||||||
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
|
||||||
color*=bb;
|
|
||||||
|
|
||||||
vec3 Glow = COMPAT_TEXTURE(GlowPass, pos ).rgb;
|
|
||||||
vec3 Bloom = Glow;
|
|
||||||
float maxb = COMPAT_TEXTURE(GlowPass, pos ).a;
|
|
||||||
float vig = COMPAT_TEXTURE(PrePass, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a;
|
|
||||||
|
|
||||||
vec3 Bloom1 = min(Glow*(orig1+color), max(0.5*(colmx + orig1 - color),0.0));
|
|
||||||
color = color + bloom*Bloom1;
|
|
||||||
|
|
||||||
color = min(color, mix(one, cmask, mclip));
|
|
||||||
if (!interb) color = declip(color, pow(w3,0.6));
|
|
||||||
|
|
||||||
if (halation > 0.025) {
|
|
||||||
Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx);
|
|
||||||
color = color + (1.1-0.25*colmx)*(0.75+maxb)*Bloom*(0.75 + 0.70*pow(colmx,0.33333))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; }
|
|
||||||
|
|
||||||
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
|
||||||
if (glow >= 0.0) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + (-glow)*cmask*Glow; }
|
|
||||||
|
|
||||||
color = min(color, 1.0);
|
|
||||||
|
|
||||||
color = pow(color, vec3(1.0/gamma_out));
|
|
||||||
|
|
||||||
float corner0 = corner(pos0);
|
|
||||||
|
|
||||||
FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir)), corner0);
|
|
||||||
}
|
|
165
crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass1.slang
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
/*
|
||||||
|
CRT - Guest - NTSC - Pass1
|
||||||
|
|
||||||
|
Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
float SIGMA_HOR;
|
||||||
|
float HSHARPNESS;
|
||||||
|
float S_SHARP;
|
||||||
|
float HARNG;
|
||||||
|
float HSHARP;
|
||||||
|
float prescalex;
|
||||||
|
float prescaley;
|
||||||
|
float spike;
|
||||||
|
float internal_res;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter HSHARPNESS " Horizontal Filter Range" 1.5 1.0 8.0 0.125
|
||||||
|
#define HSHARPNESS params.HSHARPNESS
|
||||||
|
|
||||||
|
#pragma parameter SIGMA_HOR " Horizontal Blur Sigma" 0.90 0.1 7.0 0.05
|
||||||
|
#define SIGMA_HOR params.SIGMA_HOR
|
||||||
|
|
||||||
|
#pragma parameter S_SHARP " Substractive Sharpness" 0.9 0.0 2.0 0.10
|
||||||
|
#define S_SHARP params.S_SHARP
|
||||||
|
|
||||||
|
#pragma parameter HSHARP " Sharpness Definition" 1.2 0.0 2.0 0.10
|
||||||
|
#define HSHARP params.HSHARP
|
||||||
|
|
||||||
|
#pragma parameter HARNG " Substractive Sharpness Ringing" 0.4 0.0 4.0 0.10
|
||||||
|
#define HARNG params.HARNG
|
||||||
|
|
||||||
|
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
||||||
|
#define spike params.spike
|
||||||
|
|
||||||
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match
|
||||||
|
#define prescalex params.prescalex // prescale-x factor
|
||||||
|
|
||||||
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
|
#define TEX0 vTexCoord
|
||||||
|
|
||||||
|
#define OutputSize params.OutputSize
|
||||||
|
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
||||||
|
|
||||||
|
#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 LinearizePass;
|
||||||
|
|
||||||
|
float invsqrsigma = 1.0/(2.0*SIGMA_HOR*SIGMA_HOR);
|
||||||
|
|
||||||
|
float gaussian(float x)
|
||||||
|
{
|
||||||
|
return exp(-x*x*invsqrsigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 SourceSize = params.OriginalSize * vec4(2.0*prescalex, 1.0, 0.5/prescalex, 1.0);
|
||||||
|
|
||||||
|
float f = fract(SourceSize.x * vTexCoord.x);
|
||||||
|
f = 0.5 - f;
|
||||||
|
vec2 tex = floor(SourceSize.xy * vTexCoord)*SourceSize.zw + 0.5*SourceSize.zw;
|
||||||
|
vec3 color = 0.0.xxx;
|
||||||
|
float scolor = 0.0;
|
||||||
|
vec2 dx = vec2(SourceSize.z, 0.0);
|
||||||
|
|
||||||
|
float w = 0.0;
|
||||||
|
float swsum = 0.0;
|
||||||
|
float wsum = 0.0;
|
||||||
|
vec3 pixel;
|
||||||
|
|
||||||
|
float hsharpness = HSHARPNESS;
|
||||||
|
vec3 cmax = 0.0.xxx;
|
||||||
|
vec3 cmin = 1.0.xxx;
|
||||||
|
float sharp = gaussian(hsharpness) * S_SHARP;
|
||||||
|
float maxsharp = 0.20;
|
||||||
|
float FPR = hsharpness;
|
||||||
|
float fpx = 0.0;
|
||||||
|
float sp = 0.0;
|
||||||
|
float sw = 0.0;
|
||||||
|
|
||||||
|
float ts = 0.025;
|
||||||
|
vec3 luma = vec3(0.2126, 0.7152, 0.0722);
|
||||||
|
|
||||||
|
float LOOPSIZE = ceil(2.0*FPR);
|
||||||
|
float CLAMPSIZE = round(2.0*LOOPSIZE/3.0);
|
||||||
|
|
||||||
|
float n = -LOOPSIZE;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx).rgb;
|
||||||
|
sp = max(max(pixel.r,pixel.g),pixel.b);
|
||||||
|
|
||||||
|
w = gaussian(n+f) - sharp;
|
||||||
|
fpx = abs(n+f-sign(n)*FPR)/FPR;
|
||||||
|
if (abs(n) <= CLAMPSIZE) { cmax = max(cmax, pixel); cmin = min(cmin, pixel); }
|
||||||
|
if (w < 0.0) w = clamp(w, mix(-maxsharp, 0.0, pow(fpx, HSHARP)), 0.0);
|
||||||
|
|
||||||
|
color = color + w * pixel;
|
||||||
|
wsum = wsum + w;
|
||||||
|
|
||||||
|
sw = max(w, 0.0) * (dot(pixel,luma) + ts);
|
||||||
|
scolor = scolor + sw * sp;
|
||||||
|
swsum = swsum + sw;
|
||||||
|
|
||||||
|
n = n + 1.0;
|
||||||
|
|
||||||
|
} while (n <= LOOPSIZE);
|
||||||
|
|
||||||
|
color = color / wsum;
|
||||||
|
scolor = scolor / swsum;
|
||||||
|
|
||||||
|
color = clamp(mix(clamp(color, cmin, cmax), color, HARNG), 0.0, 1.0);
|
||||||
|
|
||||||
|
scolor = clamp(mix(max(max(color.r, color.g),color.b), scolor, spike), 0.0, 1.0);
|
||||||
|
|
||||||
|
FragColor = vec4(color, scolor);
|
||||||
|
}
|
399
crt/shaders/guest/advanced/crt-guest-advanced-ntsc-pass2.slang
Normal file
|
@ -0,0 +1,399 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
/*
|
||||||
|
CRT - Guest - Advanced - NTSC
|
||||||
|
|
||||||
|
Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
float IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
||||||
|
h_sharp, s_sharp, warpX, warpY, glow, shadowMask, masksize, vertmask, ring;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
float bloom;
|
||||||
|
float halation;
|
||||||
|
float scans;
|
||||||
|
float gamma_c;
|
||||||
|
float gamma_out;
|
||||||
|
float overscanX;
|
||||||
|
float overscanY;
|
||||||
|
float intres;
|
||||||
|
float prescalex;
|
||||||
|
float c_shape;
|
||||||
|
float blendMode;
|
||||||
|
float scangamma;
|
||||||
|
float rolling_scan;
|
||||||
|
float sborder;
|
||||||
|
float scan_falloff;
|
||||||
|
float bloom_dist;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
||||||
|
#define glow params.glow // Glow Strength
|
||||||
|
|
||||||
|
#pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05
|
||||||
|
#define bloom global.bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter mask_bloom " Mask Bloom" 0.0 0.0 2.0 0.05
|
||||||
|
#define mask_bloom params.mask_bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter bloom_dist " Bloom Distribution" 0.0 0.0 3.0 0.05
|
||||||
|
#define bloom_dist global.bloom_dist // bloom effect distribution
|
||||||
|
|
||||||
|
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
||||||
|
#define halation global.halation // halation effect
|
||||||
|
|
||||||
|
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
||||||
|
#define gamma_c global.gamma_c // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05
|
||||||
|
#define brightboost params.brightboost // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025
|
||||||
|
#define brightboost1 params.brightboost1 // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
||||||
|
#define gsl params.gsl // Alternate scanlines
|
||||||
|
|
||||||
|
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5
|
||||||
|
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
||||||
|
|
||||||
|
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 70.0 1.0
|
||||||
|
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
||||||
|
|
||||||
|
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 5.0 0.05
|
||||||
|
#define beam_min params.beam_min // dark area beam min - narrow
|
||||||
|
|
||||||
|
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025
|
||||||
|
#define beam_max params.beam_max // bright area beam max - wide
|
||||||
|
|
||||||
|
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
||||||
|
#define beam_size params.beam_size // increased max. beam size
|
||||||
|
|
||||||
|
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
||||||
|
#define vertmask params.vertmask // Scanline deconvergence colors
|
||||||
|
|
||||||
|
#pragma parameter scans " Scanline Saturation / Mask Falloff" 0.60 0.0 2.5 0.05
|
||||||
|
#define scans global.scans // scanline saturation
|
||||||
|
|
||||||
|
#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.25 2.0 0.05
|
||||||
|
#define scan_falloff global.scan_falloff // scanline falloff
|
||||||
|
|
||||||
|
#pragma parameter scangamma " Scanline Gamma" 2.40 0.5 5.0 0.05
|
||||||
|
#define scangamma global.scangamma
|
||||||
|
|
||||||
|
#pragma parameter rolling_scan " Rolling Scanlines" 0.0 -1.0 1.0 0.01
|
||||||
|
#define rolling_scan global.rolling_scan // rolling scanlines
|
||||||
|
|
||||||
|
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with linearize pass, values must match
|
||||||
|
|
||||||
|
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
||||||
|
#define IOS params.IOS // Smart Integer Scaling
|
||||||
|
|
||||||
|
#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
|
||||||
|
#define OS params.OS // Do overscan
|
||||||
|
|
||||||
|
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
||||||
|
#define BLOOM params.BLOOM // Bloom overscan percentage
|
||||||
|
|
||||||
|
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpX params.warpX // Curvature X
|
||||||
|
|
||||||
|
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpY params.warpY // Curvature Y
|
||||||
|
|
||||||
|
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
||||||
|
#define c_shape global.c_shape // curvature shape
|
||||||
|
|
||||||
|
#pragma parameter overscanX " Overscan X original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanX global.overscanX // OverscanX pixels
|
||||||
|
|
||||||
|
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanY global.overscanY // OverscanY pixels
|
||||||
|
|
||||||
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0
|
||||||
|
#define prescalex global.prescalex // prescale-x factor
|
||||||
|
|
||||||
|
|
||||||
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
|
#define TEX0 vTexCoord
|
||||||
|
|
||||||
|
#define OutputSize global.OutputSize
|
||||||
|
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
||||||
|
|
||||||
|
#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 LinearizePass;
|
||||||
|
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D Pass1;
|
||||||
|
|
||||||
|
#define eps 1e-8
|
||||||
|
|
||||||
|
float st(float x)
|
||||||
|
{
|
||||||
|
return exp2(-10.0*x*x);
|
||||||
|
}
|
||||||
|
|
||||||
|
float st1(float x)
|
||||||
|
{
|
||||||
|
return exp2(-7.0*x*x);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sw0(float x, float color, float scanline)
|
||||||
|
{
|
||||||
|
float tmp = mix(beam_min, beam_max, color);
|
||||||
|
float ex = x*tmp;
|
||||||
|
ex = (gsl > -0.5) ? ex*ex : mix(ex*ex, ex*ex*ex, 0.4);
|
||||||
|
return exp2(-scanline*ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sw1(float x, float color, float scanline)
|
||||||
|
{
|
||||||
|
x = mix (x, beam_min*x, max(x-0.4*color,0.0));
|
||||||
|
float tmp = mix(1.2*beam_min, beam_max, color);
|
||||||
|
float ex = x*tmp;
|
||||||
|
return exp2(-scanline*ex*ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sw2(float x, float color, float scanline)
|
||||||
|
{
|
||||||
|
float tmp = mix((2.5-0.5*color)*beam_min, beam_max, color);
|
||||||
|
tmp = mix(beam_max, tmp, pow(x, color+0.3));
|
||||||
|
float ex = x*tmp;
|
||||||
|
return exp2(-scanline*ex*ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Warp(vec2 pos)
|
||||||
|
{
|
||||||
|
pos = pos*2.0-1.0;
|
||||||
|
pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape);
|
||||||
|
return pos*0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Overscan(vec2 pos, float dx, float dy){
|
||||||
|
pos=pos*2.0-1.0;
|
||||||
|
pos*=vec2(dx,dy);
|
||||||
|
return pos*0.5+0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 gc(vec3 c)
|
||||||
|
{
|
||||||
|
float mc = max(max(c.r,c.g),c.b);
|
||||||
|
float mg = pow(mc, 1.0/gamma_c);
|
||||||
|
return c * mg/(mc + eps);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 SourceSize = global.OriginalSize * vec4(prescalex, 1.0, 1.0/prescalex, 1.0);
|
||||||
|
|
||||||
|
SourceSize*= vec4(2.0, 1.0, 0.5, 1.0);
|
||||||
|
|
||||||
|
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.5,0.5)).a;
|
||||||
|
|
||||||
|
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
||||||
|
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
||||||
|
bool interb = (intera < 0.5);
|
||||||
|
|
||||||
|
float SourceY = SourceSize.y;
|
||||||
|
float sy = 1.0;
|
||||||
|
if (global.intres == 0.5) sy = SourceY/224.0; else
|
||||||
|
if (global.intres == 1.0) sy = SourceY/240.0; else
|
||||||
|
if (global.intres > 1.25) sy = global.intres;
|
||||||
|
SourceSize*=vec4(1.0, 1.0/sy, 1.0, sy);
|
||||||
|
|
||||||
|
// Calculating texel coordinates
|
||||||
|
|
||||||
|
vec2 texcoord = TEX0.xy;
|
||||||
|
if (IOS > 0.0 && !interb){
|
||||||
|
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
||||||
|
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
||||||
|
vec2 diff = ofactor/intfactor;
|
||||||
|
float scan = diff.y;
|
||||||
|
texcoord = Overscan(texcoord, scan, scan);
|
||||||
|
if (IOS == 1.0 || IOS == 3.0) texcoord = vec2(TEX0.x, texcoord.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
||||||
|
texcoord = Overscan(texcoord, factor, factor);
|
||||||
|
|
||||||
|
texcoord = Overscan(texcoord, (SourceSize.x - overscanX)/SourceSize.x, (SourceSize.y - overscanY)/SourceSize.y);
|
||||||
|
|
||||||
|
vec2 pos = Warp(texcoord);
|
||||||
|
vec2 pos0 = Warp(TEX0.xy);
|
||||||
|
|
||||||
|
vec2 coffset = vec2(0.5, 0.5);
|
||||||
|
|
||||||
|
vec2 ps = SourceSize.zw;
|
||||||
|
vec2 OGL2Pos = pos * SourceSize.xy - coffset;
|
||||||
|
vec2 fp = fract(OGL2Pos);
|
||||||
|
|
||||||
|
vec2 dx = vec2(ps.x,0.0);
|
||||||
|
vec2 dy = vec2(0.0, ps.y);
|
||||||
|
|
||||||
|
// Reading the texels
|
||||||
|
|
||||||
|
float f = fp.y;
|
||||||
|
|
||||||
|
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
|
||||||
|
pC4.x = pos.x;
|
||||||
|
if (interb) pC4.y = pos.y;
|
||||||
|
|
||||||
|
vec3 color1 = COMPAT_TEXTURE(Pass1, pC4 ).rgb;
|
||||||
|
vec3 scolor1 = COMPAT_TEXTURE(Pass1, pC4 ).aaa;
|
||||||
|
|
||||||
|
if(!interb) color1 = pow(color1, vec3(scangamma/gamma_in));
|
||||||
|
|
||||||
|
pC4+=dy;
|
||||||
|
|
||||||
|
vec3 color2 = COMPAT_TEXTURE(Pass1, pC4 ).rgb;
|
||||||
|
vec3 scolor2 = COMPAT_TEXTURE(Pass1, pC4 ).aaa;
|
||||||
|
|
||||||
|
if(!interb) color2 = pow(color2, vec3(scangamma/gamma_in));
|
||||||
|
|
||||||
|
vec3 ctmp = color1; float w3 = 1.0; vec3 color = color1;
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
|
||||||
|
if (!interb)
|
||||||
|
{
|
||||||
|
// calculating scanlines
|
||||||
|
|
||||||
|
float shape1 = mix(scanline1, scanline2, f);
|
||||||
|
float shape2 = mix(scanline1, scanline2, 1.0-f);
|
||||||
|
|
||||||
|
float wt1 = st(f);
|
||||||
|
float wt2 = st(1.0-f);
|
||||||
|
|
||||||
|
vec3 color00 = color1*wt1 + color2*wt2;
|
||||||
|
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
||||||
|
|
||||||
|
ctmp = color00/(wt1+wt2);
|
||||||
|
vec3 sctmp = scolor0/(wt1+wt2);
|
||||||
|
|
||||||
|
float wf1, wf2;
|
||||||
|
|
||||||
|
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = pow(max(max(cref1.r,cref1.g),cref1.b), scan_falloff);
|
||||||
|
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = pow(max(max(cref2.r,cref2.g),cref2.b), scan_falloff);
|
||||||
|
|
||||||
|
float f1 = f;
|
||||||
|
float f2 = 1.0-f;
|
||||||
|
|
||||||
|
float scanpix = SourceSize.x/OutputSize.x;
|
||||||
|
|
||||||
|
f1 = fract(f1 + rolling_scan*float(global.FrameCount)*scanpix);
|
||||||
|
f2 = 1.0 - f1;
|
||||||
|
|
||||||
|
if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else
|
||||||
|
if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else
|
||||||
|
{ wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);}
|
||||||
|
|
||||||
|
if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; }
|
||||||
|
|
||||||
|
// Scanline saturation application
|
||||||
|
|
||||||
|
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
||||||
|
w3 = wf1+wf2;
|
||||||
|
|
||||||
|
float mc1 = max(max(color1.r,color1.g),color1.b) + eps;
|
||||||
|
float mc2 = max(max(color2.r,color2.g),color2.b) + eps;
|
||||||
|
|
||||||
|
cref1 = color1 / mc1; cref1=cref1*cref1; cref1*=cref1;
|
||||||
|
cref2 = color2 / mc2; cref2=cref2*cref2; cref2*=cref2;
|
||||||
|
|
||||||
|
w1 = max( mix(w1*mix(one, cref1, scans), w1, wf1*min((1.0+0.15*scans), 1.2)), 0.0); w1 = min(w1*color1, mc1)/(color1 + eps);
|
||||||
|
w2 = max( mix(w2*mix(one, cref2, scans), w2, wf2*min((1.0+0.15*scans), 1.2)), 0.0); w2 = min(w2*color2, mc2)/(color2 + eps);
|
||||||
|
|
||||||
|
// Scanline Deconvergence
|
||||||
|
|
||||||
|
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
||||||
|
|
||||||
|
float v_high1 = 1.0 + 0.3*vm;
|
||||||
|
float v_high2 = 1.0 + 0.6*vm;
|
||||||
|
float v_low = 1.0 - vm;
|
||||||
|
|
||||||
|
float ds1 = min(max(1.0-w3*w3, 2.5*f1), 1.0);
|
||||||
|
float ds2 = min(max(1.0-w3*w3, 2.5*f2), 1.0);
|
||||||
|
|
||||||
|
if (vertmask < 0.0)
|
||||||
|
{
|
||||||
|
cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1);
|
||||||
|
cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1);
|
||||||
|
cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2);
|
||||||
|
}
|
||||||
|
|
||||||
|
color = gc(color1)*w1*cd1 + gc(color2)*w2*cd2;
|
||||||
|
|
||||||
|
if (abs(rolling_scan) > 0.005)
|
||||||
|
{
|
||||||
|
wt1 = st1(f);
|
||||||
|
wt2 = st1(1.0-f);
|
||||||
|
color00 = (color1*wt1 + color2*wt2)/(wt1+wt2);
|
||||||
|
color = gc(color00) * mix(w1+w2, w3.xxx, max(wf1,wf2));
|
||||||
|
}
|
||||||
|
|
||||||
|
color = min(color, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interb)
|
||||||
|
{
|
||||||
|
color = gc(color1);
|
||||||
|
}
|
||||||
|
|
||||||
|
float colmx = pow(max(max(ctmp.r,ctmp.g),ctmp.b), 1.40/gamma_in);
|
||||||
|
|
||||||
|
if(!interb) color = pow( color, vec3(gamma_in/scangamma) );
|
||||||
|
|
||||||
|
FragColor = vec4(color, colmx);
|
||||||
|
}
|
|
@ -1,904 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - Advanced
|
|
||||||
|
|
||||||
Copyright (C) 2018-2021 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
|
||||||
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
|
||||||
h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask,
|
|
||||||
slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float bloom;
|
|
||||||
float halation;
|
|
||||||
float scans;
|
|
||||||
float scansub;
|
|
||||||
float slotms;
|
|
||||||
float mclip;
|
|
||||||
float gamma_c;
|
|
||||||
float mask_gamma;
|
|
||||||
float smart_ei;
|
|
||||||
float ei_limit;
|
|
||||||
float sth;
|
|
||||||
float gamma_out;
|
|
||||||
float overscanY;
|
|
||||||
float intres;
|
|
||||||
float prescalex;
|
|
||||||
float c_shape;
|
|
||||||
float barspeed;
|
|
||||||
float barintensity;
|
|
||||||
float bardir;
|
|
||||||
float blendMode;
|
|
||||||
float scangamma;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter blendMode "NTSC Blend Mode (Main Mode Control)" 1.0 0.0 2.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
|
||||||
#define glow params.glow // Glow Strength
|
|
||||||
|
|
||||||
#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05
|
|
||||||
#define bloom global.bloom // bloom effect
|
|
||||||
|
|
||||||
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
|
||||||
#define halation global.halation // halation effect
|
|
||||||
|
|
||||||
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
|
||||||
#define gamma_c global.gamma_c // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.25 0.25 10.0 0.05
|
|
||||||
#define brightboost params.brightboost // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025
|
|
||||||
#define brightboost1 params.brightboost1 // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
|
||||||
#define gsl params.gsl // Alternate scanlines
|
|
||||||
|
|
||||||
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 0.0 20.0 0.5
|
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 40.0 1.0
|
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 0.05
|
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
|
||||||
|
|
||||||
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 2.5 0.05
|
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
|
||||||
|
|
||||||
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
|
||||||
#define beam_size params.beam_size // increased max. beam size
|
|
||||||
|
|
||||||
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
|
||||||
#define vertmask params.vertmask // Scanline deconvergence colors
|
|
||||||
|
|
||||||
#pragma parameter scans " Scanline Saturation" 0.65 0.0 1.0 0.05
|
|
||||||
#define scans global.scans // scanline saturation
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// #pragma parameter scansub " Scanline darken 'edges'" 0.0 0.0 0.30 0.005
|
|
||||||
// #define scansub global.scansub // scanline substraction
|
|
||||||
|
|
||||||
#pragma parameter spike " Scanline Spike Removal" 0.7 0.0 2.0 0.10
|
|
||||||
#define spike params.spike
|
|
||||||
|
|
||||||
#pragma parameter scangamma " Scanline Gamma" 2.40 0.5 5.0 0.05
|
|
||||||
#define scangamma global.scangamma
|
|
||||||
|
|
||||||
#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter h_sharp " Horizontal sharpness" 3.70 0.10 15.0 0.10
|
|
||||||
#define h_sharp params.h_sharp // pixel sharpness
|
|
||||||
|
|
||||||
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.20 0.0 1.5 0.10
|
|
||||||
#define s_sharp params.s_sharp // substractive sharpness
|
|
||||||
|
|
||||||
#pragma parameter smart_ei " Smart Edges Effect Strength" 0.0 0.0 20.0 0.25
|
|
||||||
#define smart_ei global.smart_ei // smart edge handling
|
|
||||||
|
|
||||||
#pragma parameter ei_limit " Smart Edges Effect Strength Limit" 2.0 1.0 12.0 0.1
|
|
||||||
#define ei_limit global.ei_limit // smart edge handling
|
|
||||||
|
|
||||||
#pragma parameter sth " Smart Edges Smoothing Threshold" 0.20 0.0 1.0 0.01
|
|
||||||
#define sth global.sth // corner size
|
|
||||||
|
|
||||||
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with linearize pass, values must match
|
|
||||||
|
|
||||||
#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0
|
|
||||||
#define TATE params.TATE // Screen orientation
|
|
||||||
|
|
||||||
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
|
||||||
#define IOS params.IOS // Smart Integer Scaling
|
|
||||||
|
|
||||||
#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
|
|
||||||
#define OS params.OS // Do overscan
|
|
||||||
|
|
||||||
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
|
||||||
#define BLOOM params.BLOOM // Bloom overscan percentage
|
|
||||||
|
|
||||||
#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01
|
|
||||||
#define csize params.csize // corner size
|
|
||||||
|
|
||||||
#pragma parameter bsize " Border smoothness" 600.0 100.0 700.0 10.0
|
|
||||||
#define bsize params.bsize // border smoothness
|
|
||||||
|
|
||||||
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01
|
|
||||||
|
|
||||||
#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
|
||||||
#define warpX params.warpX // Curvature X
|
|
||||||
|
|
||||||
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01
|
|
||||||
#define warpY params.warpY // Curvature Y
|
|
||||||
|
|
||||||
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
|
||||||
#define c_shape global.c_shape // curvature shape
|
|
||||||
|
|
||||||
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -50.0 50.0 1.0
|
|
||||||
#define overscanY global.overscanY // OverscanY pixels
|
|
||||||
|
|
||||||
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0
|
|
||||||
#define prescalex global.prescalex // prescale-x factor
|
|
||||||
|
|
||||||
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0
|
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
|
||||||
|
|
||||||
#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05
|
|
||||||
#define maskstr params.maskstr // CGWG Mask Strength
|
|
||||||
|
|
||||||
#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05
|
|
||||||
#define mcut params.mcut // Mask 5-7 dark color strength
|
|
||||||
|
|
||||||
#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0
|
|
||||||
#define masksize params.masksize // Mask Size
|
|
||||||
|
|
||||||
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
|
||||||
#define maskDark params.maskDark // Dark "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.025
|
|
||||||
#define mask_gamma global.mask_gamma // Mask application gamma
|
|
||||||
|
|
||||||
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask params.slotmask
|
|
||||||
|
|
||||||
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask1 params.slotmask1
|
|
||||||
|
|
||||||
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 6.0 0.5
|
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
|
||||||
|
|
||||||
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
|
||||||
|
|
||||||
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
|
||||||
#define slotms global.slotms // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05
|
|
||||||
#define mclip global.mclip // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter gamma_out "Gamma out" 2.0 1.0 5.0 0.05
|
|
||||||
#define gamma_out global.gamma_out // output gamma
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
#define OutputSize global.OutputSize
|
|
||||||
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
|
||||||
|
|
||||||
#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.000001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma stage fragment
|
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
|
||||||
layout(location = 0) out vec4 FragColor;
|
|
||||||
layout(set = 0, binding = 2) uniform sampler2D LinearizePass;
|
|
||||||
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
|
||||||
layout(set = 0, binding = 4) uniform sampler2D GlowPass;
|
|
||||||
layout(set = 0, binding = 5) uniform sampler2D BloomPass;
|
|
||||||
layout(set = 0, binding = 6) uniform sampler2D PrePass0;
|
|
||||||
layout(set = 0, binding = 7) uniform sampler2D NtscPass;
|
|
||||||
|
|
||||||
#define eps 1e-8
|
|
||||||
|
|
||||||
float st(float x)
|
|
||||||
{
|
|
||||||
return exp2(-10.0*x*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw0(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix(beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
ex = (gsl > -0.5) ? ex*ex : mix(ex*ex, ex*ex*ex, 0.4);
|
|
||||||
return exp2(-scanline*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw1(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
x = mix (x, beam_min*x, max(x-0.4*color,0.0));
|
|
||||||
float tmp = mix(1.2*beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw2(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix((2.5-0.5*color)*beam_min, beam_max, color);
|
|
||||||
tmp = mix(beam_max, tmp, pow(x, color+0.3));
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shadow mask (1-4 from PD CRT Lottes shader).
|
|
||||||
|
|
||||||
vec3 Mask(vec2 pos, float mx)
|
|
||||||
{
|
|
||||||
pos = floor(pos/masksize);
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 0.0) + 1.0, 1.0, mx);
|
|
||||||
float mc = 1.0 - max(maskstr, 0.0);
|
|
||||||
|
|
||||||
// No mask
|
|
||||||
if (shadowMask == -1.0)
|
|
||||||
{
|
|
||||||
mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phosphor.
|
|
||||||
else if (shadowMask == 0.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x*0.5);
|
|
||||||
if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
|
||||||
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very compressed TV style shadow mask.
|
|
||||||
else if (shadowMask == 1.0)
|
|
||||||
{
|
|
||||||
float line = maskLight;
|
|
||||||
float odd = 0.0;
|
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
|
||||||
odd = 1.0;
|
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
|
||||||
line = maskDark;
|
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
|
|
||||||
mask*=line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aperture-grille.
|
|
||||||
else if (shadowMask == 2.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stretched VGA style shadow mask (same as prior shaders).
|
|
||||||
else if (shadowMask == 3.0)
|
|
||||||
{
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA style shadow mask.
|
|
||||||
else if (shadowMask == 4.0)
|
|
||||||
{
|
|
||||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 5
|
|
||||||
else if (shadowMask == 5.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5)
|
|
||||||
{ mask.r = 1.0;
|
|
||||||
mask.b = 1.0;
|
|
||||||
}
|
|
||||||
else mask.g = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 6
|
|
||||||
else if (shadowMask == 6.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
if (pos.x < 0.333) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.666) mask.g = 1.0;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BW Trinitron mask 7
|
|
||||||
else if (shadowMask == 7.0)
|
|
||||||
{
|
|
||||||
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
mask = vec3(maskTmp);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5) mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4k mask
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mask = vec3(mc);
|
|
||||||
pos.x = fract(pos.x * 0.25);
|
|
||||||
if (pos.x < 0.2) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
|
||||||
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SlotMask(vec2 pos, float m)
|
|
||||||
{
|
|
||||||
if (slotmask == 0.0) return 1.0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pos = floor(pos/slotms);
|
|
||||||
float mlen = slotwidth*2.0;
|
|
||||||
float px = fract(pos.x/mlen);
|
|
||||||
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
|
||||||
float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m);
|
|
||||||
float slot = 1.0;
|
|
||||||
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
|
||||||
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Warp(vec2 pos)
|
|
||||||
{
|
|
||||||
pos = pos*2.0-1.0;
|
|
||||||
pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape);
|
|
||||||
return pos*0.5 + 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Overscan(vec2 pos, float dx, float dy){
|
|
||||||
pos=pos*2.0-1.0;
|
|
||||||
pos*=vec2(dx,dy);
|
|
||||||
return pos*0.5+0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
float humbar(float pos)
|
|
||||||
{
|
|
||||||
if (global.barintensity == 0.0) return 1.0; else
|
|
||||||
{
|
|
||||||
pos = (global.barintensity >= 0.0) ? pos : (1.0-pos);
|
|
||||||
pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0));
|
|
||||||
pos = (global.barintensity < 0.0) ? pos : (1.0-pos);
|
|
||||||
return (1.0-global.barintensity) + global.barintensity*pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Borrowed from cgwg's crt-geom, under GPL
|
|
||||||
|
|
||||||
float corner(vec2 coord)
|
|
||||||
{
|
|
||||||
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
|
|
||||||
vec2 cdist = vec2(max(csize/3.0, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002)));
|
|
||||||
coord = (cdist - min(coord,cdist));
|
|
||||||
float dist = sqrt(dot(coord,coord));
|
|
||||||
return clamp((cdist.x-dist)*bsize,0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 gc(vec3 c)
|
|
||||||
{
|
|
||||||
float mc = max(max(c.r,c.g),c.b);
|
|
||||||
float mg = pow(mc, 1.0/gamma_c);
|
|
||||||
return c * mg/(mc + eps);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 plant (vec3 tar, float r)
|
|
||||||
{
|
|
||||||
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
|
||||||
return tar * r / t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 SourceSize = global.OriginalSize * vec4(prescalex, 1.0, 1.0/prescalex, 1.0);
|
|
||||||
|
|
||||||
bool nmode1 = (global.blendMode == 1.0);
|
|
||||||
bool nmode2 = (global.blendMode > 1.5);
|
|
||||||
|
|
||||||
if (nmode2) SourceSize*= vec4(2.0, 1.0, 0.5, 1.0);
|
|
||||||
|
|
||||||
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.5,0.5)).a;
|
|
||||||
|
|
||||||
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
|
||||||
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
|
||||||
bool interb = (intera < 0.75);
|
|
||||||
bool notate = (TATE < 0.5);
|
|
||||||
|
|
||||||
float SourceY = mix(SourceSize.y, SourceSize.x, TATE);
|
|
||||||
float sy = 1.0;
|
|
||||||
if (global.intres == 0.5) sy = SourceY/224.0; else
|
|
||||||
if (global.intres == 1.0) sy = SourceY/240.0; else
|
|
||||||
if (global.intres > 1.25) sy = global.intres;
|
|
||||||
if (notate) SourceSize*=vec4(1.0, 1.0/sy, 1.0, sy); else SourceSize*=vec4(1.0/sy, 1.0, sy, 1.0);
|
|
||||||
|
|
||||||
// Calculating texel coordinates
|
|
||||||
|
|
||||||
vec2 texcoord = TEX0.xy;
|
|
||||||
if (IOS > 0.0){
|
|
||||||
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
|
||||||
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
|
||||||
vec2 diff = ofactor/intfactor;
|
|
||||||
float scan = mix(diff.y, diff.x, TATE);
|
|
||||||
texcoord = Overscan(texcoord, scan, scan);
|
|
||||||
if (IOS == 1.0 || IOS == 3.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
|
||||||
texcoord = Overscan(texcoord, factor, factor);
|
|
||||||
|
|
||||||
texcoord = Overscan(texcoord, 1.0, (SourceSize.y - overscanY)/SourceSize.y);
|
|
||||||
|
|
||||||
vec2 pos = Warp(texcoord);
|
|
||||||
vec2 pos0 = Warp(TEX0.xy);
|
|
||||||
|
|
||||||
bool smarte = (smart_ei > 0.0 && notate); // smart edge interpolation on / off
|
|
||||||
|
|
||||||
vec2 coffset = vec2(0.5, 0.5);
|
|
||||||
|
|
||||||
vec2 ps = SourceSize.zw;
|
|
||||||
vec2 OGL2Pos = pos * SourceSize.xy - coffset;
|
|
||||||
vec2 fp = fract(OGL2Pos);
|
|
||||||
|
|
||||||
vec2 dx = vec2(ps.x,0.0);
|
|
||||||
vec2 dy = vec2(0.0, ps.y);
|
|
||||||
|
|
||||||
// Reading the texels
|
|
||||||
vec2 x2 = 2.0*dx;
|
|
||||||
vec2 y2 = 2.0*dy;
|
|
||||||
|
|
||||||
vec2 offx = dx;
|
|
||||||
vec2 off2 = x2;
|
|
||||||
vec2 offy = dy;
|
|
||||||
float fpx = fp.x;
|
|
||||||
if(!notate)
|
|
||||||
{
|
|
||||||
offx = dy;
|
|
||||||
off2 = y2;
|
|
||||||
offy = dx;
|
|
||||||
fpx = fp.y;
|
|
||||||
}
|
|
||||||
float f = (notate) ? fp.y : fp.x;
|
|
||||||
|
|
||||||
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
|
|
||||||
|
|
||||||
vec2 pC5 = mix(vec2(pos.x, pC4.y), vec2(pC4.x, pos.y), float(!notate));
|
|
||||||
|
|
||||||
if (interb) pC4.y = pos.y;
|
|
||||||
|
|
||||||
float zero = exp2(-h_sharp);
|
|
||||||
float sharp1 = s_sharp * zero;
|
|
||||||
|
|
||||||
float fdivider = min(prescalex + 0.325*float(nmode2), 2.0);
|
|
||||||
|
|
||||||
float wl3 = (2.0 + fpx)/fdivider;
|
|
||||||
float wl2 = (1.0 + fpx)/fdivider;
|
|
||||||
float wl1 = ( fpx)/fdivider;
|
|
||||||
float wr1 = (1.0 - fpx)/fdivider;
|
|
||||||
float wr2 = (2.0 - fpx)/fdivider;
|
|
||||||
float wr3 = (3.0 - fpx)/fdivider;
|
|
||||||
|
|
||||||
wl3*=wl3; wl3 = exp2(-h_sharp*wl3);
|
|
||||||
wl2*=wl2; wl2 = exp2(-h_sharp*wl2);
|
|
||||||
wl1*=wl1; wl1 = exp2(-h_sharp*wl1);
|
|
||||||
wr1*=wr1; wr1 = exp2(-h_sharp*wr1);
|
|
||||||
wr2*=wr2; wr2 = exp2(-h_sharp*wr2);
|
|
||||||
wr3*=wr3; wr3 = exp2(-h_sharp*wr3);
|
|
||||||
|
|
||||||
float fp1 = 1.-fpx;
|
|
||||||
|
|
||||||
float twl3 = max(wl3 - sharp1, 0.0);
|
|
||||||
float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1));
|
|
||||||
float twl1 = max(wl1 - sharp1, 0.0);
|
|
||||||
float twr1 = max(wr1 - sharp1, 0.0);
|
|
||||||
float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx));
|
|
||||||
float twr3 = max(wr3 - sharp1, 0.0);
|
|
||||||
|
|
||||||
bool sharp = (sharp1 > 0.0);
|
|
||||||
|
|
||||||
float rwl3, rwl2, rwr2;
|
|
||||||
|
|
||||||
float rwl1 = twl1;
|
|
||||||
float rwr1 = twr1;
|
|
||||||
vec3 c1, c2;
|
|
||||||
|
|
||||||
if (smarte)
|
|
||||||
{
|
|
||||||
rwl3 = wl3; rwl2 = wl2;
|
|
||||||
rwl1 = wl1; rwr1 = wr1;
|
|
||||||
rwr2 = wr2;
|
|
||||||
twl3 = 0.0; twr3 = 0.0;
|
|
||||||
vec3 t = COMPAT_TEXTURE(AvgLumPass, pC4 - offy).xyz;
|
|
||||||
vec3 a = COMPAT_TEXTURE(AvgLumPass, pC4 ).xyz;
|
|
||||||
vec3 b = COMPAT_TEXTURE(AvgLumPass, pC4 + offy).xyz;
|
|
||||||
vec3 d = COMPAT_TEXTURE(AvgLumPass, pC4 +dy+dy).xyz;
|
|
||||||
c1 = (h_sharp > 2.6) ? a : min(a,(t + a + b)/3.0); c1 = max(c1 - sth, 0.0);
|
|
||||||
c2 = (h_sharp > 2.6) ? b : min(b,(a + b + d)/3.0); c2 = max(c2 - sth, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 cc, l3, l2, l1, r1, r2, r3, sl2, sl1, sr1, sr2, color1, color2, colmin, colmax;
|
|
||||||
|
|
||||||
if (nmode2)
|
|
||||||
{
|
|
||||||
l3 = pow(COMPAT_TEXTURE(NtscPass, pC4 -off2).rgb, gamma_in.xxx);
|
|
||||||
l2 = pow(COMPAT_TEXTURE(NtscPass, pC4 -offx).rgb, gamma_in.xxx);
|
|
||||||
l1 = pow(COMPAT_TEXTURE(NtscPass, pC4 ).rgb, gamma_in.xxx);
|
|
||||||
r1 = pow(COMPAT_TEXTURE(NtscPass, pC4 +offx).rgb, gamma_in.xxx);
|
|
||||||
r2 = pow(COMPAT_TEXTURE(NtscPass, pC4 +off2).rgb, gamma_in.xxx);
|
|
||||||
r3 = pow(COMPAT_TEXTURE(NtscPass, pC4 +offx+off2).rgb, gamma_in.xxx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).rgb;
|
|
||||||
l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb;
|
|
||||||
l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb;
|
|
||||||
r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb;
|
|
||||||
r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).rgb;
|
|
||||||
r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+off2).rgb;
|
|
||||||
cc = pow(COMPAT_TEXTURE(NtscPass, pC5).rgb, gamma_in.xxx);
|
|
||||||
}
|
|
||||||
colmin = min(min(l1,r1), min(l2,r2));
|
|
||||||
colmax = max(max(l1,r1), max(l2,r2));
|
|
||||||
|
|
||||||
if (smarte)
|
|
||||||
{
|
|
||||||
float pc = min(1.0 + smart_ei*c1.y, ei_limit);
|
|
||||||
float pl = min(1.0 + smart_ei*max(c1.y,c1.x), ei_limit);
|
|
||||||
float pr = min(1.0 + smart_ei*max(c1.y,c1.z), ei_limit);
|
|
||||||
twl1 = pow(abs(rwl1), pc); twr1 = pow(abs(rwr1), pc);
|
|
||||||
twl2 = pow(abs(rwl2), pl); twr2 = pow(abs(rwr2), pr);
|
|
||||||
float wmax = max(twl1, twr1);
|
|
||||||
float sharp_ei = s_sharp*pow(zero, pc)/wmax;
|
|
||||||
twl2 = max(twl2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fp1*fp1));
|
|
||||||
twl1 = max(twl1/wmax - sharp_ei, 0.0);
|
|
||||||
twr1 = max(twr1/wmax - sharp_ei, 0.0);
|
|
||||||
twr2 = max(twr2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fpx*fpx));
|
|
||||||
}
|
|
||||||
color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
|
||||||
if (sharp) color1 = clamp(color1, colmin, colmax);
|
|
||||||
if (nmode1 && !interb) color1 = min(normalize (color1+eps) * length(sqrt(color1 * cc)) ,1.0);
|
|
||||||
|
|
||||||
color1 = pow(color1, vec3(scangamma/gamma_in));
|
|
||||||
|
|
||||||
float ts = 0.033;
|
|
||||||
|
|
||||||
bool ntscbm = (global.blendMode == 0.0);
|
|
||||||
|
|
||||||
if (ntscbm)
|
|
||||||
{
|
|
||||||
l2 = COMPAT_TEXTURE(PrePass0, pC4 -offx).rgb;
|
|
||||||
l1 = COMPAT_TEXTURE(PrePass0, pC4 ).rgb;
|
|
||||||
r1 = COMPAT_TEXTURE(PrePass0, pC4 +offx).rgb;
|
|
||||||
r2 = COMPAT_TEXTURE(PrePass0, pC4 +off2).rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
float lm2 = max(max(l2.r,l2.g),l2.b);
|
|
||||||
float lm1 = max(max(l1.r,l1.g),l1.b);
|
|
||||||
float rm1 = max(max(r1.r,r1.g),r1.b);
|
|
||||||
float rm2 = max(max(r2.r,r2.g),r2.b);
|
|
||||||
|
|
||||||
if (ntscbm)
|
|
||||||
{
|
|
||||||
lm2 = pow(lm2, gamma_in);
|
|
||||||
lm1 = pow(lm1, gamma_in);
|
|
||||||
rm1 = pow(rm1, gamma_in);
|
|
||||||
rm2 = pow(rm2, gamma_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
float swl2 = max(twl2, eps) * (lm2+ts);
|
|
||||||
float swl1 = twl1 * (lm1+ts);
|
|
||||||
float swr1 = twr1 * (rm1+ts);
|
|
||||||
float swr2 = max(twr2, eps) * (rm2+ts);
|
|
||||||
|
|
||||||
float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
|
||||||
vec3 mcolor1 = vec3(fscolor1);
|
|
||||||
vec3 scolor1 = vec3(clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0));
|
|
||||||
|
|
||||||
vec3 scolor2, mcolor2;
|
|
||||||
|
|
||||||
if (!interb)
|
|
||||||
{
|
|
||||||
pC4+=offy;
|
|
||||||
pC5+=offy;
|
|
||||||
|
|
||||||
if (nmode2)
|
|
||||||
{
|
|
||||||
l3 = pow(COMPAT_TEXTURE(NtscPass, pC4 -off2).rgb, gamma_in.xxx);
|
|
||||||
l2 = pow(COMPAT_TEXTURE(NtscPass, pC4 -offx).rgb, gamma_in.xxx);
|
|
||||||
l1 = pow(COMPAT_TEXTURE(NtscPass, pC4 ).rgb, gamma_in.xxx);
|
|
||||||
r1 = pow(COMPAT_TEXTURE(NtscPass, pC4 +offx).rgb, gamma_in.xxx);
|
|
||||||
r2 = pow(COMPAT_TEXTURE(NtscPass, pC4 +off2).rgb, gamma_in.xxx);
|
|
||||||
r3 = pow(COMPAT_TEXTURE(NtscPass, pC4 +offx+off2).rgb, gamma_in.xxx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).rgb;
|
|
||||||
l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb;
|
|
||||||
l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb;
|
|
||||||
r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb;
|
|
||||||
r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).rgb;
|
|
||||||
r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+off2).rgb;
|
|
||||||
cc = pow(COMPAT_TEXTURE(NtscPass, pC5).rgb, gamma_in.xxx);
|
|
||||||
}
|
|
||||||
|
|
||||||
colmin = min(min(l1,r1), min(l2,r2));
|
|
||||||
colmax = max(max(l1,r1), max(l2,r2));
|
|
||||||
|
|
||||||
if (smarte)
|
|
||||||
{
|
|
||||||
float pc = min(1.0 + smart_ei*c2.y, ei_limit);
|
|
||||||
float pl = min(1.0 + smart_ei*max(c2.y,c2.x), ei_limit);
|
|
||||||
float pr = min(1.0 + smart_ei*max(c2.y,c2.z), ei_limit);
|
|
||||||
twl1 = pow(abs(rwl1), pc); twr1 = pow(abs(rwr1), pc);
|
|
||||||
twl2 = pow(abs(rwl2), pl); twr2 = pow(abs(rwr2), pr);
|
|
||||||
float wmax = max(twl1, twr1);
|
|
||||||
float sharp_ei = s_sharp*pow(zero, pc)/wmax;
|
|
||||||
twl2 = max(twl2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fp1*fp1));
|
|
||||||
twl1 = max(twl1/wmax - sharp_ei, 0.0);
|
|
||||||
twr1 = max(twr1/wmax - sharp_ei, 0.0);
|
|
||||||
twr2 = max(twr2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fpx*fpx));
|
|
||||||
}
|
|
||||||
color2 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
|
||||||
if (sharp) color2 = clamp(color2, colmin, colmax);
|
|
||||||
if (nmode1 && !interb) color2 = min(normalize (color2+eps) * length(sqrt(color2 * cc)) ,1.0);
|
|
||||||
|
|
||||||
color2 = pow(color2, vec3(scangamma/gamma_in));
|
|
||||||
|
|
||||||
if (ntscbm)
|
|
||||||
{
|
|
||||||
l2 = COMPAT_TEXTURE(PrePass0, pC4 -offx).rgb;
|
|
||||||
l1 = COMPAT_TEXTURE(PrePass0, pC4 ).rgb;
|
|
||||||
r1 = COMPAT_TEXTURE(PrePass0, pC4 +offx).rgb;
|
|
||||||
r2 = COMPAT_TEXTURE(PrePass0, pC4 +off2).rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
lm2 = max(max(l2.r,l2.g),l2.b);
|
|
||||||
lm1 = max(max(l1.r,l1.g),l1.b);
|
|
||||||
rm1 = max(max(r1.r,r1.g),r1.b);
|
|
||||||
rm2 = max(max(r2.r,r2.g),r2.b);
|
|
||||||
|
|
||||||
if (ntscbm)
|
|
||||||
{
|
|
||||||
lm2 = pow(lm2, gamma_in);
|
|
||||||
lm1 = pow(lm1, gamma_in);
|
|
||||||
rm1 = pow(rm1, gamma_in);
|
|
||||||
rm2 = pow(rm2, gamma_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
swl2 = max(twl2, 0.0) * (lm2+ts);
|
|
||||||
swl1 = twl1 * (lm1+ts);
|
|
||||||
swr1 = twr1 * (rm1+ts);
|
|
||||||
swr2 = max(twr2, 0.0) * (rm2+ts);
|
|
||||||
|
|
||||||
float fscolor2 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
|
||||||
mcolor2 = vec3(fscolor2);
|
|
||||||
scolor2 = vec3(clamp(mix(max(max(color2.r,color2.g),color2.b), fscolor2, spike), 0.0, 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 ctmp; vec3 mcolor; float w3; vec3 color;
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
|
|
||||||
if (!interb)
|
|
||||||
{
|
|
||||||
// calculating scanlines
|
|
||||||
|
|
||||||
float shape1 = mix(scanline1, scanline2, f);
|
|
||||||
float shape2 = mix(scanline1, scanline2, 1.0-f);
|
|
||||||
|
|
||||||
float wt1 = st(f);
|
|
||||||
float wt2 = st(1.0-f);
|
|
||||||
|
|
||||||
vec3 color00 = color1*wt1 + color2*wt2;
|
|
||||||
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
|
||||||
mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2);
|
|
||||||
|
|
||||||
ctmp = color00/(wt1+wt2);
|
|
||||||
vec3 sctmp = scolor0/(wt1+wt2);
|
|
||||||
mcolor = clamp(mix(ctmp, mcolor, 1.5), 0.0, 1.0);
|
|
||||||
|
|
||||||
float wf1, wf2;
|
|
||||||
|
|
||||||
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b);
|
|
||||||
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b);
|
|
||||||
|
|
||||||
float f1 = f;
|
|
||||||
float f2 = 1.0-f;
|
|
||||||
|
|
||||||
if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else
|
|
||||||
if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else
|
|
||||||
{ wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);}
|
|
||||||
|
|
||||||
if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; }
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// float ws1 = max(wf1 - scansub, 0.2*wf1*wf2); wf1 = ws1/(1.0 - wf1 + ws1);
|
|
||||||
// float ws2 = max(wf2 - scansub, 0.2*wf2*wf1); wf2 = ws2/(1.0 - wf2 + ws2);
|
|
||||||
|
|
||||||
// Scanline saturation application
|
|
||||||
|
|
||||||
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
|
||||||
w3 = wf1+wf2;
|
|
||||||
|
|
||||||
cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001);
|
|
||||||
cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001);
|
|
||||||
|
|
||||||
w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1);
|
|
||||||
w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2);
|
|
||||||
|
|
||||||
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
|
||||||
|
|
||||||
float v_high1 = 1.0 + 0.3*vm;
|
|
||||||
float v_high2 = 1.0 + 0.6*vm;
|
|
||||||
float v_low = 1.0 - vm;
|
|
||||||
|
|
||||||
float ds1 = min(max(1.0-w3*w3, 2.5*f1), 1.0);
|
|
||||||
float ds2 = min(max(1.0-w3*w3, 2.5*f2), 1.0);
|
|
||||||
|
|
||||||
if (vertmask < 0.0)
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2);
|
|
||||||
}
|
|
||||||
|
|
||||||
color = gc(color1)*w1*cd1 + gc(color2)*w2*cd2;
|
|
||||||
|
|
||||||
color = min(color, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interb)
|
|
||||||
{
|
|
||||||
color = gc(color1);
|
|
||||||
mcolor = clamp(mix(color1, mcolor1, 1.25), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float mx = max(max(mcolor.r,mcolor.g),mcolor.b);
|
|
||||||
mx = pow(mx, 1.20/gamma_in);
|
|
||||||
|
|
||||||
// Apply Mask
|
|
||||||
|
|
||||||
vec3 orig1 = color;
|
|
||||||
vec3 cmask = one;
|
|
||||||
|
|
||||||
vec2 maskcoord = gl_FragCoord.yx * 1.000001;
|
|
||||||
if (notate) maskcoord = maskcoord.yx;
|
|
||||||
|
|
||||||
float smask = SlotMask(maskcoord, mx);
|
|
||||||
cmask*= Mask(maskcoord, mx);
|
|
||||||
|
|
||||||
color = pow(color, vec3(mask_gamma/gamma_in));
|
|
||||||
color = color*cmask;
|
|
||||||
color = min(color,1.0);
|
|
||||||
color = color*smask;
|
|
||||||
color = pow(color, vec3(gamma_in/mask_gamma));
|
|
||||||
|
|
||||||
cmask = min(cmask*smask, 1.0);
|
|
||||||
|
|
||||||
if (interb) ctmp = color;
|
|
||||||
float colmx = pow( max( max(ctmp.r, ctmp.g), ctmp.b), 1.40/gamma_out);
|
|
||||||
float bb = mix(brightboost, brightboost1, colmx);
|
|
||||||
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
|
||||||
color*=bb;
|
|
||||||
|
|
||||||
vec3 Glow = COMPAT_TEXTURE(GlowPass, pos).rgb;
|
|
||||||
vec3 Bloom = COMPAT_TEXTURE(BloomPass, pos).rgb;
|
|
||||||
float maxb = COMPAT_TEXTURE(BloomPass, pos).a;
|
|
||||||
float vig = COMPAT_TEXTURE(PrePass0, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a;
|
|
||||||
|
|
||||||
vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0));
|
|
||||||
color = color + bloom*Bloom1;
|
|
||||||
|
|
||||||
color = min(color, mix(one, cmask, mclip));
|
|
||||||
if (!interb) color = declip(color, pow(w3,0.60));
|
|
||||||
|
|
||||||
if (halation > 0.025) {
|
|
||||||
Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx);
|
|
||||||
color = color + (1.1-0.25*colmx)*(0.75+maxb)*Bloom*(0.75 + 0.70*pow(colmx,0.33333))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; }
|
|
||||||
|
|
||||||
color = pow(color, vec3(gamma_in/scangamma));
|
|
||||||
|
|
||||||
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
|
||||||
if (glow >= 0.0) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + (-glow)*cmask*Glow; }
|
|
||||||
|
|
||||||
color = min(color, 1.0);
|
|
||||||
|
|
||||||
color = pow(color, vec3(1.0/gamma_out));
|
|
||||||
|
|
||||||
FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir)), corner(pos0));
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
CRT - Guest - Advanced
|
CRT - Guest - Advanced
|
||||||
|
|
||||||
Copyright (C) 2018-2021 guest(r) - guest.r@gmail.com
|
Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
@ -27,8 +27,7 @@
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
||||||
h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask,
|
h_sharp, s_sharp, csize, bsize1, warpX, warpY, glow, vertmask, spike, ring;
|
||||||
slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike;
|
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
@ -41,22 +40,19 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
float bloom;
|
float bloom;
|
||||||
float halation;
|
float halation;
|
||||||
float scans;
|
float scans;
|
||||||
float scansub;
|
|
||||||
float slotms;
|
|
||||||
float mclip;
|
|
||||||
float gamma_c;
|
float gamma_c;
|
||||||
float mask_gamma;
|
|
||||||
float smart_ei;
|
float smart_ei;
|
||||||
float ei_limit;
|
float ei_limit;
|
||||||
float sth;
|
float sth;
|
||||||
float gamma_out;
|
float overscanX;
|
||||||
float overscanY;
|
float overscanY;
|
||||||
|
float c_shape;
|
||||||
float intres;
|
float intres;
|
||||||
float prescalex;
|
float prescalex;
|
||||||
float c_shape;
|
float scan_falloff;
|
||||||
float barspeed;
|
float rolling_scan;
|
||||||
float barintensity;
|
float bloom_dist;
|
||||||
float bardir;
|
float scangamma;
|
||||||
} global;
|
} global;
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,9 +61,15 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
||||||
#define glow params.glow // Glow Strength
|
#define glow params.glow // Glow Strength
|
||||||
|
|
||||||
#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05
|
#pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05
|
||||||
#define bloom global.bloom // bloom effect
|
#define bloom global.bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter mask_bloom " Mask Bloom" 0.0 0.0 2.0 0.05
|
||||||
|
#define mask_bloom params.mask_bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter bloom_dist " Bloom Distribution" 0.0 0.0 3.0 0.05
|
||||||
|
#define bloom_dist global.bloom_dist // bloom effect distribution
|
||||||
|
|
||||||
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
||||||
#define halation global.halation // halation effect
|
#define halation global.halation // halation effect
|
||||||
|
|
||||||
|
@ -85,16 +87,16 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
||||||
#define gsl params.gsl // Alternate scanlines
|
#define gsl params.gsl // Alternate scanlines
|
||||||
|
|
||||||
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 0.0 20.0 0.5
|
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
||||||
|
|
||||||
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 40.0 1.0
|
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 0.0 70.0 1.0
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
||||||
|
|
||||||
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 0.05
|
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 5.0 0.05
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
#define beam_min params.beam_min // dark area beam min - narrow
|
||||||
|
|
||||||
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 2.5 0.05
|
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
#define beam_max params.beam_max // bright area beam max - wide
|
||||||
|
|
||||||
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
||||||
|
@ -103,17 +105,21 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
||||||
#define vertmask params.vertmask // Scanline deconvergence colors
|
#define vertmask params.vertmask // Scanline deconvergence colors
|
||||||
|
|
||||||
#pragma parameter scans " Scanline Saturation" 0.60 0.0 1.0 0.05
|
#pragma parameter scans " Scanline Saturation / Mask Falloff" 0.60 0.0 2.5 0.05
|
||||||
#define scans global.scans // scanline saturation
|
#define scans global.scans // scanline saturation
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.25 2.0 0.05
|
||||||
|
#define scan_falloff global.scan_falloff // scanline falloff
|
||||||
// #pragma parameter scansub " Scanline darken 'edges'" 0.0 0.0 0.30 0.005
|
|
||||||
// #define scansub global.scansub // scanline substraction
|
|
||||||
|
|
||||||
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
||||||
#define spike params.spike
|
#define spike params.spike
|
||||||
|
|
||||||
|
#pragma parameter rolling_scan " Rolling Scanlines" 0.0 -1.0 1.0 0.01
|
||||||
|
#define rolling_scan global.rolling_scan // rolling scanlines
|
||||||
|
|
||||||
|
#pragma parameter scangamma " Scanline Gamma" 2.40 0.5 5.0 0.05
|
||||||
|
#define scangamma global.scangamma
|
||||||
|
|
||||||
#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.10
|
#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.10
|
||||||
|
@ -122,13 +128,16 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
||||||
#define s_sharp params.s_sharp // substractive sharpness
|
#define s_sharp params.s_sharp // substractive sharpness
|
||||||
|
|
||||||
#pragma parameter smart_ei " Smart Edges Effect Strength" 0.0 0.0 20.0 0.25
|
#pragma parameter ring " Substractive sharpness Ringing" 0.0 0.0 3.0 0.05
|
||||||
|
#define ring params.ring // substractive sharpness ringing
|
||||||
|
|
||||||
|
#pragma parameter smart_ei " Smart Edges Effect Strength" 0.0 0.0 0.75 0.01
|
||||||
#define smart_ei global.smart_ei // smart edge handling
|
#define smart_ei global.smart_ei // smart edge handling
|
||||||
|
|
||||||
#pragma parameter ei_limit " Smart Edges Effect Strength Limit" 2.0 1.0 12.0 0.1
|
#pragma parameter ei_limit " Smart Edges Effect Strength Limit" 0.25 0.0 0.75 0.01
|
||||||
#define ei_limit global.ei_limit // smart edge handling
|
#define ei_limit global.ei_limit // smart edge handling
|
||||||
|
|
||||||
#pragma parameter sth " Smart Edges Smoothing Threshold" 0.20 0.0 1.0 0.01
|
#pragma parameter sth " Smart Edges Smoothing Threshold" 0.23 0.0 1.0 0.01
|
||||||
#define sth global.sth // corner size
|
#define sth global.sth // corner size
|
||||||
|
|
||||||
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
@ -147,18 +156,6 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
||||||
#define BLOOM params.BLOOM // Bloom overscan percentage
|
#define BLOOM params.BLOOM // Bloom overscan percentage
|
||||||
|
|
||||||
#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01
|
|
||||||
#define csize params.csize // corner size
|
|
||||||
|
|
||||||
#pragma parameter bsize " Border smoothness" 600.0 100.0 700.0 10.0
|
|
||||||
#define bsize params.bsize // border smoothness
|
|
||||||
|
|
||||||
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01
|
|
||||||
|
|
||||||
#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
||||||
#define warpX params.warpX // Curvature X
|
#define warpX params.warpX // Curvature X
|
||||||
|
|
||||||
|
@ -168,55 +165,15 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
||||||
#define c_shape global.c_shape // curvature shape
|
#define c_shape global.c_shape // curvature shape
|
||||||
|
|
||||||
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -50.0 50.0 1.0
|
#pragma parameter overscanX " Overscan X original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanX global.overscanX // OverscanX pixels
|
||||||
|
|
||||||
|
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -200.0 200.0 1.0
|
||||||
#define overscanY global.overscanY // OverscanY pixels
|
#define overscanY global.overscanY // OverscanY pixels
|
||||||
|
|
||||||
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0
|
||||||
#define prescalex global.prescalex // prescale-x factor
|
#define prescalex global.prescalex // prescale-x factor
|
||||||
|
|
||||||
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0
|
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
|
||||||
|
|
||||||
#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05
|
|
||||||
#define maskstr params.maskstr // CGWG Mask Strength
|
|
||||||
|
|
||||||
#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05
|
|
||||||
#define mcut params.mcut // Mask 5-7 dark color strength
|
|
||||||
|
|
||||||
#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0
|
|
||||||
#define masksize params.masksize // Mask Size
|
|
||||||
|
|
||||||
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
|
||||||
#define maskDark params.maskDark // Dark "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05
|
|
||||||
#define mask_gamma global.mask_gamma // Mask application gamma
|
|
||||||
|
|
||||||
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask params.slotmask
|
|
||||||
|
|
||||||
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask1 params.slotmask1
|
|
||||||
|
|
||||||
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 6.0 0.5
|
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
|
||||||
|
|
||||||
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
|
||||||
|
|
||||||
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
|
||||||
#define slotms global.slotms // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05
|
|
||||||
#define mclip global.mclip // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05
|
|
||||||
#define gamma_out global.gamma_out // output gamma
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
#define TEX0 vTexCoord
|
#define TEX0 vTexCoord
|
||||||
|
@ -232,7 +189,7 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord * 1.000001;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
|
@ -240,9 +197,7 @@ layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D LinearizePass;
|
layout(set = 0, binding = 2) uniform sampler2D LinearizePass;
|
||||||
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
||||||
layout(set = 0, binding = 4) uniform sampler2D GlowPass;
|
layout(set = 0, binding = 4) uniform sampler2D PrePass;
|
||||||
layout(set = 0, binding = 5) uniform sampler2D BloomPass;
|
|
||||||
layout(set = 0, binding = 6) uniform sampler2D PrePass;
|
|
||||||
|
|
||||||
#define eps 1e-10
|
#define eps 1e-10
|
||||||
|
|
||||||
|
@ -251,6 +206,11 @@ float st(float x)
|
||||||
return exp2(-10.0*x*x);
|
return exp2(-10.0*x*x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float st1(float x)
|
||||||
|
{
|
||||||
|
return exp2(-7.0*x*x);
|
||||||
|
}
|
||||||
|
|
||||||
float sw0(float x, float color, float scanline)
|
float sw0(float x, float color, float scanline)
|
||||||
{
|
{
|
||||||
float tmp = mix(beam_min, beam_max, color);
|
float tmp = mix(beam_min, beam_max, color);
|
||||||
|
@ -275,147 +235,6 @@ float sw2(float x, float color, float scanline)
|
||||||
return exp2(-scanline*ex*ex);
|
return exp2(-scanline*ex*ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shadow mask (1-4 from PD CRT Lottes shader).
|
|
||||||
|
|
||||||
vec3 Mask(vec2 pos, float mx)
|
|
||||||
{
|
|
||||||
pos = floor(pos/masksize);
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 0.0) + 1.0, 1.0, mx);
|
|
||||||
float mc = 1.0 - max(maskstr, 0.0);
|
|
||||||
|
|
||||||
// No mask
|
|
||||||
if (shadowMask == -1.0)
|
|
||||||
{
|
|
||||||
mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phosphor.
|
|
||||||
else if (shadowMask == 0.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x*0.5);
|
|
||||||
if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
|
||||||
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very compressed TV style shadow mask.
|
|
||||||
else if (shadowMask == 1.0)
|
|
||||||
{
|
|
||||||
float line = maskLight;
|
|
||||||
float odd = 0.0;
|
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
|
||||||
odd = 1.0;
|
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
|
||||||
line = maskDark;
|
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
|
|
||||||
mask*=line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aperture-grille.
|
|
||||||
else if (shadowMask == 2.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stretched VGA style shadow mask (same as prior shaders).
|
|
||||||
else if (shadowMask == 3.0)
|
|
||||||
{
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA style shadow mask.
|
|
||||||
else if (shadowMask == 4.0)
|
|
||||||
{
|
|
||||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 5
|
|
||||||
else if (shadowMask == 5.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5)
|
|
||||||
{ mask.r = 1.0;
|
|
||||||
mask.b = 1.0;
|
|
||||||
}
|
|
||||||
else mask.g = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 6
|
|
||||||
else if (shadowMask == 6.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
if (pos.x < 0.333) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.666) mask.g = 1.0;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BW Trinitron mask 7
|
|
||||||
else if (shadowMask == 7.0)
|
|
||||||
{
|
|
||||||
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
mask = vec3(maskTmp);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5) mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4k mask
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mask = vec3(mc);
|
|
||||||
pos.x = fract(pos.x * 0.25);
|
|
||||||
if (pos.x < 0.2) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
|
||||||
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SlotMask(vec2 pos, float m)
|
|
||||||
{
|
|
||||||
if ((slotmask + slotmask1) == 0.0) return 1.0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pos = floor(pos/slotms);
|
|
||||||
float mlen = slotwidth*2.0;
|
|
||||||
float px = fract(pos.x/mlen);
|
|
||||||
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
|
||||||
float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m);
|
|
||||||
float slot = 1.0;
|
|
||||||
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
|
||||||
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Warp(vec2 pos)
|
vec2 Warp(vec2 pos)
|
||||||
{
|
{
|
||||||
|
@ -430,34 +249,6 @@ vec2 Overscan(vec2 pos, float dx, float dy){
|
||||||
return pos*0.5+0.5;
|
return pos*0.5+0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
float humbar(float pos)
|
|
||||||
{
|
|
||||||
if (global.barintensity == 0.0) return 1.0; else
|
|
||||||
{
|
|
||||||
pos = (global.barintensity >= 0.0) ? pos : (1.0-pos);
|
|
||||||
pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0));
|
|
||||||
pos = (global.barintensity < 0.0) ? pos : (1.0-pos);
|
|
||||||
return (1.0-global.barintensity) + global.barintensity*pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Borrowed from cgwg's crt-geom, under GPL
|
|
||||||
|
|
||||||
float corner(vec2 coord)
|
|
||||||
{
|
|
||||||
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
|
|
||||||
vec2 cdist = vec2(max(csize/3.0, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002)));
|
|
||||||
coord = (cdist - min(coord,cdist));
|
|
||||||
float dist = sqrt(dot(coord,coord));
|
|
||||||
return clamp((cdist.x-dist)*bsize,0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 gc(vec3 c)
|
vec3 gc(vec3 c)
|
||||||
{
|
{
|
||||||
|
@ -466,21 +257,16 @@ vec3 gc(vec3 c)
|
||||||
return c * mg/(mc + eps);
|
return c * mg/(mc + eps);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 plant (vec3 tar, float r)
|
|
||||||
{
|
|
||||||
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
|
||||||
return tar * r / t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 SourceSize = global.OriginalSize * vec4(prescalex, 1.0, 1.0/prescalex, 1.0);
|
vec4 SourceSize = global.OriginalSize * mix( vec4(prescalex, 1.0, 1.0/prescalex, 1.0), vec4(1.0, prescalex, 1.0, 1.0/prescalex), TATE);
|
||||||
|
|
||||||
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.5,0.5)).a;
|
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.5,0.5)).a;
|
||||||
|
|
||||||
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
||||||
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
||||||
bool interb = (intera < 0.75);
|
bool interb = (intera < 0.5);
|
||||||
bool notate = (TATE < 0.5);
|
bool notate = (TATE < 0.5);
|
||||||
|
|
||||||
float SourceY = mix(SourceSize.y, SourceSize.x, TATE);
|
float SourceY = mix(SourceSize.y, SourceSize.x, TATE);
|
||||||
|
@ -493,7 +279,7 @@ void main()
|
||||||
// Calculating texel coordinates
|
// Calculating texel coordinates
|
||||||
|
|
||||||
vec2 texcoord = TEX0.xy;
|
vec2 texcoord = TEX0.xy;
|
||||||
if (IOS > 0.0){
|
if (IOS > 0.0 && !interb){
|
||||||
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
||||||
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
||||||
vec2 diff = ofactor/intfactor;
|
vec2 diff = ofactor/intfactor;
|
||||||
|
@ -505,12 +291,11 @@ void main()
|
||||||
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
||||||
texcoord = Overscan(texcoord, factor, factor);
|
texcoord = Overscan(texcoord, factor, factor);
|
||||||
|
|
||||||
texcoord = Overscan(texcoord, 1.0, (SourceSize.y - overscanY)/SourceSize.y);
|
texcoord = Overscan(texcoord, (global.OriginalSize.x - overscanX)/global.OriginalSize.x, (global.OriginalSize.y - overscanY)/global.OriginalSize.y);
|
||||||
|
|
||||||
vec2 pos = Warp(texcoord);
|
vec2 pos = Warp(texcoord);
|
||||||
vec2 pos0 = Warp(TEX0.xy);
|
|
||||||
|
|
||||||
bool smarte = (smart_ei > 0.0 && notate); // smart edge interpolation on / off
|
bool smarte = (smart_ei > 0.01 && notate); // smart edge interpolation on / off
|
||||||
|
|
||||||
vec2 coffset = vec2(0.5, 0.5);
|
vec2 coffset = vec2(0.5, 0.5);
|
||||||
|
|
||||||
|
@ -564,32 +349,23 @@ void main()
|
||||||
float fp1 = 1.-fpx;
|
float fp1 = 1.-fpx;
|
||||||
|
|
||||||
float twl3 = max(wl3 - sharp1, 0.0);
|
float twl3 = max(wl3 - sharp1, 0.0);
|
||||||
float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1)); float scl2 = max(twl2, 0.0);
|
float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1));
|
||||||
float twl1 = max(wl1 - sharp1, 0.0);
|
float twl1 = max(wl1 - sharp1, 0.0);
|
||||||
float twr1 = max(wr1 - sharp1, 0.0);
|
float twr1 = max(wr1 - sharp1, 0.0);
|
||||||
float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx)); float scr2 = max(twr2, 0.0);
|
float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx));
|
||||||
float twr3 = max(wr3 - sharp1, 0.0);
|
float twr3 = max(wr3 - sharp1, 0.0);
|
||||||
|
|
||||||
bool sharp = (sharp1 > 0.0);
|
bool sharp = (sharp1 > 0.0);
|
||||||
|
|
||||||
float rwl3, rwl2, rwr2;
|
|
||||||
|
|
||||||
float rwl1 = twl1;
|
|
||||||
float rwr1 = twr1;
|
|
||||||
vec3 c1, c2;
|
vec3 c1, c2;
|
||||||
|
|
||||||
if (smarte)
|
if (smarte)
|
||||||
{
|
{
|
||||||
rwl3 = wl3; rwl2 = wl2;
|
|
||||||
rwl1 = wl1; rwr1 = wr1;
|
|
||||||
rwr2 = wr2;
|
|
||||||
twl3 = 0.0; twr3 = 0.0;
|
twl3 = 0.0; twr3 = 0.0;
|
||||||
vec3 t = COMPAT_TEXTURE(AvgLumPass, pC4 - offy).xyz;
|
c1 = COMPAT_TEXTURE(AvgLumPass, pC4 ).xyz;
|
||||||
vec3 a = COMPAT_TEXTURE(AvgLumPass, pC4 ).xyz;
|
c2 = COMPAT_TEXTURE(AvgLumPass, pC4 + offy).xyz;
|
||||||
vec3 b = COMPAT_TEXTURE(AvgLumPass, pC4 + offy).xyz;
|
c1 = max(c1 - sth, 0.0);
|
||||||
vec3 d = COMPAT_TEXTURE(AvgLumPass, pC4 +dy+dy).xyz;
|
c2 = max(c2 - sth, 0.0);
|
||||||
c1 = (h_sharp > 2.6) ? a : min(a,(t + a + b)/3.0); c1 = max(c1 - sth, 0.0);
|
|
||||||
c2 = (h_sharp > 2.6) ? b : min(b,(a + b + d)/3.0); c2 = max(c2 - sth, 0.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 l3, l2, l1, r1, r2, r3, sl2, sl1, sr1, sr2, color1, color2, colmin, colmax;
|
vec3 l3, l2, l1, r1, r2, r3, sl2, sl1, sr1, sr2, color1, color2, colmin, colmax;
|
||||||
|
@ -606,38 +382,35 @@ void main()
|
||||||
|
|
||||||
if (smarte)
|
if (smarte)
|
||||||
{
|
{
|
||||||
float pc = min(1.0 + smart_ei*c1.y, ei_limit);
|
float pc = min(smart_ei*c1.y, ei_limit);
|
||||||
float pl = min(1.0 + smart_ei*max(c1.y,c1.x), ei_limit);
|
float pl = min(smart_ei*max(c1.y,c1.x), ei_limit);
|
||||||
float pr = min(1.0 + smart_ei*max(c1.y,c1.z), ei_limit);
|
float pr = min(smart_ei*max(c1.y,c1.z), ei_limit);
|
||||||
twl1 = pow(abs(rwl1), pc); twr1 = pow(abs(rwr1), pc);
|
twl1 = max(wl1-pc, 0.01*wl1); twr1 = max(wr1-pc, 0.01*wr1);
|
||||||
twl2 = pow(abs(rwl2), pl); twr2 = pow(abs(rwr2), pr);
|
twl2 = max(wl2-pl, 0.01*wl2); twr2 = max(wr2-pr, 0.01*wr2);
|
||||||
float wmax = max(twl1, twr1);
|
|
||||||
float sharp_ei = s_sharp*pow(zero, pc)/wmax;
|
|
||||||
twl2 = max(twl2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fp1*fp1));
|
|
||||||
twl1 = max(twl1/wmax - sharp_ei, 0.0);
|
|
||||||
twr1 = max(twr1/wmax - sharp_ei, 0.0);
|
|
||||||
twr2 = max(twr2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fpx*fpx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
||||||
|
|
||||||
if (sharp) color1 = clamp(color1, colmin, colmax);
|
if (sharp) color1 = clamp(mix(clamp(color1, colmin, colmax), color1, ring), 0.0, 1.0);
|
||||||
float ts = 0.033;
|
float ts = 0.025;
|
||||||
|
vec3 luma = vec3(0.2126, 0.7152, 0.0722);
|
||||||
|
|
||||||
float lm2 = max(max(l2.r,l2.g),l2.b);
|
float lm2 = max(max(l2.r,l2.g),l2.b);
|
||||||
float lm1 = max(max(l1.r,l1.g),l1.b);
|
float lm1 = max(max(l1.r,l1.g),l1.b);
|
||||||
float rm1 = max(max(r1.r,r1.g),r1.b);
|
float rm1 = max(max(r1.r,r1.g),r1.b);
|
||||||
float rm2 = max(max(r2.r,r2.g),r2.b);
|
float rm2 = max(max(r2.r,r2.g),r2.b);
|
||||||
|
|
||||||
float swl2 = max(twl2, 0.0) * (lm2+ts);
|
float swl2 = max(twl2, 0.0) * (dot(l2,luma) + ts);
|
||||||
float swl1 = twl1 * (lm1+ts);
|
float swl1 = twl1 * (dot(l1,luma) + ts);
|
||||||
float swr1 = twr1 * (rm1+ts);
|
float swr1 = twr1 * (dot(r1,luma) + ts);
|
||||||
float swr2 = max(twr2, 0.0) * (rm2+ts);
|
float swr2 = max(twr2, 0.0) * (dot(r2,luma) + ts);
|
||||||
|
|
||||||
float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
||||||
vec3 mcolor1 = vec3(fscolor1);
|
|
||||||
vec3 scolor1 = vec3(clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0));
|
vec3 scolor1 = vec3(clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0));
|
||||||
|
|
||||||
vec3 scolor2, mcolor2;
|
if(!interb) color1 = pow(color1, vec3(scangamma/gamma_in));
|
||||||
|
|
||||||
|
vec3 scolor2;
|
||||||
|
|
||||||
if (!interb)
|
if (!interb)
|
||||||
{
|
{
|
||||||
|
@ -655,38 +428,35 @@ void main()
|
||||||
|
|
||||||
if (smarte)
|
if (smarte)
|
||||||
{
|
{
|
||||||
float pc = min(1.0 + smart_ei*c2.y, ei_limit);
|
float pc = min(smart_ei*c2.y, ei_limit);
|
||||||
float pl = min(1.0 + smart_ei*max(c2.y,c2.x), ei_limit);
|
float pl = min(smart_ei*max(c2.y,c2.x), ei_limit);
|
||||||
float pr = min(1.0 + smart_ei*max(c2.y,c2.z), ei_limit);
|
float pr = min(smart_ei*max(c2.y,c2.z), ei_limit);
|
||||||
twl1 = pow(abs(rwl1), pc); twr1 = pow(abs(rwr1), pc);
|
twl1 = max(wl1-pc, 0.01*wl1); twr1 = max(wr1-pc, 0.01*wr1);
|
||||||
twl2 = pow(abs(rwl2), pl); twr2 = pow(abs(rwr2), pr);
|
twl2 = max(wl2-pl, 0.01*wl2); twr2 = max(wr2-pr, 0.01*wr2);
|
||||||
float wmax = max(twl1, twr1);
|
|
||||||
float sharp_ei = s_sharp*pow(zero, pc)/wmax;
|
|
||||||
twl2 = max(twl2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fp1*fp1));
|
|
||||||
twl1 = max(twl1/wmax - sharp_ei, 0.0);
|
|
||||||
twr1 = max(twr1/wmax - sharp_ei, 0.0);
|
|
||||||
twr2 = max(twr2/wmax - sharp_ei, mix(-0.12, 0.0, 1.0-fpx*fpx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
color2 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
color2 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
||||||
|
|
||||||
if (sharp) color2 = clamp(color2, colmin, colmax);
|
if (sharp) color2 = clamp(mix(clamp(color2, colmin, colmax), color2, ring), 0.0, 1.0);
|
||||||
|
|
||||||
lm2 = max(max(l2.r,l2.g),l2.b);
|
lm2 = max(max(l2.r,l2.g),l2.b);
|
||||||
lm1 = max(max(l1.r,l1.g),l1.b);
|
lm1 = max(max(l1.r,l1.g),l1.b);
|
||||||
rm1 = max(max(r1.r,r1.g),r1.b);
|
rm1 = max(max(r1.r,r1.g),r1.b);
|
||||||
rm2 = max(max(r2.r,r2.g),r2.b);
|
rm2 = max(max(r2.r,r2.g),r2.b);
|
||||||
|
|
||||||
swl2 = max(twl2, 0.0) * (lm2+ts);
|
swl2 = max(twl2, 0.0) * (dot(l2,luma) + ts);
|
||||||
swl1 = twl1 * (lm1+ts);
|
swl1 = twl1 * (dot(l1,luma) + ts);
|
||||||
swr1 = twr1 * (rm1+ts);
|
swr1 = twr1 * (dot(r1,luma) + ts);
|
||||||
swr2 = max(twr2, 0.0) * (rm2+ts);
|
swr2 = max(twr2, 0.0) * (dot(r2,luma) + ts);
|
||||||
|
|
||||||
float fscolor2 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
float fscolor2 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
||||||
mcolor2 = vec3(fscolor2);
|
|
||||||
scolor2 = vec3(clamp(mix(max(max(color2.r,color2.g),color2.b), fscolor2, spike), 0.0, 1.0));
|
scolor2 = vec3(clamp(mix(max(max(color2.r,color2.g),color2.b), fscolor2, spike), 0.0, 1.0));
|
||||||
|
|
||||||
|
color2 = pow(color2, vec3(scangamma/gamma_in));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 ctmp; vec3 mcolor; float w3; vec3 color;
|
vec3 ctmp = color1; float w3 = 1.0; vec3 color = color1;
|
||||||
vec3 one = vec3(1.0);
|
vec3 one = vec3(1.0);
|
||||||
|
|
||||||
if (!interb)
|
if (!interb)
|
||||||
|
@ -701,41 +471,44 @@ if (!interb)
|
||||||
|
|
||||||
vec3 color00 = color1*wt1 + color2*wt2;
|
vec3 color00 = color1*wt1 + color2*wt2;
|
||||||
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
||||||
mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2);
|
|
||||||
|
|
||||||
ctmp = color00/(wt1+wt2);
|
ctmp = color00/(wt1+wt2);
|
||||||
vec3 sctmp = scolor0/(wt1+wt2);
|
vec3 sctmp = scolor0/(wt1+wt2);
|
||||||
mcolor = clamp(mix(ctmp, mcolor, 1.25), 0.0, 1.0);
|
|
||||||
|
|
||||||
float wf1, wf2;
|
float wf1, wf2;
|
||||||
|
|
||||||
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b);
|
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = pow(max(max(cref1.r,cref1.g),cref1.b), scan_falloff);
|
||||||
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b);
|
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = pow(max(max(cref2.r,cref2.g),cref2.b), scan_falloff);
|
||||||
|
|
||||||
float f1 = f;
|
float f1 = f;
|
||||||
float f2 = 1.0-f;
|
float f2 = 1.0-f;
|
||||||
|
|
||||||
|
float scanpix = mix(SourceSize.x/OutputSize.x, SourceSize.y/OutputSize.y, float(notate));
|
||||||
|
|
||||||
|
f1 = fract(f1 + rolling_scan*float(global.FrameCount)*scanpix);
|
||||||
|
f2 = 1.0 - f1;
|
||||||
|
|
||||||
if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else
|
if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else
|
||||||
if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else
|
if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else
|
||||||
{ wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);}
|
{ wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);}
|
||||||
|
|
||||||
if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; }
|
if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; }
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// float ws1 = max(wf1 - scansub, 0.2*wf1*wf2); wf1 = ws1/(1.0 - wf1 + ws1);
|
|
||||||
// float ws2 = max(wf2 - scansub, 0.2*wf2*wf1); wf2 = ws2/(1.0 - wf2 + ws2);
|
|
||||||
|
|
||||||
// Scanline saturation application
|
// Scanline saturation application
|
||||||
|
|
||||||
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
||||||
w3 = wf1+wf2;
|
w3 = wf1+wf2;
|
||||||
|
|
||||||
cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001);
|
float mc1 = max(max(color1.r,color1.g),color1.b) + eps;
|
||||||
cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001);
|
float mc2 = max(max(color2.r,color2.g),color2.b) + eps;
|
||||||
|
|
||||||
w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1);
|
cref1 = color1 / mc1; cref1=cref1*cref1; cref1*=cref1;
|
||||||
w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2);
|
cref2 = color2 / mc2; cref2=cref2*cref2; cref2*=cref2;
|
||||||
|
|
||||||
|
w1 = max( mix(w1*mix(one, cref1, scans), w1, wf1*min((1.0+0.15*scans), 1.2)), 0.0); w1 = min(w1*color1, mc1)/(color1 + eps);
|
||||||
|
w2 = max( mix(w2*mix(one, cref2, scans), w2, wf2*min((1.0+0.15*scans), 1.2)), 0.0); w2 = min(w2*color2, mc2)/(color2 + eps);
|
||||||
|
|
||||||
|
// Scanline Deconvergence
|
||||||
|
|
||||||
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
||||||
|
|
||||||
|
@ -759,64 +532,25 @@ if (!interb)
|
||||||
|
|
||||||
color = gc(color1)*w1*cd1 + gc(color2)*w2*cd2;
|
color = gc(color1)*w1*cd1 + gc(color2)*w2*cd2;
|
||||||
|
|
||||||
|
if (abs(rolling_scan) > 0.005)
|
||||||
|
{
|
||||||
|
wt1 = st1(f);
|
||||||
|
wt2 = st1(1.0-f);
|
||||||
|
color00 = (color1*wt1 + color2*wt2)/(wt1+wt2);
|
||||||
|
color = gc(color00) * mix(w1+w2, w3.xxx, max(wf1,wf2));
|
||||||
|
}
|
||||||
|
|
||||||
color = min(color, 1.0);
|
color = min(color, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interb)
|
if (interb)
|
||||||
{
|
{
|
||||||
color = gc(color1);
|
color = gc(color1);
|
||||||
mcolor = clamp(mix(color1, mcolor1, 1.25), 0.0, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float mx = max(max(mcolor.r,mcolor.g),mcolor.b);
|
float colmx = pow(max(max(ctmp.r,ctmp.g),ctmp.b), 1.40/gamma_in);
|
||||||
mx = pow(mx, 1.20/gamma_in);
|
|
||||||
|
|
||||||
// Apply Mask
|
if(!interb) color = pow( color, vec3(gamma_in/scangamma) );
|
||||||
|
|
||||||
vec3 orig1 = color;
|
FragColor = vec4(color, colmx);
|
||||||
vec3 cmask = one;
|
|
||||||
|
|
||||||
vec2 maskcoord = gl_FragCoord.yx * 1.000001;
|
|
||||||
if (notate) maskcoord = maskcoord.yx;
|
|
||||||
|
|
||||||
float smask = SlotMask(maskcoord, mx);
|
|
||||||
cmask*= Mask(maskcoord, mx);
|
|
||||||
|
|
||||||
color = pow(color, vec3(mask_gamma/gamma_in));
|
|
||||||
color = color*cmask;
|
|
||||||
color = min(color,1.0);
|
|
||||||
color = color*smask;
|
|
||||||
color = pow(color, vec3(gamma_in/mask_gamma));
|
|
||||||
|
|
||||||
cmask = min(cmask*smask, 1.0);
|
|
||||||
|
|
||||||
if (interb) ctmp = color;
|
|
||||||
float colmx = pow( max( max(ctmp.r, ctmp.g), ctmp.b), 1.40/gamma_out);
|
|
||||||
float bb = mix(brightboost, brightboost1, colmx);
|
|
||||||
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
|
||||||
color*=bb;
|
|
||||||
|
|
||||||
vec3 Glow = COMPAT_TEXTURE(GlowPass, pos).rgb;
|
|
||||||
vec3 Bloom = COMPAT_TEXTURE(BloomPass, pos).rgb;
|
|
||||||
float maxb = COMPAT_TEXTURE(BloomPass, pos).a;
|
|
||||||
float vig = COMPAT_TEXTURE(PrePass, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a;
|
|
||||||
|
|
||||||
vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0));
|
|
||||||
color = color + bloom*Bloom1;
|
|
||||||
|
|
||||||
color = min(color, mix(one, cmask, mclip));
|
|
||||||
if (!interb) color = declip(color, pow(w3,0.60));
|
|
||||||
|
|
||||||
if (halation > 0.025) {
|
|
||||||
Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx);
|
|
||||||
color = color + (1.1-0.25*colmx)*(0.75+maxb)*Bloom*(0.75 + 0.70*pow(colmx,0.33333))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; }
|
|
||||||
|
|
||||||
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
|
||||||
if (glow >= 0.0) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + (-glow)*cmask*Glow; }
|
|
||||||
|
|
||||||
color = min(color, 1.0);
|
|
||||||
|
|
||||||
color = pow(color, vec3(1.0/gamma_out));
|
|
||||||
|
|
||||||
FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir)), corner(pos0));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
Fast Sharpen Shader (Custom)
|
Fast Sharpen Shader (Custom)
|
||||||
|
|
||||||
Copyright (C) 2005 - 2019 guest(r) - guest.r@gmail.com
|
Copyright (C) 2005 - 2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -26,16 +26,16 @@ layout(push_constant) uniform Push
|
||||||
vec4 OriginalSize;
|
vec4 OriginalSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
float SHARPEN, CONTR, DETAILS;
|
float CSHARPEN, CCONTR, CDETAILS;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
#pragma parameter SHARPEN "Sharpen strength" 0.00 0.0 4.00 0.10
|
#pragma parameter CSHARPEN "Sharpen strength" 0.00 0.0 5.00 0.10
|
||||||
#pragma parameter CONTR "Ammount of sharpening" 0.05 0.0 0.25 0.01
|
#pragma parameter CCONTR "Ammount of sharpening" 0.05 0.0 0.25 0.01
|
||||||
#pragma parameter DETAILS "Details sharpened " 1.00 0.0 1.00 0.05
|
#pragma parameter CDETAILS "Details sharpened " 1.00 0.0 1.00 0.05
|
||||||
|
|
||||||
#define SHARPEN params.SHARPEN
|
#define CSHARPEN params.CSHARPEN
|
||||||
#define CONTR params.CONTR
|
#define CCONTR params.CCONTR
|
||||||
#define DETAILS params.DETAILS
|
#define CDETAILS params.CDETAILS
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
{
|
{
|
||||||
|
@ -71,13 +71,13 @@ void main()
|
||||||
vec3 b11 = 0.5*(c01+c21);
|
vec3 b11 = 0.5*(c01+c21);
|
||||||
|
|
||||||
float contrast = max(max(c11.r,c11.g),c11.b);
|
float contrast = max(max(c11.r,c11.g),c11.b);
|
||||||
contrast = mix(2.0*CONTR, CONTR, contrast);
|
contrast = mix(2.0*CCONTR, CCONTR, contrast);
|
||||||
|
|
||||||
vec3 mn1 = min(c01,c21); mn1 = min(mn1,c11*(1.0-contrast));
|
vec3 mn1 = min(c01,c21); mn1 = min(mn1,c11*(1.0-contrast));
|
||||||
vec3 mx1 = max(c01,c21); mx1 = max(mx1,c11*(1.0+contrast));
|
vec3 mx1 = max(c01,c21); mx1 = max(mx1,c11*(1.0+contrast));
|
||||||
|
|
||||||
vec3 dif = pow(mx1-mn1+0.0001, vec3(0.75,0.75,0.75));
|
vec3 dif = pow(mx1-mn1+0.0001, vec3(0.75,0.75,0.75));
|
||||||
vec3 sharpen = mix(vec3(SHARPEN*DETAILS), vec3(SHARPEN), dif);
|
vec3 sharpen = mix(vec3(CSHARPEN*CDETAILS), vec3(CSHARPEN), dif);
|
||||||
|
|
||||||
c11 = clamp(mix(c11,b11,-sharpen), mn1,mx1);
|
c11 = clamp(mix(c11,b11,-sharpen), mn1,mx1);
|
||||||
|
|
||||||
|
|
697
crt/shaders/guest/advanced/deconvergence-ntsc.slang
Normal file
|
@ -0,0 +1,697 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
/*
|
||||||
|
CRT - Guest - Advanced
|
||||||
|
|
||||||
|
Copyright (C) 2018-2021 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
float IOS, OS, BLOOM, brightboost, brightboost1, csize, bsize1, warpX, warpY, glow, shadowMask, masksize,
|
||||||
|
slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, mshift, mask_layout, mask_bloom;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
float bloom;
|
||||||
|
float halation;
|
||||||
|
float slotms;
|
||||||
|
float mclip;
|
||||||
|
float mask_gamma;
|
||||||
|
float gamma_out;
|
||||||
|
float overscanX;
|
||||||
|
float overscanY;
|
||||||
|
float intres;
|
||||||
|
float prescalex;
|
||||||
|
float c_shape;
|
||||||
|
float barspeed;
|
||||||
|
float barintensity;
|
||||||
|
float bardir;
|
||||||
|
float sborder;
|
||||||
|
float bloom_dist;
|
||||||
|
float deconr;
|
||||||
|
float decons;
|
||||||
|
float addnoised;
|
||||||
|
float noiseresd;
|
||||||
|
float noisetype;
|
||||||
|
float deconrr;
|
||||||
|
float deconrg;
|
||||||
|
float deconrb;
|
||||||
|
float deconrry;
|
||||||
|
float deconrgy;
|
||||||
|
float deconrby;
|
||||||
|
float dctypex;
|
||||||
|
float dctypey;
|
||||||
|
float post_br;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
||||||
|
#define glow params.glow // Glow Strength
|
||||||
|
|
||||||
|
#pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05
|
||||||
|
#define bloom global.bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter mask_bloom " Mask Bloom" 0.0 0.0 2.0 0.05
|
||||||
|
#define mask_bloom params.mask_bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter bloom_dist " Bloom Distribution" 0.0 0.0 3.0 0.05
|
||||||
|
#define bloom_dist global.bloom_dist // bloom effect distribution
|
||||||
|
|
||||||
|
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
||||||
|
#define halation global.halation // halation effect
|
||||||
|
|
||||||
|
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
||||||
|
#define gamma_c global.gamma_c // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05
|
||||||
|
#define brightboost params.brightboost // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025
|
||||||
|
#define brightboost1 params.brightboost1 // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
||||||
|
#define IOS params.IOS // Smart Integer Scaling
|
||||||
|
|
||||||
|
#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
|
||||||
|
#define OS params.OS // Do overscan
|
||||||
|
|
||||||
|
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
||||||
|
#define BLOOM params.BLOOM // Bloom overscan percentage
|
||||||
|
|
||||||
|
#pragma parameter csize " Corner Size" 0.0 0.0 0.25 0.005
|
||||||
|
#define csize params.csize // corner size
|
||||||
|
|
||||||
|
#pragma parameter bsize1 " Border Size" 0.01 0.0 3.0 0.01
|
||||||
|
#define bsize1 params.bsize1 // border Size
|
||||||
|
|
||||||
|
#pragma parameter sborder " Border Intensity" 0.75 0.25 2.0 0.05
|
||||||
|
#define sborder global.sborder // border intensity
|
||||||
|
|
||||||
|
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpX params.warpX // Curvature X
|
||||||
|
|
||||||
|
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpY params.warpY // Curvature Y
|
||||||
|
|
||||||
|
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
||||||
|
#define c_shape global.c_shape // curvature shape
|
||||||
|
|
||||||
|
#pragma parameter overscanX " Overscan X original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanX global.overscanX // OverscanX pixels
|
||||||
|
|
||||||
|
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanY global.overscanY // OverscanY pixels
|
||||||
|
|
||||||
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0
|
||||||
|
#define prescalex global.prescalex // prescale-x factor
|
||||||
|
|
||||||
|
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-12:'Trinitron'" 0.0 -1.0 12.0 1.0
|
||||||
|
#define shadowMask params.shadowMask // Mask Style
|
||||||
|
|
||||||
|
#pragma parameter maskstr " Mask Strength (0, 5-12)" 0.3 -0.5 1.0 0.025
|
||||||
|
#define maskstr params.maskstr // Mask Strength
|
||||||
|
|
||||||
|
#pragma parameter mcut " Mask 5-12 Low Strength" 1.10 0.0 2.0 0.05
|
||||||
|
#define mcut params.mcut // Mask 5-12 dark color strength
|
||||||
|
|
||||||
|
#pragma parameter masksize " CRT Mask Size" 1.0 1.0 4.0 1.0
|
||||||
|
#define masksize params.masksize // Mask Size
|
||||||
|
|
||||||
|
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
||||||
|
#define maskDark params.maskDark // Dark "Phosphor"
|
||||||
|
|
||||||
|
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
||||||
|
#define maskLight params.maskLight // Light "Phosphor"
|
||||||
|
|
||||||
|
#pragma parameter mshift " Mask Shift/Stagger" 0.0 -8.0 8.0 1.0
|
||||||
|
#define mshift params.mshift // mask 'line' shift/stagger
|
||||||
|
|
||||||
|
#pragma parameter mask_layout " Mask Layout: RGB or BGR (check LCD panel) " 0.0 0.0 1.0 1.0
|
||||||
|
#define mask_layout params.mask_layout // mask layout: RGB or BGR
|
||||||
|
|
||||||
|
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05
|
||||||
|
#define mask_gamma global.mask_gamma // Mask application gamma
|
||||||
|
|
||||||
|
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
||||||
|
#define slotmask params.slotmask
|
||||||
|
|
||||||
|
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
||||||
|
#define slotmask1 params.slotmask1
|
||||||
|
|
||||||
|
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0
|
||||||
|
#define slotwidth params.slotwidth // Slot Mask Width
|
||||||
|
|
||||||
|
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0
|
||||||
|
#define double_slot params.double_slot // Slot Mask Height
|
||||||
|
|
||||||
|
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
||||||
|
#define slotms global.slotms // Slot Mask Size
|
||||||
|
|
||||||
|
#pragma parameter mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05
|
||||||
|
#define mclip global.mclip //
|
||||||
|
|
||||||
|
#pragma parameter gamma_out "Gamma out" 1.95 1.0 5.0 0.05
|
||||||
|
#define gamma_out global.gamma_out // output gamma
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter bogus_deconvergence11 "[ HORIZONTAL/VERTICAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter dctypex " Deconvergence type X : 0.0 - static, other - dynamic" 0.0 0.0 0.75 0.05
|
||||||
|
|
||||||
|
#pragma parameter dctypey " Deconvergence type Y : 0.0 - static, other - dynamic" 0.0 0.0 0.75 0.05
|
||||||
|
|
||||||
|
#pragma parameter deconrr " Horizontal Deconvergence Red Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrg " Horizontal Deconvergence Green Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrb " Horizontal Deconvergence Blue Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrry " Vertical Deconvergence Red Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrgy " Vertical Deconvergence Green Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrby " Vertical Deconvergence Blue Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter decons " Deconvergence Strength" 1.0 0.0 3.0 0.10
|
||||||
|
|
||||||
|
#pragma parameter addnoised " Add Noise" 0.0 -1.0 1.0 0.02
|
||||||
|
|
||||||
|
#pragma parameter noiseresd " Noise Resolution" 2.0 1.0 10.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter noisetype " Noise Type: Colored, Luma" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter post_br " Post Brightness" 1.0 0.25 5.0 0.01
|
||||||
|
|
||||||
|
|
||||||
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
|
#define TEX0 vTexCoord
|
||||||
|
|
||||||
|
#define OutputSize global.OutputSize
|
||||||
|
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
||||||
|
|
||||||
|
#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 LinearizePass;
|
||||||
|
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D GlowPass;
|
||||||
|
layout(set = 0, binding = 5) uniform sampler2D BloomPass;
|
||||||
|
layout(set = 0, binding = 6) uniform sampler2D PrePass0;
|
||||||
|
layout(set = 0, binding = 7) uniform sampler2D Source;
|
||||||
|
|
||||||
|
#define eps 1e-10
|
||||||
|
|
||||||
|
// Shadow mask (1-4 from PD CRT Lottes shader).
|
||||||
|
|
||||||
|
vec3 Mask(vec2 pos, float mx)
|
||||||
|
{
|
||||||
|
vec2 pos0 = pos;
|
||||||
|
pos.y = floor(pos.y/masksize);
|
||||||
|
float next_line = float(fract(pos.y*0.5) > 0.25);
|
||||||
|
pos0.x = (mshift > -0.25) ? (pos0.x + next_line * mshift) : (pos0.x + pos.y * mshift);
|
||||||
|
pos = floor(pos0/masksize);
|
||||||
|
|
||||||
|
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.4, 0.0) + 1.0, 1.0, mx);
|
||||||
|
float mc = 1.0 - max(maskstr, 0.0);
|
||||||
|
|
||||||
|
// No mask
|
||||||
|
if (shadowMask == -1.0)
|
||||||
|
{
|
||||||
|
mask = vec3(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phosphor.
|
||||||
|
else if (shadowMask == 0.0)
|
||||||
|
{
|
||||||
|
pos.x = fract(pos.x*0.5);
|
||||||
|
if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
||||||
|
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Very compressed TV style shadow mask.
|
||||||
|
else if (shadowMask == 1.0)
|
||||||
|
{
|
||||||
|
float line = maskLight;
|
||||||
|
float odd = 0.0;
|
||||||
|
|
||||||
|
if (fract(pos.x/6.0) < 0.49)
|
||||||
|
odd = 1.0;
|
||||||
|
if (fract((pos.y + odd)/2.0) < 0.49)
|
||||||
|
line = maskDark;
|
||||||
|
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
|
||||||
|
mask*=line;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aperture-grille.
|
||||||
|
else if (shadowMask == 2.0)
|
||||||
|
{
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stretched VGA style shadow mask (same as prior shaders).
|
||||||
|
else if (shadowMask == 3.0)
|
||||||
|
{
|
||||||
|
pos.x += pos.y*3.0;
|
||||||
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VGA style shadow mask.
|
||||||
|
else if (shadowMask == 4.0)
|
||||||
|
{
|
||||||
|
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
||||||
|
pos.x += pos.y*3.0;
|
||||||
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trinitron mask 5
|
||||||
|
else if (shadowMask == 5.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/2.0);
|
||||||
|
if (pos.x < 0.49)
|
||||||
|
{ mask.r = 1.0;
|
||||||
|
mask.b = 1.0;
|
||||||
|
}
|
||||||
|
else mask.g = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trinitron mask 6
|
||||||
|
else if (shadowMask == 6.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.6) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BW Trinitron mask 7
|
||||||
|
else if (shadowMask == 7.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/2.0);
|
||||||
|
if (pos.x < 0.49)
|
||||||
|
{ mask = 0.0.xxx;
|
||||||
|
}
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BW Trinitron mask 8
|
||||||
|
else if (shadowMask == 8.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask = 1.0.xxx;
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magenta - Green - Black mask
|
||||||
|
else if (shadowMask == 9.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask.rb = 1.0.xx;
|
||||||
|
else mask.g = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RGBX
|
||||||
|
else if (shadowMask == 10.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.4) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.7) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4k mask
|
||||||
|
else if (shadowMask == 11.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
||||||
|
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RRGGBBX mask
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = floor(mod(pos.x,7.0));
|
||||||
|
if (pos.x < 1.0) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 3.0) mask.r = 1.0;
|
||||||
|
else if (pos.x < 5.0) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SlotMask(vec2 pos, float m)
|
||||||
|
{
|
||||||
|
if ((slotmask + slotmask1) == 0.0) return 1.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos = floor(pos/slotms);
|
||||||
|
float mlen = slotwidth*2.0;
|
||||||
|
float px = fract(pos.x/mlen);
|
||||||
|
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
||||||
|
float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m);
|
||||||
|
float slot = 1.0;
|
||||||
|
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
||||||
|
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Warp(vec2 pos)
|
||||||
|
{
|
||||||
|
pos = pos*2.0-1.0;
|
||||||
|
pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape);
|
||||||
|
return pos*0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Overscan(vec2 pos, float dx, float dy){
|
||||||
|
pos=pos*2.0-1.0;
|
||||||
|
pos*=vec2(dx,dy);
|
||||||
|
return pos*0.5+0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
float humbar(float pos)
|
||||||
|
{
|
||||||
|
if (global.barintensity == 0.0) return 1.0; else
|
||||||
|
{
|
||||||
|
pos = (global.barintensity >= 0.0) ? pos : (1.0-pos);
|
||||||
|
pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0));
|
||||||
|
pos = (global.barintensity < 0.0) ? pos : (1.0-pos);
|
||||||
|
return (1.0-global.barintensity) + global.barintensity*pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float corner(vec2 pos) {
|
||||||
|
vec2 b = vec2(bsize1, bsize1) * vec2(1.0, OutputSize.x/OutputSize.y) * 0.05;
|
||||||
|
pos = clamp(pos, 0.0, 1.0);
|
||||||
|
pos = abs(2.0*(pos - 0.5));
|
||||||
|
float csize1 = mix(400.0, 7.0, pow(4.0*csize, 0.10));
|
||||||
|
float crn = dot(pow(pos, csize1.xx), vec2(1.0, OutputSize.y/OutputSize.x));
|
||||||
|
crn = (csize == 0.0) ? max(pos.x, pos.y) : pow(crn, 1.0/csize1);
|
||||||
|
pos = max(pos, crn);
|
||||||
|
vec2 res = (bsize1 == 0.0) ? 1.0.xx : mix(0.0.xx, 1.0.xx, smoothstep(1.0.xx, 1.0.xx-b, sqrt(pos)));
|
||||||
|
res = pow(res, sborder.xx);
|
||||||
|
return sqrt(res.x*res.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 plant (vec3 tar, float r)
|
||||||
|
{
|
||||||
|
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
||||||
|
return tar * r / t;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 declip(vec3 c, float b)
|
||||||
|
{
|
||||||
|
float m = max(max(c.r,c.g),c.b);
|
||||||
|
if (m > b) c = c*b/m;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// noise function:
|
||||||
|
// Dedicated to the public domain.
|
||||||
|
// If you want a real license, you may consider this MIT/BSD/CC0/WTFPL-licensed (take your pick).
|
||||||
|
// Adapted from ChuckNorris - shadertoy: https://www.shadertoy.com/view/XtK3Dz
|
||||||
|
|
||||||
|
vec3 noise(vec3 v){
|
||||||
|
if (global.addnoised < 0.0) v.z = -global.addnoised; else v.z = mod(v.z,6001.0)/1753.0;
|
||||||
|
// ensure reasonable range
|
||||||
|
v = fract(v) + fract(v*1e4) + fract(v*1e-4);
|
||||||
|
// seed
|
||||||
|
v += vec3(0.12345, 0.6789, 0.314159);
|
||||||
|
// more iterations => more random
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fetch_pixel (inout vec3 c, inout vec3 b, vec2 coord, vec2 bcoord)
|
||||||
|
{
|
||||||
|
float stepx = OutputSize.z;
|
||||||
|
float stepy = OutputSize.w;
|
||||||
|
|
||||||
|
float ds = global.decons;
|
||||||
|
|
||||||
|
vec2 dx = vec2(stepx, 0.0);
|
||||||
|
vec2 dy = vec2(0.0, stepy);
|
||||||
|
|
||||||
|
float posx = 2.0*coord.x - 1.0;
|
||||||
|
float posy = 2.0*coord.y - 1.0;
|
||||||
|
|
||||||
|
if (global.dctypex > 0.025)
|
||||||
|
{
|
||||||
|
posx = sign(posx)*pow(abs(posx), 1.05-global.dctypex);
|
||||||
|
dx = posx * dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global.dctypey > 0.025)
|
||||||
|
{
|
||||||
|
|
||||||
|
posy = sign(posy)*pow(abs(posy), 1.05-global.dctypey);
|
||||||
|
dy = posy * dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (global.dctypex > 0.025 || global.dctypey > 0.025) ds *= sqrt(posx*posx*sign(global.dctypex) + posy*posy*sign(global.dctypey));
|
||||||
|
|
||||||
|
vec2 rc = global.deconrr * dx + global.deconrry*dy;
|
||||||
|
vec2 gc = global.deconrg * dx + global.deconrgy*dy;
|
||||||
|
vec2 bc = global.deconrb * dx + global.deconrby*dy;
|
||||||
|
|
||||||
|
float r1 = COMPAT_TEXTURE(Source, coord + rc).r;
|
||||||
|
float g1 = COMPAT_TEXTURE(Source, coord + gc).g;
|
||||||
|
float b1 = COMPAT_TEXTURE(Source, coord + bc).b;
|
||||||
|
|
||||||
|
vec3 d = vec3(r1, g1, b1);
|
||||||
|
c = clamp(mix(c, d, ds), 0.0, 1.0);
|
||||||
|
|
||||||
|
r1 = COMPAT_TEXTURE(BloomPass, bcoord + rc).r;
|
||||||
|
g1 = COMPAT_TEXTURE(BloomPass, bcoord + gc).g;
|
||||||
|
b1 = COMPAT_TEXTURE(BloomPass, bcoord + bc).b;
|
||||||
|
|
||||||
|
d = vec3(r1, g1, b1);
|
||||||
|
b = clamp(mix(b, d, ds), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 SourceSize = global.OriginalSize * vec4(prescalex, 1.0, 1.0/prescalex, 1.0);
|
||||||
|
|
||||||
|
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.5,0.5)).a;
|
||||||
|
|
||||||
|
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
||||||
|
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
||||||
|
bool interb = (intera < 0.5);
|
||||||
|
|
||||||
|
// Calculating texel coordinates
|
||||||
|
|
||||||
|
vec2 texcoord = TEX0.xy;
|
||||||
|
if (IOS > 0.0 && !interb){
|
||||||
|
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
||||||
|
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
||||||
|
vec2 diff = ofactor/intfactor;
|
||||||
|
float scan = diff.y;
|
||||||
|
texcoord = Overscan(texcoord, scan, scan);
|
||||||
|
if (IOS == 1.0 || IOS == 3.0) texcoord = vec2(TEX0.x, texcoord.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
||||||
|
texcoord = Overscan(texcoord, factor, factor);
|
||||||
|
|
||||||
|
texcoord = Overscan(texcoord, (global.OriginalSize.x - overscanX)/global.OriginalSize.x, (global.OriginalSize.y - overscanY)/global.OriginalSize.y);
|
||||||
|
|
||||||
|
vec2 pos1 = TEX0.xy;
|
||||||
|
vec2 pos = Warp(texcoord);
|
||||||
|
vec2 pos0 = Warp(TEX0.xy);
|
||||||
|
vec3 color0 = COMPAT_TEXTURE(Source,pos1).rgb;
|
||||||
|
float c0 = max(max(color0.r, color0.g),color0.b);
|
||||||
|
|
||||||
|
// color and bloom fetching
|
||||||
|
vec3 color = COMPAT_TEXTURE(Source,pos1).rgb;
|
||||||
|
vec3 Bloom = COMPAT_TEXTURE(BloomPass, pos).rgb;
|
||||||
|
fetch_pixel(color, Bloom, pos1, pos);
|
||||||
|
|
||||||
|
float cm = max(max(color.r,color.g),color.b);
|
||||||
|
float mx1 = COMPAT_TEXTURE(Source, pos1 ).a;
|
||||||
|
float colmx = max(mx1, cm);
|
||||||
|
float w3 = min((c0 + 0.0005) / (pow(colmx, gamma_in/1.4) + 0.0005), 1.0);
|
||||||
|
|
||||||
|
vec2 dx = vec2(0.001, 0.0);
|
||||||
|
float mx0 = COMPAT_TEXTURE(Source, pos1 - dx).a;
|
||||||
|
float mx2 = COMPAT_TEXTURE(Source, pos1 + dx).a;
|
||||||
|
float mx = max(max(mx0,mx1),max(mx2,cm));
|
||||||
|
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
|
||||||
|
// Apply Mask
|
||||||
|
|
||||||
|
vec3 orig1 = color;
|
||||||
|
vec3 cmask = one;
|
||||||
|
|
||||||
|
vec2 maskcoord = gl_FragCoord.xy * 1.000001;
|
||||||
|
|
||||||
|
float smask = SlotMask(maskcoord, mx);
|
||||||
|
cmask*= Mask(maskcoord, mx);
|
||||||
|
|
||||||
|
if (mask_layout > 0.5) cmask = cmask.rbg;
|
||||||
|
|
||||||
|
vec3 cmask1 = cmask;
|
||||||
|
float smask1 = smask;
|
||||||
|
|
||||||
|
if (mask_bloom > 0.025)
|
||||||
|
{
|
||||||
|
float maxb = max(max(Bloom.r,Bloom.g),Bloom.b);
|
||||||
|
maxb = pow(sqrt(maxb*mix(maxb, colmx, 0.75)),0.275);
|
||||||
|
vec3 mBloom = 0.5*(1.5*Bloom+0.5*maxb) * mix(1.0, 2.0-colmx, (bloom_dist + 0.5));
|
||||||
|
float maskmx = 1.0; if (shadowMask > 0.5 || shadowMask < 4.5) maskmx = maskLight; else if (shadowMask > 6.5 && shadowMask < 10.5) maskmx = 1.0; else maskmx = max(max(cmask.r,cmask.g),cmask.b);
|
||||||
|
cmask = min(cmask + maxb*mBloom*mask_bloom, maskmx);
|
||||||
|
smask = min(smask + 0.9*maxb*max(max(mBloom.r,mBloom.g),mBloom.b)*mask_bloom, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
color = pow(color, vec3(mask_gamma/gamma_in));
|
||||||
|
color = color*cmask;
|
||||||
|
color = min(color,1.0);
|
||||||
|
color = color*smask;
|
||||||
|
color = pow(color, vec3(gamma_in/mask_gamma));
|
||||||
|
|
||||||
|
cmask = min(cmask*smask, 1.0);
|
||||||
|
cmask1 = min(cmask1*smask1, 1.0);
|
||||||
|
|
||||||
|
float bb = mix(brightboost, brightboost1, colmx);
|
||||||
|
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
||||||
|
color*=bb;
|
||||||
|
|
||||||
|
vec3 Glow = COMPAT_TEXTURE(GlowPass, pos).rgb;
|
||||||
|
vec3 Ref = COMPAT_TEXTURE(LinearizePass, pos).rgb;
|
||||||
|
float maxb = COMPAT_TEXTURE(BloomPass, pos).a;
|
||||||
|
float vig = COMPAT_TEXTURE(PrePass0, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a;
|
||||||
|
|
||||||
|
vec3 Bloom1 = Bloom;
|
||||||
|
|
||||||
|
if (bloom < -0.01) Bloom1 = plant(Bloom, maxb);
|
||||||
|
|
||||||
|
Bloom1 = min(Bloom1*(orig1+color), max(0.5*(colmx + orig1 - color),0.001*Bloom1));
|
||||||
|
Bloom1 = 0.5*(Bloom1 + mix(Bloom1, mix(colmx*orig1, Bloom1, 0.5), 1.0-color));
|
||||||
|
|
||||||
|
Bloom1 = Bloom1 * mix(1.0, 2.0-colmx, bloom_dist);
|
||||||
|
|
||||||
|
color = color + abs(bloom) * Bloom1;
|
||||||
|
|
||||||
|
color = min(color, mix(one, cmask1, mclip));
|
||||||
|
|
||||||
|
if (!interb) color = declip(color, mix(1.0, w3, 0.6)); else w3 = 1.0;
|
||||||
|
|
||||||
|
if (halation > 0.01) {
|
||||||
|
Bloom = mix(0.5*(Bloom + Bloom*Bloom), 0.75*Bloom*Bloom, colmx);
|
||||||
|
color = color + 2.0*max((2.0*mix(maxb*maxb, maxb, colmx)-0.5*max(max(Ref.r,Ref.g),Ref.b)),0.25)*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.6)*Bloom*halation; }
|
||||||
|
|
||||||
|
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
||||||
|
if (glow >= 0.0) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + (-glow)*cmask*Glow; }
|
||||||
|
|
||||||
|
color = min(color, 1.0);
|
||||||
|
|
||||||
|
color = pow(color, vec3(1.0/gamma_out));
|
||||||
|
|
||||||
|
float rc = 0.6*sqrt(max(max(color.r, color.g), color.b))+0.4;
|
||||||
|
|
||||||
|
if (abs(global.addnoised) > 0.01)
|
||||||
|
{
|
||||||
|
vec3 noise0 = noise(vec3(floor(OutputSize.xy * vTexCoord / global.noiseresd), float(global.FrameCount)));
|
||||||
|
if (global.noisetype < 0.5) color = mix(color, noise0, 0.25*abs(global.addnoised) * rc);
|
||||||
|
else color = min(color * mix(1.0, 1.5*noise0.x, 0.5*abs(global.addnoised)), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir))*global.post_br*corner(pos0), 1.0);
|
||||||
|
}
|
|
@ -1,9 +1,12 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CRT - Guest - Advanced - Deconvergence pass + noise
|
CRT - Guest - Advanced
|
||||||
|
|
||||||
Copyright (C) 2021 guest(r) - guest.r@gmail.com
|
Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -23,63 +26,208 @@
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
|
float TATE, IOS, OS, BLOOM, brightboost, brightboost1, csize, bsize1, warpX, warpY, glow, shadowMask, masksize,
|
||||||
|
slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, mshift, mask_layout, mask_bloom;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
|
float bloom;
|
||||||
|
float halation;
|
||||||
|
float slotms;
|
||||||
|
float mclip;
|
||||||
|
float mask_gamma;
|
||||||
|
float gamma_out;
|
||||||
|
float overscanX;
|
||||||
|
float overscanY;
|
||||||
|
float intres;
|
||||||
|
float prescalex;
|
||||||
|
float c_shape;
|
||||||
|
float barspeed;
|
||||||
|
float barintensity;
|
||||||
|
float bardir;
|
||||||
|
float sborder;
|
||||||
|
float bloom_dist;
|
||||||
float deconr;
|
float deconr;
|
||||||
float TATE;
|
|
||||||
float decons;
|
float decons;
|
||||||
float addnoised;
|
float addnoised;
|
||||||
|
float noisetype;
|
||||||
float noiseresd;
|
float noiseresd;
|
||||||
float shadowMask;
|
|
||||||
float masksize;
|
|
||||||
float deconrr;
|
float deconrr;
|
||||||
float deconrg;
|
float deconrg;
|
||||||
float deconrb;
|
float deconrb;
|
||||||
float deconrry;
|
float deconrry;
|
||||||
float deconrgy;
|
float deconrgy;
|
||||||
float deconrby;
|
float deconrby;
|
||||||
float deconsmooth;
|
|
||||||
float dctypex;
|
float dctypex;
|
||||||
float dctypey;
|
float dctypey;
|
||||||
} params;
|
float post_br;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
||||||
|
#define glow params.glow // Glow Strength
|
||||||
|
|
||||||
|
#pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05
|
||||||
|
#define bloom global.bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter mask_bloom " Mask Bloom" 0.0 0.0 2.0 0.05
|
||||||
|
#define mask_bloom params.mask_bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter bloom_dist " Bloom Distribution" 0.0 0.0 3.0 0.05
|
||||||
|
#define bloom_dist global.bloom_dist // bloom effect distribution
|
||||||
|
|
||||||
|
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
||||||
|
#define halation global.halation // halation effect
|
||||||
|
|
||||||
|
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
||||||
|
#define gamma_c global.gamma_c // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05
|
||||||
|
#define brightboost params.brightboost // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025
|
||||||
|
#define brightboost1 params.brightboost1 // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0
|
#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0
|
||||||
#define TATE params.TATE // Screen orientation
|
#define TATE params.TATE // Screen orientation
|
||||||
|
|
||||||
|
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
||||||
|
#define IOS params.IOS // Smart Integer Scaling
|
||||||
|
|
||||||
|
#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
|
||||||
|
#define OS params.OS // Do overscan
|
||||||
|
|
||||||
|
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
||||||
|
#define BLOOM params.BLOOM // Bloom overscan percentage
|
||||||
|
|
||||||
|
#pragma parameter csize " Corner Size" 0.0 0.0 0.25 0.005
|
||||||
|
#define csize params.csize // corner size
|
||||||
|
|
||||||
|
#pragma parameter bsize1 " Border Size" 0.01 0.0 3.0 0.01
|
||||||
|
#define bsize1 params.bsize1 // border Size
|
||||||
|
|
||||||
|
#pragma parameter sborder " Border Intensity" 0.75 0.25 2.0 0.05
|
||||||
|
#define sborder global.sborder // border intensity
|
||||||
|
|
||||||
|
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpX params.warpX // Curvature X
|
||||||
|
|
||||||
|
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpY params.warpY // Curvature Y
|
||||||
|
|
||||||
|
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
||||||
|
#define c_shape global.c_shape // curvature shape
|
||||||
|
|
||||||
|
#pragma parameter overscanX " Overscan X original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanX global.overscanX // OverscanX pixels
|
||||||
|
|
||||||
|
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanY global.overscanY // OverscanY pixels
|
||||||
|
|
||||||
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0
|
||||||
|
#define prescalex global.prescalex // prescale-x factor
|
||||||
|
|
||||||
|
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-12:'Trinitron'" 0.0 -1.0 12.0 1.0
|
||||||
|
#define shadowMask params.shadowMask // Mask Style
|
||||||
|
|
||||||
|
#pragma parameter maskstr " Mask Strength (0, 5-12)" 0.3 -0.5 1.0 0.025
|
||||||
|
#define maskstr params.maskstr // Mask Strength
|
||||||
|
|
||||||
|
#pragma parameter mcut " Mask 5-12 Low Strength" 1.10 0.0 2.0 0.05
|
||||||
|
#define mcut params.mcut // Mask 5-12 dark color strength
|
||||||
|
|
||||||
|
#pragma parameter masksize " CRT Mask Size" 1.0 1.0 4.0 1.0
|
||||||
|
#define masksize params.masksize // Mask Size
|
||||||
|
|
||||||
|
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
||||||
|
#define maskDark params.maskDark // Dark "Phosphor"
|
||||||
|
|
||||||
|
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
||||||
|
#define maskLight params.maskLight // Light "Phosphor"
|
||||||
|
|
||||||
|
#pragma parameter mshift " Mask Shift/Stagger" 0.0 -8.0 8.0 1.0
|
||||||
|
#define mshift params.mshift // mask 'line' shift/stagger
|
||||||
|
|
||||||
|
#pragma parameter mask_layout " Mask Layout: RGB or BGR (check LCD panel) " 0.0 0.0 1.0 1.0
|
||||||
|
#define mask_layout params.mask_layout // mask layout: RGB or BGR
|
||||||
|
|
||||||
|
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05
|
||||||
|
#define mask_gamma global.mask_gamma // Mask application gamma
|
||||||
|
|
||||||
|
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
||||||
|
#define slotmask params.slotmask
|
||||||
|
|
||||||
|
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
||||||
|
#define slotmask1 params.slotmask1
|
||||||
|
|
||||||
|
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0
|
||||||
|
#define slotwidth params.slotwidth // Slot Mask Width
|
||||||
|
|
||||||
|
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0
|
||||||
|
#define double_slot params.double_slot // Slot Mask Height
|
||||||
|
|
||||||
|
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
||||||
|
#define slotms global.slotms // Slot Mask Size
|
||||||
|
|
||||||
|
#pragma parameter mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05
|
||||||
|
#define mclip global.mclip //
|
||||||
|
|
||||||
|
#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05
|
||||||
|
#define gamma_out global.gamma_out // output gamma
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter bogus_deconvergence11 "[ HORIZONTAL/VERTICAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_deconvergence11 "[ HORIZONTAL/VERTICAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter dctypex " Deconvergence type X : 0.0 - static, other - dynamic" 0.0 0.0 1.0 0.05
|
#pragma parameter dctypex " Deconvergence type X : 0.0 - static, other - dynamic" 0.0 0.0 0.75 0.05
|
||||||
|
|
||||||
#pragma parameter dctypey " Deconvergence type Y : 0.0 - static, other - dynamic" 0.0 0.0 1.0 0.05
|
#pragma parameter dctypey " Deconvergence type Y : 0.0 - static, other - dynamic" 0.0 0.0 0.75 0.05
|
||||||
|
|
||||||
#pragma parameter deconrr " Horizontal Deconvergence Red Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrr " Horizontal Deconvergence Red Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrg " Horizontal Deconvergence Green Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrg " Horizontal Deconvergence Green Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrb " Horizontal Deconvergence Blue Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrb " Horizontal Deconvergence Blue Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrry " Vertical Deconvergence Red Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrry " Vertical Deconvergence Red Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrgy " Vertical Deconvergence Green Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrgy " Vertical Deconvergence Green Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrby " Vertical Deconvergence Blue Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrby " Vertical Deconvergence Blue Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter decons " Deconvergence Strength (and Type)" 0.5 -4.0 4.0 0.10
|
#pragma parameter decons " Deconvergence Strength" 1.0 0.0 3.0 0.10
|
||||||
#define decons params.decons // Horizontal deconvergence colors strength
|
|
||||||
|
|
||||||
#pragma parameter deconsmooth " Deconvergence Smoothing" 0.0 0.0 1.0 0.10
|
|
||||||
|
|
||||||
#pragma parameter addnoised " Add Noise" 0.0 -1.0 1.0 0.02
|
#pragma parameter addnoised " Add Noise" 0.0 -1.0 1.0 0.02
|
||||||
#define addnoised params.addnoised // add noise
|
|
||||||
|
|
||||||
#pragma parameter noiseresd " Noise Resolution" 2.0 0.0 10.0 1.0
|
#pragma parameter noiseresd " Noise Resolution" 2.0 1.0 10.0 1.0
|
||||||
#define noiseresd params.noiseresd // add noise
|
|
||||||
|
#pragma parameter noisetype " Noise Type: Colored, Luma" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter post_br " Post Brightness" 1.0 0.25 5.0 0.01
|
||||||
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
{
|
#define TEX0 vTexCoord
|
||||||
mat4 MVP;
|
|
||||||
} global;
|
#define OutputSize global.OutputSize
|
||||||
|
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
||||||
|
|
||||||
#pragma stage vertex
|
#pragma stage vertex
|
||||||
layout(location = 0) in vec4 Position;
|
layout(location = 0) in vec4 Position;
|
||||||
|
@ -89,16 +237,269 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
layout(set = 0, binding = 2) uniform sampler2D LinearizePass;
|
||||||
|
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D GlowPass;
|
||||||
|
layout(set = 0, binding = 5) uniform sampler2D BloomPass;
|
||||||
|
layout(set = 0, binding = 6) uniform sampler2D PrePass;
|
||||||
|
layout(set = 0, binding = 7) uniform sampler2D Source;
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
#define eps 1e-10
|
||||||
|
|
||||||
|
// Shadow mask (1-4 from PD CRT Lottes shader).
|
||||||
|
|
||||||
|
vec3 Mask(vec2 pos, float mx)
|
||||||
|
{
|
||||||
|
vec2 pos0 = pos;
|
||||||
|
pos.y = floor(pos.y/masksize);
|
||||||
|
float next_line = float(fract(pos.y*0.5) > 0.25);
|
||||||
|
pos0.x = (mshift > -0.25) ? (pos0.x + next_line * mshift) : (pos0.x + pos.y * mshift);
|
||||||
|
pos = floor(pos0/masksize);
|
||||||
|
|
||||||
|
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.4, 0.0) + 1.0, 1.0, mx);
|
||||||
|
float mc = 1.0 - max(maskstr, 0.0);
|
||||||
|
|
||||||
|
// No mask
|
||||||
|
if (shadowMask == -1.0)
|
||||||
|
{
|
||||||
|
mask = vec3(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phosphor.
|
||||||
|
else if (shadowMask == 0.0)
|
||||||
|
{
|
||||||
|
pos.x = fract(pos.x*0.5);
|
||||||
|
if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
||||||
|
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Very compressed TV style shadow mask.
|
||||||
|
else if (shadowMask == 1.0)
|
||||||
|
{
|
||||||
|
float line = maskLight;
|
||||||
|
float odd = 0.0;
|
||||||
|
|
||||||
|
if (fract(pos.x/6.0) < 0.49)
|
||||||
|
odd = 1.0;
|
||||||
|
if (fract((pos.y + odd)/2.0) < 0.49)
|
||||||
|
line = maskDark;
|
||||||
|
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
|
||||||
|
mask*=line;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aperture-grille.
|
||||||
|
else if (shadowMask == 2.0)
|
||||||
|
{
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stretched VGA style shadow mask (same as prior shaders).
|
||||||
|
else if (shadowMask == 3.0)
|
||||||
|
{
|
||||||
|
pos.x += pos.y*3.0;
|
||||||
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VGA style shadow mask.
|
||||||
|
else if (shadowMask == 4.0)
|
||||||
|
{
|
||||||
|
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
||||||
|
pos.x += pos.y*3.0;
|
||||||
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trinitron mask 5
|
||||||
|
else if (shadowMask == 5.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/2.0);
|
||||||
|
if (pos.x < 0.49)
|
||||||
|
{ mask.r = 1.0;
|
||||||
|
mask.b = 1.0;
|
||||||
|
}
|
||||||
|
else mask.g = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trinitron mask 6
|
||||||
|
else if (shadowMask == 6.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.6) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BW Trinitron mask 7
|
||||||
|
else if (shadowMask == 7.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/2.0);
|
||||||
|
if (pos.x < 0.49)
|
||||||
|
{ mask = 0.0.xxx;
|
||||||
|
}
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BW Trinitron mask 8
|
||||||
|
else if (shadowMask == 8.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask = 1.0.xxx;
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magenta - Green - Black mask
|
||||||
|
else if (shadowMask == 9.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask.rb = 1.0.xx;
|
||||||
|
else mask.g = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RGBX
|
||||||
|
else if (shadowMask == 10.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.4) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.7) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4k mask
|
||||||
|
else if (shadowMask == 11.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
||||||
|
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RRGGBBX mask
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = floor(mod(pos.x,7.0));
|
||||||
|
if (pos.x < 1.0) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 3.0) mask.r = 1.0;
|
||||||
|
else if (pos.x < 5.0) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SlotMask(vec2 pos, float m)
|
||||||
|
{
|
||||||
|
if ((slotmask + slotmask1) == 0.0) return 1.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos = floor(pos/slotms);
|
||||||
|
float mlen = slotwidth*2.0;
|
||||||
|
float px = fract(pos.x/mlen);
|
||||||
|
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
||||||
|
float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m);
|
||||||
|
float slot = 1.0;
|
||||||
|
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
||||||
|
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Warp(vec2 pos)
|
||||||
|
{
|
||||||
|
pos = pos*2.0-1.0;
|
||||||
|
pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape);
|
||||||
|
return pos*0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Overscan(vec2 pos, float dx, float dy){
|
||||||
|
pos=pos*2.0-1.0;
|
||||||
|
pos*=vec2(dx,dy);
|
||||||
|
return pos*0.5+0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
float humbar(float pos)
|
||||||
|
{
|
||||||
|
if (global.barintensity == 0.0) return 1.0; else
|
||||||
|
{
|
||||||
|
pos = (global.barintensity >= 0.0) ? pos : (1.0-pos);
|
||||||
|
pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0));
|
||||||
|
pos = (global.barintensity < 0.0) ? pos : (1.0-pos);
|
||||||
|
return (1.0-global.barintensity) + global.barintensity*pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float corner(vec2 pos) {
|
||||||
|
vec2 b = vec2(bsize1, bsize1) * vec2(1.0, OutputSize.x/OutputSize.y) * 0.05;
|
||||||
|
pos = clamp(pos, 0.0, 1.0);
|
||||||
|
pos = abs(2.0*(pos - 0.5));
|
||||||
|
float csize1 = mix(400.0, 7.0, pow(4.0*csize, 0.10));
|
||||||
|
float crn = dot(pow(pos, csize1.xx), vec2(1.0, OutputSize.y/OutputSize.x));
|
||||||
|
crn = (csize == 0.0) ? max(pos.x, pos.y) : pow(crn, 1.0/csize1);
|
||||||
|
pos = max(pos, crn);
|
||||||
|
vec2 res = (bsize1 == 0.0) ? 1.0.xx : mix(0.0.xx, 1.0.xx, smoothstep(1.0.xx, 1.0.xx-b, sqrt(pos)));
|
||||||
|
res = pow(res, sborder.xx);
|
||||||
|
return sqrt(res.x*res.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 plant (vec3 tar, float r)
|
||||||
|
{
|
||||||
|
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
||||||
|
return tar * r / t;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 declip(vec3 c, float b)
|
||||||
|
{
|
||||||
|
float m = max(max(c.r,c.g),c.b);
|
||||||
|
if (m > b) c = c*b/m;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
// noise function:
|
// noise function:
|
||||||
// Dedicated to the public domain.
|
// Dedicated to the public domain.
|
||||||
|
@ -106,93 +507,198 @@ layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
// Adapted from ChuckNorris - shadertoy: https://www.shadertoy.com/view/XtK3Dz
|
// Adapted from ChuckNorris - shadertoy: https://www.shadertoy.com/view/XtK3Dz
|
||||||
|
|
||||||
vec3 noise(vec3 v){
|
vec3 noise(vec3 v){
|
||||||
if (addnoised < 0.0) v.z = -addnoised; else v.z = v.z/6000.0;
|
if (global.addnoised < 0.0) v.z = -global.addnoised; else v.z = mod(v.z,6001.0)/1753.0;
|
||||||
// ensure reasonable range
|
// ensure reasonable range
|
||||||
v = fract(v) + fract(v*1e4) + fract(v*1e-4);
|
v = fract(v) + fract(v*1e4) + fract(v*1e-4);
|
||||||
// seed
|
// seed
|
||||||
v += vec3(0.12345, 0.6789, 0.314159);
|
v += vec3(0.12345, 0.6789, 0.314159);
|
||||||
// more iterations => more random
|
// more iterations => more random
|
||||||
v = fract(v*dot(v, v)*123.456);
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
v = fract(v*dot(v, v)*123.456);
|
v = fract(v*dot(v, v)*123.456);
|
||||||
v = fract(v*dot(v, v)*123.456);
|
v = fract(v*dot(v, v)*123.456);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void fetch_pixel (inout vec3 c, inout vec3 b, vec2 coord, vec2 bcoord)
|
||||||
{
|
{
|
||||||
|
float stepx = OutputSize.z;
|
||||||
|
float stepy = OutputSize.w;
|
||||||
|
|
||||||
vec3 color = COMPAT_TEXTURE(Source, vTexCoord).rgb;
|
float ds = global.decons;
|
||||||
vec3 result = color;
|
|
||||||
|
|
||||||
if ((abs(params.deconrr) + abs(params.deconrg) + abs(params.deconrb) + abs(params.deconrry) + abs(params.deconrgy) + abs(params.deconrby)) > 0.20)
|
vec2 dx = vec2(stepx, 0.0);
|
||||||
|
vec2 dy = vec2(0.0, stepy);
|
||||||
|
|
||||||
|
float posx = 2.0*coord.x - 1.0;
|
||||||
|
float posy = 2.0*coord.y - 1.0;
|
||||||
|
|
||||||
|
if (global.dctypex > 0.025)
|
||||||
{
|
{
|
||||||
float step = 1.0;
|
posx = sign(posx)*pow(abs(posx), 1.05-global.dctypex);
|
||||||
float dstep = step;
|
|
||||||
step*= (TATE < 0.5) ? (params.OutputSize.z) : (params.OutputSize.w);
|
|
||||||
float stepy = (TATE < 0.5) ? (params.OutputSize.w) : (params.OutputSize.z);
|
|
||||||
float stepx = (TATE < 0.5) ? (params.OutputSize.z) : (params.OutputSize.w);
|
|
||||||
|
|
||||||
vec2 sx = mix(vec2(stepx, 0.0), vec2(0.0, stepx), TATE);
|
|
||||||
|
|
||||||
float ds = decons;
|
|
||||||
|
|
||||||
vec2 dx = (TATE < 0.5) ? vec2(step, 0.0) : vec2(0.0, step);
|
|
||||||
vec2 dy = (TATE > 0.5) ? vec2(stepy, 0.0) : vec2(0.0, stepy);
|
|
||||||
|
|
||||||
float posx = 2.0*vTexCoord.x - 1.0;
|
|
||||||
float posy = 2.0*vTexCoord.y - 1.0;
|
|
||||||
|
|
||||||
if (params.dctypex > 0.025)
|
|
||||||
{
|
|
||||||
posx = sign(posx)*pow(abs(posx), 1.05-params.dctypex);
|
|
||||||
dx = posx * dx;
|
dx = posx * dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.dctypey > 0.025)
|
if (global.dctypey > 0.025)
|
||||||
{
|
{
|
||||||
|
|
||||||
posy = sign(posy)*pow(abs(posy), 1.05-params.dctypey);
|
posy = sign(posy)*pow(abs(posy), 1.05-global.dctypey);
|
||||||
dy = posy * dy;
|
dy = posy * dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.dctypex > 0.025 || params.dctypey > 0.025) ds *= sqrt(posx*posx*sign(params.dctypex) + posy*posy*sign(params.dctypey));
|
// if (global.dctypex > 0.025 || global.dctypey > 0.025) ds *= sqrt(posx*posx*sign(global.dctypex) + posy*posy*sign(global.dctypey));
|
||||||
|
|
||||||
vec2 rc = params.deconrr * dx + params.deconrry*dy;
|
vec2 rc = global.deconrr * dx + global.deconrry*dy;
|
||||||
vec2 gc = params.deconrg * dx + params.deconrgy*dy;
|
vec2 gc = global.deconrg * dx + global.deconrgy*dy;
|
||||||
vec2 bc = params.deconrb * dx + params.deconrby*dy;
|
vec2 bc = global.deconrb * dx + global.deconrby*dy;
|
||||||
|
|
||||||
dx = (dx+dy) * params.deconsmooth;
|
float r1 = COMPAT_TEXTURE(Source, coord + rc).r;
|
||||||
|
float g1 = COMPAT_TEXTURE(Source, coord + gc).g;
|
||||||
|
float b1 = COMPAT_TEXTURE(Source, coord + bc).b;
|
||||||
|
|
||||||
float r1 = COMPAT_TEXTURE(Source, vTexCoord + rc ).r;
|
vec3 d = vec3(r1, g1, b1);
|
||||||
float g1 = COMPAT_TEXTURE(Source, vTexCoord + gc ).g;
|
c = clamp(mix(c, d, ds), 0.0, 1.0);
|
||||||
float b1 = COMPAT_TEXTURE(Source, vTexCoord + bc ).b;
|
|
||||||
|
|
||||||
float r2 = COMPAT_TEXTURE(Source, vTexCoord + rc -dx).r;
|
r1 = COMPAT_TEXTURE(BloomPass, bcoord + rc).r;
|
||||||
float g2 = COMPAT_TEXTURE(Source, vTexCoord + gc -dx).g;
|
g1 = COMPAT_TEXTURE(BloomPass, bcoord + gc).g;
|
||||||
float b2 = COMPAT_TEXTURE(Source, vTexCoord + bc -dx).b;
|
b1 = COMPAT_TEXTURE(BloomPass, bcoord + bc).b;
|
||||||
|
|
||||||
float r3 = COMPAT_TEXTURE(Source, vTexCoord + rc +dx).r;
|
d = vec3(r1, g1, b1);
|
||||||
float g3 = COMPAT_TEXTURE(Source, vTexCoord + gc +dx).g;
|
b = clamp(mix(b, d, ds), 0.0, 1.0);
|
||||||
float b3 = COMPAT_TEXTURE(Source, vTexCoord + bc +dx).b;
|
|
||||||
|
|
||||||
vec3 result1 = vec3(r1,g1,b1);
|
|
||||||
vec3 result2 = vec3(r2,g2,b2);
|
|
||||||
vec3 result3 = vec3(r3,g3,b3);
|
|
||||||
result = (result1+result2+result3)/3.0;
|
|
||||||
|
|
||||||
vec3 dcolor = max(max(COMPAT_TEXTURE(Source, vTexCoord + sx).rgb, COMPAT_TEXTURE(Source, vTexCoord - sx).rgb), color);
|
|
||||||
|
|
||||||
float mc = max(max(dcolor.r, dcolor.g), dcolor.b);
|
|
||||||
if (decons < 0.0) mc = 0.9;
|
|
||||||
|
|
||||||
result = clamp(mix(color, sqrt(mix(result*result, color*result, sqrt(mc))), abs(ds)), min(result,color), max(result, color));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float rc = 0.6*sqrt(max(max(result.r, result.g), result.b))+0.4;
|
|
||||||
|
|
||||||
if (abs(addnoised) > 0.01) result = mix(result, noise(vec3(floor(params.OutputSize.xy * vTexCoord / noiseresd), float(params.FrameCount))), 0.25*abs(addnoised) * rc);
|
void main()
|
||||||
|
{
|
||||||
|
vec4 SourceSize = global.OriginalSize * vec4(prescalex, 1.0, 1.0/prescalex, 1.0);
|
||||||
|
|
||||||
float corner = COMPAT_TEXTURE(Source, vTexCoord).a;
|
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.5,0.5)).a;
|
||||||
|
|
||||||
FragColor = vec4(result*corner, 1.0);
|
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
||||||
|
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
||||||
|
bool interb = (intera < 0.5);
|
||||||
|
bool notate = (TATE < 0.5);
|
||||||
|
|
||||||
|
// Calculating texel coordinates
|
||||||
|
|
||||||
|
vec2 texcoord = TEX0.xy;
|
||||||
|
if (IOS > 0.0 && !interb){
|
||||||
|
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
||||||
|
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
||||||
|
vec2 diff = ofactor/intfactor;
|
||||||
|
float scan = mix(diff.y, diff.x, TATE);
|
||||||
|
texcoord = Overscan(texcoord, scan, scan);
|
||||||
|
if (IOS == 1.0 || IOS == 3.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
||||||
|
texcoord = Overscan(texcoord, factor, factor);
|
||||||
|
|
||||||
|
texcoord = Overscan(texcoord, (global.OriginalSize.x - overscanX)/global.OriginalSize.x, (global.OriginalSize.y - overscanY)/global.OriginalSize.y);
|
||||||
|
|
||||||
|
vec2 pos1 = TEX0.xy;
|
||||||
|
vec2 pos = Warp(texcoord);
|
||||||
|
vec2 pos0 = Warp(TEX0.xy);
|
||||||
|
vec3 color0 = COMPAT_TEXTURE(Source,pos1).rgb;
|
||||||
|
float c0 = max(max(color0.r, color0.g),color0.b);
|
||||||
|
|
||||||
|
// color and bloom fetching
|
||||||
|
vec3 color = COMPAT_TEXTURE(Source,pos1).rgb;
|
||||||
|
vec3 Bloom = COMPAT_TEXTURE(BloomPass, pos).rgb;
|
||||||
|
|
||||||
|
fetch_pixel(color, Bloom, pos1, pos); // deconvergence
|
||||||
|
|
||||||
|
float cm = max(max(color.r,color.g),color.b);
|
||||||
|
float mx1 = COMPAT_TEXTURE(Source, pos1 ).a;
|
||||||
|
float colmx = max(mx1, cm);
|
||||||
|
float w3 = min((c0 + 0.0005) / (pow(colmx, gamma_in/1.4) + 0.0005), 1.0);
|
||||||
|
|
||||||
|
vec2 dx = mix(vec2(0.001, 0.0), vec2(0.0, 0.001), TATE);
|
||||||
|
float mx0 = COMPAT_TEXTURE(Source, pos1 - dx).a;
|
||||||
|
float mx2 = COMPAT_TEXTURE(Source, pos1 + dx).a;
|
||||||
|
float mx = max(max(mx0,mx1),max(mx2,cm));
|
||||||
|
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
|
||||||
|
// Apply Mask
|
||||||
|
|
||||||
|
vec3 orig1 = color;
|
||||||
|
vec3 cmask = one;
|
||||||
|
|
||||||
|
vec2 maskcoord = gl_FragCoord.yx * 1.000001;
|
||||||
|
if (notate) maskcoord = maskcoord.yx;
|
||||||
|
|
||||||
|
float smask = SlotMask(maskcoord, mx);
|
||||||
|
cmask*= Mask(maskcoord, mx);
|
||||||
|
|
||||||
|
if (mask_layout > 0.5) cmask = cmask.rbg;
|
||||||
|
|
||||||
|
vec3 cmask1 = cmask;
|
||||||
|
float smask1 = smask;
|
||||||
|
|
||||||
|
if (mask_bloom > 0.025)
|
||||||
|
{
|
||||||
|
float maxb = max(max(Bloom.r,Bloom.g),Bloom.b);
|
||||||
|
maxb = pow(sqrt(maxb*mix(maxb, colmx, 0.75)),0.275);
|
||||||
|
vec3 mBloom = 0.5*(1.5*Bloom+0.5*maxb) * mix(1.0, 2.0-colmx, (bloom_dist + 0.5));
|
||||||
|
float maskmx = 1.0; if (shadowMask > 0.5 || shadowMask < 4.5) maskmx = maskLight; else if (shadowMask > 6.5 && shadowMask < 10.5) maskmx = 1.0; else maskmx = max(max(cmask.r,cmask.g),cmask.b);
|
||||||
|
cmask = min(cmask + maxb*mBloom*mask_bloom, maskmx);
|
||||||
|
smask = min(smask + 0.9*maxb*max(max(mBloom.r,mBloom.g),mBloom.b)*mask_bloom, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
color = pow(color, vec3(mask_gamma/gamma_in));
|
||||||
|
color = color*cmask;
|
||||||
|
color = min(color,1.0);
|
||||||
|
color = color*smask;
|
||||||
|
color = pow(color, vec3(gamma_in/mask_gamma));
|
||||||
|
|
||||||
|
cmask = min(cmask*smask, 1.0);
|
||||||
|
cmask1 = min(cmask1*smask1, 1.0);
|
||||||
|
|
||||||
|
float bb = mix(brightboost, brightboost1, colmx);
|
||||||
|
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
||||||
|
color*=bb;
|
||||||
|
|
||||||
|
vec3 Glow = COMPAT_TEXTURE(GlowPass, pos).rgb;
|
||||||
|
vec3 Ref = COMPAT_TEXTURE(LinearizePass, pos).rgb;
|
||||||
|
float maxb = COMPAT_TEXTURE(BloomPass, pos).a;
|
||||||
|
float vig = COMPAT_TEXTURE(PrePass, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a;
|
||||||
|
|
||||||
|
vec3 Bloom1 = Bloom;
|
||||||
|
|
||||||
|
if (bloom < -0.01) Bloom1 = plant(Bloom, maxb);
|
||||||
|
|
||||||
|
Bloom1 = min(Bloom1*(orig1+color), max(0.5*(colmx + orig1 - color),0.001*Bloom1));
|
||||||
|
Bloom1 = 0.5*(Bloom1 + mix(Bloom1, mix(colmx*orig1, Bloom1, 0.5), 1.0-color));
|
||||||
|
|
||||||
|
Bloom1 = Bloom1 * mix(1.0, 2.0-colmx, bloom_dist);
|
||||||
|
|
||||||
|
color = color + abs(bloom) * Bloom1;
|
||||||
|
|
||||||
|
color = min(color, mix(one, cmask1, mclip));
|
||||||
|
|
||||||
|
if (!interb) color = declip(color, mix(1.0, w3, 0.6)); else w3 = 1.0;
|
||||||
|
|
||||||
|
if (halation > 0.01) {
|
||||||
|
Bloom = mix(0.5*(Bloom + Bloom*Bloom), 0.75*Bloom*Bloom, colmx);
|
||||||
|
color = color + 2.0*max((2.0*mix(maxb*maxb, maxb, colmx)-0.5*max(max(Ref.r,Ref.g),Ref.b)),0.25)*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.6)*Bloom*halation; }
|
||||||
|
|
||||||
|
|
||||||
|
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
||||||
|
if (glow >= 0.0) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + (-glow)*cmask*Glow; }
|
||||||
|
|
||||||
|
color = min(color, 1.0);
|
||||||
|
|
||||||
|
color = pow(color, vec3(1.0/gamma_out));
|
||||||
|
|
||||||
|
float rc = 0.6*sqrt(max(max(color.r, color.g), color.b))+0.4;
|
||||||
|
|
||||||
|
if (abs(global.addnoised) > 0.01)
|
||||||
|
{
|
||||||
|
vec3 noise0 = noise(vec3(floor(OutputSize.xy * vTexCoord / global.noiseresd), float(global.FrameCount)));
|
||||||
|
if (global.noisetype < 0.5) color = mix(color, noise0, 0.25*abs(global.addnoised) * rc);
|
||||||
|
else color = min(color * mix(1.0, 1.5*noise0.x, 0.5*abs(global.addnoised)), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir))*global.post_br*corner(pos0), 1.0);
|
||||||
}
|
}
|
|
@ -0,0 +1,929 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
float g_gamma_in;
|
||||||
|
float g_gamma_out;
|
||||||
|
float g_signal_type;
|
||||||
|
float g_crtgamut;
|
||||||
|
float g_space_out;
|
||||||
|
float g_hue_degrees;
|
||||||
|
float g_I_SHIFT;
|
||||||
|
float g_Q_SHIFT;
|
||||||
|
float g_I_MUL;
|
||||||
|
float g_Q_MUL;
|
||||||
|
float g_lum_fix;
|
||||||
|
float g_vignette;
|
||||||
|
float g_vstr;
|
||||||
|
float g_vpower;
|
||||||
|
float g_sat;
|
||||||
|
float g_vibr;
|
||||||
|
float g_lum;
|
||||||
|
float g_cntrst;
|
||||||
|
float g_mid;
|
||||||
|
float g_lift;
|
||||||
|
float blr;
|
||||||
|
float blg;
|
||||||
|
float blb;
|
||||||
|
float wlr;
|
||||||
|
float wlg;
|
||||||
|
float wlb;
|
||||||
|
float rg;
|
||||||
|
float rb;
|
||||||
|
float gr;
|
||||||
|
float gb;
|
||||||
|
float br;
|
||||||
|
float bg;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
float wp_temperature;
|
||||||
|
float g_satr;
|
||||||
|
float g_satg;
|
||||||
|
float g_satb;
|
||||||
|
float LUT_Size1;
|
||||||
|
float LUT1_toggle;
|
||||||
|
float LUT_Size2;
|
||||||
|
float LUT2_toggle;
|
||||||
|
float AS, asat;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Grade
|
||||||
|
> Ubershader grouping some monolithic color related shaders:
|
||||||
|
::color-mangler (hunterk), ntsc color tuning knobs (Doriphor), white_point (hunterk, Dogway), RA Reshade LUT.
|
||||||
|
> and the addition of:
|
||||||
|
::analogue color emulation, phosphor gamut, color space + TRC support, vibrance, HUE vs SAT, vignette (shared by Syh), black level, rolled gain and sigmoidal contrast.
|
||||||
|
|
||||||
|
Author: Dogway
|
||||||
|
License: Public domain
|
||||||
|
|
||||||
|
**Thanks to those that helped me out keep motivated by continuous feedback and bug reports:
|
||||||
|
**Syh, Nesguy, hunterk, and the libretro forum members.
|
||||||
|
|
||||||
|
|
||||||
|
######################################...PRESETS...#######################################
|
||||||
|
##########################################################################################
|
||||||
|
### ###
|
||||||
|
### PAL ###
|
||||||
|
### Phosphor: EBU (#3) (or an EBU T3213 based CRT phosphor gamut) ###
|
||||||
|
### WP: D65 (6504K) (in practice more like ~7500K) ###
|
||||||
|
### TRC: 2.8 SMPTE-C Gamma ###
|
||||||
|
### Saturation: -0.02 ###
|
||||||
|
### ###
|
||||||
|
### NTSC-U ###
|
||||||
|
### Phosphor: P22/SMPTE-C (#1 #-1)(or a SMPTE-C based CRT phosphor gamut) ###
|
||||||
|
### WP: D65 (6504K) (in practice more like ~7500K) ###
|
||||||
|
### TRC: 2.22 SMPTE-C Gamma (in practice more like 2.35-2.55) ###
|
||||||
|
### ###
|
||||||
|
### NTSC-J (Default) ###
|
||||||
|
### Phosphor: NTSC-J (#2) (or a NTSC-J based CRT phosphor gamut) ###
|
||||||
|
### WP: 9300K+27MPCD (8942K) (CCT from x:0.281 y:0.311) ###
|
||||||
|
### TRC: 2.22 SMPTE-C Gamma (in practice more like 2.35-2.55) ###
|
||||||
|
### ###
|
||||||
|
### *Despite the standard of 2.22, a more faithful approximation to CRT... ###
|
||||||
|
### ...is to use a gamma (SMPTE-C type) with a value of 2.35-2.55. ###
|
||||||
|
### ###
|
||||||
|
### ###
|
||||||
|
##########################################################################################
|
||||||
|
##########################################################################################
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma parameter AS " Afterglow Strength" 0.20 0.0 0.60 0.01
|
||||||
|
#define AS global.AS
|
||||||
|
#pragma parameter asat " Afterglow saturation" 0.33 0.0 1.0 0.01
|
||||||
|
#define asat global.asat
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter g_gamma_in "Game Embedded Gamma" 2.222 1.80 3.0 0.05
|
||||||
|
#pragma parameter g_gamma_out "CRT Electron Gun Gamma" 2.50 1.80 3.0 0.05
|
||||||
|
#pragma parameter g_signal_type "Signal Type (0:RGB 1:Composite)" 1.0 0.0 1.0 1.0
|
||||||
|
#pragma parameter g_crtgamut "Phosphor (1:NTSC-U 2:NTSC-J 3:PAL)" 2.0 -4.0 3.0 1.0
|
||||||
|
#pragma parameter g_space_out "Diplay Color Space (-1:709 0:sRGB 1:DCI 2:2020 3:Adobe)" 0.0 -1.0 3.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter g_hue_degrees "Hue" 0.0 -360.0 360.0 1.0
|
||||||
|
#pragma parameter g_I_SHIFT "I/U Shift" 0.0 -0.2 0.2 0.01
|
||||||
|
#pragma parameter g_Q_SHIFT "Q/V Shift" 0.0 -0.2 0.2 0.01
|
||||||
|
#pragma parameter g_I_MUL "I/U Multiplier" 1.0 0.0 2.0 0.01
|
||||||
|
#pragma parameter g_Q_MUL "Q/V Multiplier" 1.0 0.0 2.0 0.01
|
||||||
|
#pragma parameter g_lum_fix "Sega Luma Fix" 0.0 0.0 1.0 1.0
|
||||||
|
#pragma parameter g_vignette "Vignette Toggle" 1.0 0.0 1.0 1.0
|
||||||
|
#pragma parameter g_vstr "Vignette Strength" 40.0 0.0 50.0 1.0
|
||||||
|
#pragma parameter g_vpower "Vignette Power" 0.20 0.0 0.5 0.01
|
||||||
|
#pragma parameter g_lum "Brightness" 0.0 -0.5 1.0 0.01
|
||||||
|
#pragma parameter g_cntrst "Contrast" 0.0 -1.0 1.0 0.05
|
||||||
|
#pragma parameter g_mid "Contrast Pivot" 0.5 0.0 1.0 0.01
|
||||||
|
#pragma parameter wp_temperature "White Point" 6504.0 5004.0 12004.0 100.0
|
||||||
|
#pragma parameter g_sat "Saturation" 0.0 -1.0 2.0 0.01
|
||||||
|
#pragma parameter g_vibr "Dullness/Vibrance" 0.0 -1.0 1.0 0.05
|
||||||
|
#pragma parameter g_satr "Hue vs Sat Red" 0.0 -1.0 1.0 0.01
|
||||||
|
#pragma parameter g_satg "Hue vs Sat Green" 0.0 -1.0 1.0 0.01
|
||||||
|
#pragma parameter g_satb "Hue vs Sat Blue" 0.0 -1.0 1.0 0.01
|
||||||
|
#pragma parameter g_lift "Black Level" 0.0 -0.5 0.5 0.01
|
||||||
|
#pragma parameter blr "Black-Red Tint" 0.0 0.0 1.0 0.01
|
||||||
|
#pragma parameter blg "Black-Green Tint" 0.0 0.0 1.0 0.01
|
||||||
|
#pragma parameter blb "Black-Blue Tint" 0.0 0.0 1.0 0.01
|
||||||
|
#pragma parameter wlr "White-Red Tint" 1.0 0.0 2.0 0.01
|
||||||
|
#pragma parameter wlg "White-Green Tint" 1.0 0.0 2.0 0.01
|
||||||
|
#pragma parameter wlb "White-Blue Tint" 1.0 0.0 2.0 0.01
|
||||||
|
#pragma parameter rg "Red-Green Tint" 0.0 -1.0 1.0 0.005
|
||||||
|
#pragma parameter rb "Red-Blue Tint" 0.0 -1.0 1.0 0.005
|
||||||
|
#pragma parameter gr "Green-Red Tint" 0.0 -1.0 1.0 0.005
|
||||||
|
#pragma parameter gb "Green-Blue Tint" 0.0 -1.0 1.0 0.005
|
||||||
|
#pragma parameter br "Blue-Red Tint" 0.0 -1.0 1.0 0.005
|
||||||
|
#pragma parameter bg "Blue-Green Tint" 0.0 -1.0 1.0 0.005
|
||||||
|
#pragma parameter LUT_Size1 "LUT Size 1" 16.0 8.0 64.0 16.0
|
||||||
|
#pragma parameter LUT1_toggle "LUT 1 Toggle" 0.0 0.0 1.0 1.0
|
||||||
|
#pragma parameter LUT_Size2 "LUT Size 2" 64.0 0.0 64.0 16.0
|
||||||
|
#pragma parameter LUT2_toggle "LUT 2 Toggle" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#define M_PI 3.1415926535897932384626433832795
|
||||||
|
#define gamma_in params.g_gamma_in
|
||||||
|
#define gamma_out params.g_gamma_out
|
||||||
|
#define signal params.g_signal_type
|
||||||
|
#define crtgamut params.g_crtgamut
|
||||||
|
#define SPC params.g_space_out
|
||||||
|
#define hue_degrees params.g_hue_degrees
|
||||||
|
#define I_SHIFT params.g_I_SHIFT
|
||||||
|
#define Q_SHIFT params.g_Q_SHIFT
|
||||||
|
#define I_MUL params.g_I_MUL
|
||||||
|
#define Q_MUL params.g_Q_MUL
|
||||||
|
#define lum_fix params.g_lum_fix
|
||||||
|
#define vignette params.g_vignette
|
||||||
|
#define vstr params.g_vstr
|
||||||
|
#define vpower params.g_vpower
|
||||||
|
#define g_sat params.g_sat
|
||||||
|
#define vibr params.g_vibr
|
||||||
|
#define satr global.g_satr
|
||||||
|
#define satg global.g_satg
|
||||||
|
#define satb global.g_satb
|
||||||
|
#define lum params.g_lum
|
||||||
|
#define cntrst params.g_cntrst
|
||||||
|
#define mid params.g_mid
|
||||||
|
#define lift params.g_lift
|
||||||
|
#define blr params.blr
|
||||||
|
#define blg params.blg
|
||||||
|
#define blb params.blb
|
||||||
|
#define wlr params.wlr
|
||||||
|
#define wlg params.wlg
|
||||||
|
#define wlb params.wlb
|
||||||
|
#define rg params.rg
|
||||||
|
#define rb params.rb
|
||||||
|
#define gr params.gr
|
||||||
|
#define gb params.gb
|
||||||
|
#define br params.br
|
||||||
|
#define bg params.bg
|
||||||
|
|
||||||
|
#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 StockPass;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D AfterglowPass;
|
||||||
|
layout(set = 0, binding = 5) uniform sampler2D SamplerLUT1;
|
||||||
|
layout(set = 0, binding = 6) uniform sampler2D SamplerLUT2;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////// Color Space Transformations //////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vec3 XYZ_to_RGB(vec3 XYZ, float CSPC){
|
||||||
|
|
||||||
|
// to sRGB
|
||||||
|
const mat3x3 sRGB = mat3x3(
|
||||||
|
3.24081254005432130, -0.969243049621582000, 0.055638398975133896,
|
||||||
|
-1.53730857372283940, 1.875966310501098600, -0.204007431864738460,
|
||||||
|
-0.49858659505844116, 0.041555050760507584, 1.057129383087158200);
|
||||||
|
|
||||||
|
// to DCI-P3 -D65-
|
||||||
|
const mat3x3 DCIP3 = mat3x3(
|
||||||
|
2.49339652061462400, -0.82948720455169680, 0.035850685089826584,
|
||||||
|
-0.93134605884552000, 1.76266026496887200, -0.076182708144187930,
|
||||||
|
-0.40269458293914795, 0.023624641820788383, 0.957014024257659900);
|
||||||
|
|
||||||
|
// to Rec.2020
|
||||||
|
const mat3x3 rec2020 = mat3x3(
|
||||||
|
1.71660947799682620, -0.66668272018432620, 0.017642205581068993,
|
||||||
|
-0.35566213726997375, 1.61647748947143550, -0.042776308953762054,
|
||||||
|
-0.25336012244224550, 0.01576850563287735, 0.942228555679321300);
|
||||||
|
|
||||||
|
// to AdobeRGB
|
||||||
|
const mat3x3 Adobe = mat3x3(
|
||||||
|
2.0415899753570557, -0.96924000978469850, 0.013439999893307686,
|
||||||
|
-0.5650100111961365, 1.87597000598907470, -0.118359997868537900,
|
||||||
|
-0.3447299897670746, 0.04156000167131424, 1.015169978141784700);
|
||||||
|
|
||||||
|
return (CSPC == 3.0) ? Adobe * XYZ : (CSPC == 2.0) ? rec2020 * XYZ : (CSPC == 1.0) ? DCIP3 * XYZ : sRGB * XYZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 RGB_to_XYZ(vec3 RGB, float CSPC){
|
||||||
|
|
||||||
|
// from sRGB
|
||||||
|
const mat3x3 sRGB = mat3x3(
|
||||||
|
0.41241079568862915, 0.21264933049678802, 0.019331756979227066,
|
||||||
|
0.35758456587791443, 0.71516913175582890, 0.119194857776165010,
|
||||||
|
0.18045382201671600, 0.07218152284622192, 0.950390160083770800);
|
||||||
|
|
||||||
|
// from DCI-P3 -D65-
|
||||||
|
const mat3x3 DCIP3 = mat3x3(
|
||||||
|
0.48659050464630127, 0.22898375988006592, 0.00000000000000000,
|
||||||
|
0.26566821336746216, 0.69173991680145260, 0.04511347413063049,
|
||||||
|
0.19819043576717377, 0.07927616685628891, 1.04380297660827640);
|
||||||
|
|
||||||
|
// from Rec.2020
|
||||||
|
const mat3x3 rec2020 = mat3x3(
|
||||||
|
0.63697350025177000, 0.24840137362480164, 0.00000000000000000,
|
||||||
|
0.15294560790061950, 0.67799961566925050, 0.04253686964511871,
|
||||||
|
0.11785808950662613, 0.03913172334432602, 1.06084382534027100);
|
||||||
|
|
||||||
|
// from AdobeRGB
|
||||||
|
const mat3x3 Adobe = mat3x3(
|
||||||
|
0.57666999101638790, 0.2973400056362152, 0.02703000046312809,
|
||||||
|
0.18556000292301178, 0.6273599863052368, 0.07068999856710434,
|
||||||
|
0.18822999298572540, 0.0752900019288063, 0.9913399815559387);
|
||||||
|
|
||||||
|
return (CSPC == 3.0) ? Adobe * RGB : (CSPC == 2.0) ? rec2020 * RGB : (CSPC == 1.0) ? DCIP3 * RGB : sRGB * RGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 XYZtoYxy(vec3 XYZ){
|
||||||
|
|
||||||
|
float XYZrgb = XYZ.r+XYZ.g+XYZ.b;
|
||||||
|
float Yxyg = (XYZrgb <= 0.0) ? 0.3805 : XYZ.r / XYZrgb;
|
||||||
|
float Yxyb = (XYZrgb <= 0.0) ? 0.3769 : XYZ.g / XYZrgb;
|
||||||
|
return vec3(XYZ.g, Yxyg, Yxyb);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 YxytoXYZ(vec3 Yxy){
|
||||||
|
|
||||||
|
float Xs = Yxy.r * (Yxy.g/Yxy.b);
|
||||||
|
float Xsz = (Yxy.r <= 0.0) ? 0.0 : 1.0;
|
||||||
|
vec3 XYZ = vec3(Xsz,Xsz,Xsz) * vec3(Xs, Yxy.r, (Xs/Yxy.g)-Xs-Yxy.r);
|
||||||
|
return XYZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////// White Point Mapping /////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// PAL: D65 NTSC-U: D65 NTSC-J: CCT NTSC-J NTSC-FCC: C
|
||||||
|
// PAL: 6504K NTSC-U: 6504K NTSC-J: 8942K NTSC-FCC: 6780K
|
||||||
|
// 0.3127 0.3290 0.3127 0.3290 0.281 0.311 0.310 0.316
|
||||||
|
|
||||||
|
vec3 wp_adjust(float temperature, vec3 color){
|
||||||
|
|
||||||
|
float temp3 = pow(10.,3.) / temperature;
|
||||||
|
float temp6 = pow(10.,6.) / pow(temperature, 2.);
|
||||||
|
float temp9 = pow(10.,9.) / pow(temperature, 3.);
|
||||||
|
|
||||||
|
vec3 wp = vec3(1.);
|
||||||
|
|
||||||
|
wp.x = (temperature <= 7000.) ? 0.244063 + 0.09911 * temp3 + 2.9678 * temp6 - 4.6070 * temp9 : \
|
||||||
|
0.237040 + 0.24748 * temp3 + 1.9018 * temp6 - 2.0064 * temp9 ;
|
||||||
|
|
||||||
|
wp.y = -3.000 * pow(wp.x,2.) + 2.870 * wp.x - 0.275;
|
||||||
|
wp.z = 1. - wp.x - wp.y;
|
||||||
|
|
||||||
|
const mat3x3 CAT02 = mat3x3(
|
||||||
|
0.7328, 0.4296, -0.1624,
|
||||||
|
-0.70360, 1.6975, 0.0061,
|
||||||
|
0.003, -0.0136, 0.9834);
|
||||||
|
|
||||||
|
vec3 fw_trans = (vec3(wp.x/wp.y,1.,wp.z/wp.y) * CAT02) / (vec3(0.95045,1.,1.088917) * CAT02) ;
|
||||||
|
|
||||||
|
return color.xyz * fw_trans.xyz ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
// Monitor Curve Functions: https://github.com/ampas/aces-dev
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
float moncurve_f( float color, float gamma, float offs)
|
||||||
|
{
|
||||||
|
// Forward monitor curve
|
||||||
|
color = clamp(color, 0.0, 1.0);
|
||||||
|
float fs = (( gamma - 1.0) / offs) * pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
||||||
|
float xb = offs / ( gamma - 1.0);
|
||||||
|
|
||||||
|
color = ( color > xb) ? pow( ( color + offs) / ( 1.0 + offs), gamma) : color * fs;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 moncurve_f_f3( vec3 color, float gamma, float offs)
|
||||||
|
{
|
||||||
|
color.r = moncurve_f( color.r, gamma, offs);
|
||||||
|
color.g = moncurve_f( color.g, gamma, offs);
|
||||||
|
color.b = moncurve_f( color.b, gamma, offs);
|
||||||
|
return color.rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float moncurve_r( float color, float gamma, float offs)
|
||||||
|
{
|
||||||
|
// Reverse monitor curve
|
||||||
|
color = clamp(color, 0.0, 1.0);
|
||||||
|
float yb = pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
|
||||||
|
float rs = pow( ( gamma - 1.0) / offs, gamma - 1.0) * pow( ( 1.0 + offs) / gamma, gamma);
|
||||||
|
|
||||||
|
color = ( color > yb) ? ( 1.0 + offs) * pow( color, 1.0 / gamma) - offs : color * rs;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 moncurve_r_f3( vec3 color, float gamma, float offs)
|
||||||
|
{
|
||||||
|
color.r = moncurve_r( color.r, gamma, offs);
|
||||||
|
color.g = moncurve_r( color.g, gamma, offs);
|
||||||
|
color.b = moncurve_r( color.b, gamma, offs);
|
||||||
|
return color.rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------- Luma Functions ----------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Performs better in gamma encoded space
|
||||||
|
float contrast_sigmoid(float color, float cont, float pivot){
|
||||||
|
|
||||||
|
cont = pow(cont + 1., 3.);
|
||||||
|
|
||||||
|
float knee = 1. / (1. + exp(cont * pivot));
|
||||||
|
float shldr = 1. / (1. + exp(cont * (pivot - 1.)));
|
||||||
|
|
||||||
|
color = (1. / (1. + exp(cont * (pivot - color))) - knee) / (shldr - knee);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Performs better in gamma encoded space
|
||||||
|
float contrast_sigmoid_inv(float color, float cont, float pivot){
|
||||||
|
|
||||||
|
cont = pow(cont - 1., 3.);
|
||||||
|
|
||||||
|
float knee = 1. / (1. + exp (cont * pivot));
|
||||||
|
float shldr = 1. / (1. + exp (cont * (pivot - 1.)));
|
||||||
|
|
||||||
|
color = pivot - log(1. / (color * (shldr - knee) + knee) - 1.) / cont;
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float rolled_gain(float color, float gain){
|
||||||
|
|
||||||
|
float gx = abs(gain) + 0.001;
|
||||||
|
float anch = (gain > 0.0) ? 0.5 / (gx / 2.0) : 0.5 / gx;
|
||||||
|
color = (gain > 0.0) ? color * ((color - anch) / (1 - anch)) : color * ((1 - anch) / (color - anch)) * (1 - gain);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec4 rolled_gain_v4(vec4 color, float gain){
|
||||||
|
|
||||||
|
color.r = rolled_gain(color.r, gain);
|
||||||
|
color.g = rolled_gain(color.g, gain);
|
||||||
|
color.b = rolled_gain(color.b, gain);
|
||||||
|
|
||||||
|
return vec4(color.rgb, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float SatMask(float color_r, float color_g, float color_b)
|
||||||
|
{
|
||||||
|
float max_rgb = max(color_r, max(color_g, color_b));
|
||||||
|
float min_rgb = min(color_r, min(color_g, color_b));
|
||||||
|
float msk = clamp((max_rgb - min_rgb) / (max_rgb + min_rgb), 0.0, 1.0);
|
||||||
|
return msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
|
vec3 mixfix(vec3 a, vec3 b, float c)
|
||||||
|
{
|
||||||
|
return (a.z < 1.0) ? mix(a, b, c) : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec4 mixfix_v4(vec4 a, vec4 b, float c)
|
||||||
|
{
|
||||||
|
return (a.z < 1.0) ? mix(a, b, c) : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------- Range Expansion/Compression -------------------
|
||||||
|
|
||||||
|
|
||||||
|
// to Studio Swing/Broadcast Safe/SMPTE legal/Limited Range
|
||||||
|
vec3 PCtoTV(vec3 col, float luma_swing, float Umax, float Vmax, float max_swing, bool rgb_in)
|
||||||
|
{
|
||||||
|
col *= 255.;
|
||||||
|
Umax = (max_swing == 1.0) ? Umax * 224. : Umax * 239.;
|
||||||
|
Vmax = (max_swing == 1.0) ? Vmax * 224. : Vmax * 239.;
|
||||||
|
|
||||||
|
col.x = (luma_swing == 1.0) ? ((col.x * 219.) / 255.) + 16. : col.x;
|
||||||
|
col.y = (rgb_in == true) ? ((col.y * 219.) / 255.) + 16. : (((col.y - 128.) * (Umax * 2.)) / 255.) + Umax;
|
||||||
|
col.z = (rgb_in == true) ? ((col.z * 219.) / 255.) + 16. : (((col.z - 128.) * (Vmax * 2.)) / 255.) + Vmax;
|
||||||
|
return col.xyz / 255.;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// to Full Swing/Full Range
|
||||||
|
vec3 TVtoPC(vec3 col, float luma_swing, float Umax, float Vmax, float max_swing, bool rgb_in)
|
||||||
|
{
|
||||||
|
col *= 255.;
|
||||||
|
Umax = (max_swing == 1.0) ? Umax * 224. : Umax * 239.;
|
||||||
|
Vmax = (max_swing == 1.0) ? Vmax * 224. : Vmax * 239.;
|
||||||
|
|
||||||
|
float colx = (luma_swing == 1.0) ? ((col.x - 16.) / 219.) * 255. : col.x;
|
||||||
|
float coly = (rgb_in == true) ? ((col.y - 16.) / 219.) * 255. : (((col.y - Umax) / (Umax * 2.)) * 255.) + 128.;
|
||||||
|
float colz = (rgb_in == true) ? ((col.z - 16.) / 219.) * 255. : (((col.z - Vmax) / (Vmax * 2.)) * 255.) + 128.;
|
||||||
|
return vec3(colx,coly,colz) / 255.;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------- ITU-R BT.470/601 (M) (1953) --------------------
|
||||||
|
|
||||||
|
|
||||||
|
// FCC (Sanctioned) YIQ matrix
|
||||||
|
vec3 RGB_FCC(vec3 col)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
0.299996928307425, 0.590001575542717, 0.110001496149858,
|
||||||
|
0.599002392519453, -0.277301256521204, -0.321701135998249,
|
||||||
|
0.213001700342824, -0.525101205289350, 0.312099504946526);
|
||||||
|
|
||||||
|
return col.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FCC (Sanctioned) YIQ matrix (inverse)
|
||||||
|
vec3 FCC_RGB(vec3 col)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
1.0000000, 0.946882217090069, 0.623556581986143,
|
||||||
|
1.0000000, -0.274787646298978, -0.635691079187380,
|
||||||
|
1.0000000, -1.108545034642030, 1.709006928406470);
|
||||||
|
|
||||||
|
return col.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------- SMPTE RP 145 (C), 170M (1987) ------------------
|
||||||
|
|
||||||
|
|
||||||
|
vec3 RGB_YIQ(vec3 col)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
0.2990, 0.5870, 0.1140,
|
||||||
|
0.5959, -0.2746, -0.3213,
|
||||||
|
0.2115, -0.5227, 0.3112);
|
||||||
|
|
||||||
|
return col.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 YIQ_RGB(vec3 col)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
1.0000000, 0.956, 0.619,
|
||||||
|
1.0000000, -0.272, -0.647,
|
||||||
|
1.0000000, -1.106, 1.703);
|
||||||
|
|
||||||
|
return col.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------- ITU-R BT.470/601 (B/G) -----------------------
|
||||||
|
|
||||||
|
|
||||||
|
vec3 r601_YUV(vec3 RGB)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
0.299000, 0.587000, 0.114000,
|
||||||
|
-0.147407, -0.289391, 0.436798,
|
||||||
|
0.614777, -0.514799, -0.099978);
|
||||||
|
|
||||||
|
return RGB.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 YUV_r601(vec3 RGB)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
1.0000000, 0.00000000000000000, 1.14025080204010000,
|
||||||
|
1.0000000, -0.39393067359924316, -0.58080917596817020,
|
||||||
|
1.0000000, 2.02839756011962900, -0.00000029356581166);
|
||||||
|
|
||||||
|
return RGB.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom - not Standard
|
||||||
|
vec3 YUV_r709(vec3 YUV)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
1.0000000, 0.0000000000000000, 1.14025092124938960,
|
||||||
|
1.0000000, -0.2047683298587799, -0.33895039558410645,
|
||||||
|
1.0000001, 2.0283975601196290, 0.00000024094399364);
|
||||||
|
|
||||||
|
return YUV.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom - not Standard
|
||||||
|
vec3 r709_YUV(vec3 RGB)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
0.2126000, 0.715200, 0.0722000,
|
||||||
|
-0.1048118, -0.3525936, 0.4574054,
|
||||||
|
0.6905498, -0.6272304, -0.0633194);
|
||||||
|
|
||||||
|
return RGB.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------- SMPTE-240M Y’PbPr --------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Umax 0.886
|
||||||
|
// Vmax 0.700
|
||||||
|
// RGB to YPbPr -full to limited range- with Rec.601 primaries
|
||||||
|
vec3 r601_YCC(vec3 RGB)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
0.299, 0.587, 0.114,
|
||||||
|
-0.16873589164785553047, -0.33126410835214446953, 0.500,
|
||||||
|
0.500, -0.41868758915834522111, -0.08131241084165477889);
|
||||||
|
|
||||||
|
return RGB.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// YPbPr to RGB -limited to full range- with Rec.601 primaries
|
||||||
|
vec3 YCC_r601(vec3 YUV)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
1.0000000, 0.000, 1.402,
|
||||||
|
1.0000000, -0.34413628620102214651, -0.71413628620102214651,
|
||||||
|
1.0000000, 1.772, 0.000);
|
||||||
|
|
||||||
|
return YUV.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Umax 0.53890924768269023496443198965294
|
||||||
|
// Vmax 0.63500127000254000508001016002032
|
||||||
|
// RGB to YPbPr -full range in-gamut- with Rec.709 primaries
|
||||||
|
vec3 r709_YCC(vec3 RGB)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
0.2126, 0.7152, 0.0722,
|
||||||
|
-0.11457210605733994395, -0.38542789394266005605, 0.5000,
|
||||||
|
0.5000, -0.45415290830581661163, -0.04584709169418338837);
|
||||||
|
|
||||||
|
return RGB.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// YPbPr to RGB -full range in-gamut- with Rec.709 primaries
|
||||||
|
vec3 YCC_r709(vec3 YUV)
|
||||||
|
{
|
||||||
|
const mat3 conv_mat = mat3(
|
||||||
|
1.0000000, 0.00000000000000000000, 1.5748,
|
||||||
|
1.0000000, -0.18732427293064876957, -0.46812427293064876957,
|
||||||
|
1.0000000, 1.8556, 0.00000000000000000000);
|
||||||
|
|
||||||
|
return YUV.rgb * conv_mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------- IPT --------------------------
|
||||||
|
|
||||||
|
|
||||||
|
const mat3 LMS =
|
||||||
|
mat3(
|
||||||
|
0.4002, 0.7076, -0.0808,
|
||||||
|
-0.2263, 1.1653, 0.0457,
|
||||||
|
0.0, 0.0, 0.9182);
|
||||||
|
|
||||||
|
const mat3 IPT =
|
||||||
|
mat3(
|
||||||
|
0.4000, 0.4000, 0.2000,
|
||||||
|
4.4550, -4.8510, 0.3960,
|
||||||
|
0.8056, 0.3572, -1.1628);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
|
||||||
|
|
||||||
|
|
||||||
|
// ITU-R BT.470/601 (M) (proof of concept, actually never used)
|
||||||
|
// SMPTE 170M-1999
|
||||||
|
// NTSC-FCC 1953 Standard Phosphor (use with temperature C: 6780K)
|
||||||
|
const mat3 NTSC_FCC_transform =
|
||||||
|
mat3(
|
||||||
|
0.60699284076690670, 0.2989666163921356, 0.00000000000000000,
|
||||||
|
0.17344850301742554, 0.5864211320877075, 0.06607561558485031,
|
||||||
|
0.20057128369808197, 0.1146121546626091, 1.11746847629547120);
|
||||||
|
|
||||||
|
// ITU-R BT.470/601 (M)
|
||||||
|
// Conrac 7211N19 CRT Phosphor
|
||||||
|
const mat3 Conrac_transform =
|
||||||
|
mat3(
|
||||||
|
0.55842006206512450, 0.28580552339553833, 0.03517606481909752,
|
||||||
|
0.20613566040992737, 0.63714659214019780, 0.09369802474975586,
|
||||||
|
0.18589359521865845, 0.07704800367355347, 0.96004259586334230);
|
||||||
|
|
||||||
|
// NTSC-J (use with D93 white point)
|
||||||
|
// Sony Trinitron KV-20M20
|
||||||
|
const mat3 Sony20_20_transform =
|
||||||
|
mat3(
|
||||||
|
0.33989441394805910, 0.18490256369113922, 0.019034087657928467,
|
||||||
|
0.33497872948646545, 0.71182984113693240, 0.149544075131416320,
|
||||||
|
0.22866378724575043, 0.10326752066612244, 1.143318891525268600);
|
||||||
|
|
||||||
|
// SMPTE-C - Measured Average Phosphor (1979-1994)
|
||||||
|
const mat3 P22_transform =
|
||||||
|
mat3(
|
||||||
|
0.4665636420249939, 0.25661000609397890, 0.005832045804709196,
|
||||||
|
0.3039233088493347, 0.66820019483566280, 0.105618737637996670,
|
||||||
|
0.1799621731042862, 0.07518967241048813, 0.977465748786926300);
|
||||||
|
|
||||||
|
// SMPTE RP 145-1994 (SMPTE-C), 170M-1999
|
||||||
|
// SMPTE-C - Standard Phosphor (Rec.601 NTSC)
|
||||||
|
const mat3 SMPTE_transform =
|
||||||
|
mat3(
|
||||||
|
0.39354196190834045, 0.21238772571086884, 0.01874009333550930,
|
||||||
|
0.36525884270668030, 0.70106136798858640, 0.11193416267633438,
|
||||||
|
0.19164848327636720, 0.08655092865228653, 0.95824241638183590);
|
||||||
|
|
||||||
|
// SMPTE RP 145-1994 (SMPTE-C), 170M-1999
|
||||||
|
// NTSC-J - Standard Phosphor (https://web.archive.org/web/20130413104152/http://arib.or.jp/english/html/overview/doc/4-TR-B09v1_0.pdf)
|
||||||
|
const mat3 NTSC_J_transform =
|
||||||
|
mat3(
|
||||||
|
0.39603787660598755, 0.22429330646991730, 0.02050681784749031,
|
||||||
|
0.31201449036598206, 0.67417418956756590, 0.12814880907535553,
|
||||||
|
0.24496731162071228, 0.10153251141309738, 1.26512730121612550);
|
||||||
|
|
||||||
|
// ITU-R BT.470/601 (B/G)
|
||||||
|
// EBU Tech.3213-E PAL - Standard Phosphor for Studio Monitors
|
||||||
|
const mat3 EBU_transform =
|
||||||
|
mat3(
|
||||||
|
0.43194326758384705, 0.22272075712680817, 0.020247340202331543,
|
||||||
|
0.34123489260673523, 0.70600330829620360, 0.129433929920196530,
|
||||||
|
0.17818950116634370, 0.07127580046653748, 0.938464701175689700);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
|
||||||
|
vec4 imgColor = texture(StockPass, vTexCoord.xy);
|
||||||
|
vec4 aftglow = texture(AfterglowPass, vTexCoord.xy);
|
||||||
|
|
||||||
|
float w = 1.0-aftglow.w;
|
||||||
|
|
||||||
|
float l = length(aftglow.rgb);
|
||||||
|
aftglow.rgb = AS*w*normalize(pow(aftglow.rgb + 0.01, vec3(asat)))*l;
|
||||||
|
|
||||||
|
|
||||||
|
// Retro Sega Systems: Genesis, 32x, CD and Saturn 2D had color palettes designed in TV levels to save on transformations.
|
||||||
|
float lum_exp = (lum_fix == 1.0) ? (255./239.) : 1.;
|
||||||
|
|
||||||
|
// vec3 src = texture(Source, vTexCoord.xy).rgb * lum_exp;
|
||||||
|
vec3 src = imgColor.rgb * lum_exp;
|
||||||
|
|
||||||
|
// Assumes framebuffer in Rec.601 with baked gamma
|
||||||
|
// make a YUV * NTSC Phosphor option too and a FCC * NTSC phosphor
|
||||||
|
vec3 col = (crtgamut == 3.0) ? r601_YUV(src) : \
|
||||||
|
(crtgamut == 2.0) ? RGB_YIQ(src) : \
|
||||||
|
(crtgamut == -3.0) ? RGB_FCC(src) : \
|
||||||
|
(crtgamut == -4.0) ? RGB_FCC(src) : \
|
||||||
|
RGB_YIQ(src) ;
|
||||||
|
|
||||||
|
|
||||||
|
// Clipping Logic / Gamut Limiting
|
||||||
|
vec2 UVmax = (crtgamut == 3.0) ? vec2(0.436798, 0.614777) : \
|
||||||
|
(crtgamut == -4.0) ? vec2(0.599002392519453, 0.52510120528935) : \
|
||||||
|
(crtgamut == -3.0) ? vec2(0.599002392519453, 0.52510120528935) : \
|
||||||
|
vec2(0.5959, 0.5227) ;
|
||||||
|
|
||||||
|
col = clamp(col.xyz, vec3(0.0, -UVmax.x, -UVmax.y), vec3(1.0, UVmax.x, UVmax.y));
|
||||||
|
|
||||||
|
|
||||||
|
col = (crtgamut == 3.0) ? col : \
|
||||||
|
(crtgamut == 2.0) ? col : \
|
||||||
|
(crtgamut == -3.0) ? PCtoTV(col, 1.0, UVmax.x, UVmax.y, 1.0, false) : \
|
||||||
|
(crtgamut == -4.0) ? PCtoTV(col, 1.0, UVmax.x, UVmax.y, 1.0, false) : \
|
||||||
|
PCtoTV(col, 1.0, UVmax.x, UVmax.y, 1.0, false) ;
|
||||||
|
|
||||||
|
|
||||||
|
// YIQ/YUV Analogue Color Controls (HUE + Color Shift + Color Burst)
|
||||||
|
float hue_radians = hue_degrees * (M_PI / 180.0);
|
||||||
|
float hue = atan(col.z, col.y) + hue_radians;
|
||||||
|
float chroma = sqrt(col.z * col.z + col.y * col.y);
|
||||||
|
col = vec3(col.x, chroma * cos(hue), chroma * sin(hue));
|
||||||
|
|
||||||
|
col.y = (mod((col.y + 1.0) + I_SHIFT, 2.0) - 1.0) * I_MUL;
|
||||||
|
col.z = (mod((col.z + 1.0) + Q_SHIFT, 2.0) - 1.0) * Q_MUL;
|
||||||
|
|
||||||
|
|
||||||
|
// Back to RGB
|
||||||
|
col = (crtgamut == 3.0) ? col : \
|
||||||
|
(crtgamut == 2.0) ? col : \
|
||||||
|
(crtgamut == -3.0) ? TVtoPC(col, 1.0, UVmax.x, UVmax.y, 1.0, false) : \
|
||||||
|
(crtgamut == -4.0) ? TVtoPC(col, 1.0, UVmax.x, UVmax.y, 1.0, false) : \
|
||||||
|
TVtoPC(col, 1.0, UVmax.x, UVmax.y, 1.0, false) ;
|
||||||
|
|
||||||
|
col = (crtgamut == 3.0) ? YUV_r601(col) : \
|
||||||
|
(crtgamut == 2.0) ? YIQ_RGB(col) : \
|
||||||
|
(crtgamut == -3.0) ? FCC_RGB(col) : \
|
||||||
|
(crtgamut == -4.0) ? FCC_RGB(col) : \
|
||||||
|
YIQ_RGB(col) ;
|
||||||
|
|
||||||
|
// Gamut Limiting
|
||||||
|
col = r601_YCC(clamp(col, 0., 1.));
|
||||||
|
col = (signal == 0.0) ? src : YCC_r601(clamp(col, vec3(0.0, -.886,-.700), vec3(1.0, .886,.700)));
|
||||||
|
|
||||||
|
|
||||||
|
// Developer baked CRT gamma (2.20 - 2.25)
|
||||||
|
col = moncurve_f_f3(col, gamma_in, 0.099);
|
||||||
|
|
||||||
|
// CRT Phosphor Gamut
|
||||||
|
mat3 m_in;
|
||||||
|
|
||||||
|
if (crtgamut == -4.0) { m_in = NTSC_FCC_transform; } else
|
||||||
|
if (crtgamut == -3.0) { m_in = Conrac_transform; } else
|
||||||
|
if (crtgamut == -2.0) { m_in = Sony20_20_transform; } else
|
||||||
|
if (crtgamut == -1.0) { m_in = SMPTE_transform; } else
|
||||||
|
if (crtgamut == 1.0) { m_in = P22_transform; } else
|
||||||
|
if (crtgamut == 2.0) { m_in = NTSC_J_transform; } else
|
||||||
|
if (crtgamut == 3.0) { m_in = EBU_transform; }
|
||||||
|
|
||||||
|
vec3 gamut = m_in*col;
|
||||||
|
|
||||||
|
// White Point Mapping
|
||||||
|
vec3 wp = (crtgamut == -4.0) ? wp_adjust(global.wp_temperature - (6404. - 6504.), gamut) : \
|
||||||
|
(crtgamut == -3.0) ? wp_adjust(global.wp_temperature - (6504. - 6504.), gamut) : \
|
||||||
|
(crtgamut == -2.0) ? wp_adjust(global.wp_temperature - (7600. - 6504.), gamut) : \
|
||||||
|
(crtgamut == -1.0) ? wp_adjust(global.wp_temperature - (6504. - 6504.), gamut) : \
|
||||||
|
(crtgamut == 1.0) ? wp_adjust(global.wp_temperature - (6504. - 6504.), gamut) : \
|
||||||
|
(crtgamut == 2.0) ? wp_adjust(global.wp_temperature - (7400. - 6504.), gamut) : \
|
||||||
|
(crtgamut == 3.0) ? wp_adjust(global.wp_temperature - (6504. - 6504.), gamut) : \
|
||||||
|
wp_adjust(global.wp_temperature, gamut) ;
|
||||||
|
|
||||||
|
vec3 adj = clamp(XYZ_to_RGB(wp, SPC), 0., 1.);
|
||||||
|
|
||||||
|
|
||||||
|
// Guest Emulated CRT Electron Gun gamma (2.35 - 2.50) (phosphor gamma brings it up back to ~2.222)
|
||||||
|
adj = moncurve_r_f3(crtgamut == 0.0 ? col : adj, pow(gamma_in, 2.) / gamma_out, 0.099);
|
||||||
|
|
||||||
|
|
||||||
|
// Look LUT - (in SPC space)
|
||||||
|
float red = (adj.r * (global.LUT_Size1 - 1.0) + 0.4999) / (global.LUT_Size1 * global.LUT_Size1);
|
||||||
|
float green = (adj.g * (global.LUT_Size1 - 1.0) + 0.4999) / global.LUT_Size1;
|
||||||
|
float blue1 = (floor(adj.b * (global.LUT_Size1 - 1.0)) / global.LUT_Size1) + red;
|
||||||
|
float blue2 = (ceil(adj.b * (global.LUT_Size1 - 1.0)) / global.LUT_Size1) + red;
|
||||||
|
float mixer = clamp(max((adj.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0);
|
||||||
|
vec3 color1 = texture(SamplerLUT1, vec2(blue1, green)).rgb;
|
||||||
|
vec3 color2 = texture(SamplerLUT1, vec2(blue2, green)).rgb;
|
||||||
|
vec3 vcolor = (global.LUT1_toggle == 0.0) ? adj : mixfix(color1, color2, mixer);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// OETF - Opto-Electronic Transfer Function (Rec.709 does a Dim to Dark Surround adaptation)
|
||||||
|
vcolor = (SPC == 3.0) ? clamp(pow(vcolor, vec3(563./256.)), 0., 1.) : \
|
||||||
|
(SPC == 2.0) ? moncurve_f_f3(vcolor, 2.20 + 0.022222, 0.0993) : \
|
||||||
|
(SPC == 1.0) ? clamp(pow(vcolor, vec3(2.20 + 0.40)), 0., 1.) : \
|
||||||
|
(SPC == 0.0) ? moncurve_f_f3(vcolor, 2.20 + 0.20, 0.0550) : \
|
||||||
|
clamp(pow(pow(vcolor, vec3(1./1.019264)), vec3(2.20 + 0.20)), 0., 1.) ;
|
||||||
|
|
||||||
|
|
||||||
|
vcolor = RGB_to_XYZ(vcolor, SPC);
|
||||||
|
|
||||||
|
|
||||||
|
// Sigmoidal Contrast
|
||||||
|
vec3 Yxy = XYZtoYxy(vcolor);
|
||||||
|
float toGamma = clamp(moncurve_r(Yxy.r, 2.40, 0.055), 0., 1.);
|
||||||
|
toGamma = (Yxy.r > 0.5) ? contrast_sigmoid_inv(toGamma, 2.3, 0.5) : toGamma;
|
||||||
|
float sigmoid = (cntrst > 0.0) ? contrast_sigmoid(toGamma, cntrst, mid) : contrast_sigmoid_inv(toGamma, cntrst, mid);
|
||||||
|
vec3 contrast = vec3(moncurve_f(sigmoid, 2.40, 0.055), Yxy.g, Yxy.b);
|
||||||
|
vec3 XYZsrgb = clamp(XYZ_to_RGB(YxytoXYZ(contrast), SPC), 0., 1.);
|
||||||
|
contrast = (cntrst == 0.0) ? XYZ_to_RGB(vcolor, SPC) : XYZsrgb;
|
||||||
|
|
||||||
|
|
||||||
|
// Vignetting & Black Level
|
||||||
|
vec2 vpos = vTexCoord*(global.OriginalSize.xy/global.SourceSize.xy);
|
||||||
|
|
||||||
|
vpos *= 1.0 - vpos.xy;
|
||||||
|
float vig = vpos.x * vpos.y * vstr;
|
||||||
|
vig = min(pow(vig, vpower), 1.0);
|
||||||
|
contrast *= (vignette == 1.0) ? vig : 1.0;
|
||||||
|
|
||||||
|
contrast += (lift / 20.0) * (1.0 - contrast);
|
||||||
|
|
||||||
|
|
||||||
|
// RGB Related Transforms
|
||||||
|
vec4 screen = vec4(max(contrast, 0.0), 1.0);
|
||||||
|
float sat = g_sat + 1.0;
|
||||||
|
|
||||||
|
// r g b alpha ; alpha does nothing for our purposes
|
||||||
|
mat4 color = mat4(wlr, rg, rb, 0.0, //red tint
|
||||||
|
gr, wlg, gb, 0.0, //green tint
|
||||||
|
br, bg, wlb, 0.0, //blue tint
|
||||||
|
blr/20., blg/20., blb/20., 0.0); //black tint
|
||||||
|
|
||||||
|
|
||||||
|
vec3 coeff = (SPC == 3.0) ? vec3(0.29734000563621520, 0.62735998630523680, 0.07529000192880630) : \
|
||||||
|
(SPC == 2.0) ? vec3(0.24840137362480164, 0.67799961566925050, 0.03913172334432602) : \
|
||||||
|
(SPC == 1.0) ? vec3(0.22898375988006592, 0.69173991680145260, 0.07927616685628891) : \
|
||||||
|
vec3(0.21264933049678802, 0.71516913175582890, 0.07218152284622192) ;
|
||||||
|
|
||||||
|
|
||||||
|
mat3 adjust = mat3((1.0 - sat) * coeff.x + sat, (1.0 - sat) * coeff.x, (1.0 - sat) * coeff.x,
|
||||||
|
(1.0 - sat) * coeff.y, (1.0 - sat) * coeff.y + sat, (1.0 - sat) * coeff.y,
|
||||||
|
(1.0 - sat) * coeff.z, (1.0 - sat) * coeff.z, (1.0 - sat) * coeff.z + sat);
|
||||||
|
|
||||||
|
|
||||||
|
screen = clamp(rolled_gain_v4(screen, clamp(lum, -0.49, 0.99)), 0., 1.);
|
||||||
|
screen = color * screen;
|
||||||
|
|
||||||
|
// HUE vs SAT
|
||||||
|
vec3 src_h = RGB_to_XYZ(screen.rgb, SPC) * LMS;
|
||||||
|
src_h.x = src_h.x >= 0.0 ? pow(src_h.x, 0.43) : -pow(-src_h.x, 0.43);
|
||||||
|
src_h.y = src_h.y >= 0.0 ? pow(src_h.y, 0.43) : -pow(-src_h.y, 0.43);
|
||||||
|
src_h.z = src_h.z >= 0.0 ? pow(src_h.z, 0.43) : -pow(-src_h.z, 0.43);
|
||||||
|
|
||||||
|
src_h.xyz *= IPT;
|
||||||
|
|
||||||
|
float hue_at = atan(src_h.z, src_h.y);
|
||||||
|
chroma = sqrt(src_h.z * src_h.z + src_h.y * src_h.y);
|
||||||
|
|
||||||
|
float hue_radians_r = -40.0 * (M_PI / 180.0);
|
||||||
|
float hue_r = chroma * cos(hue_at + hue_radians_r) * 2.;
|
||||||
|
|
||||||
|
float hue_radians_g = 230.0 * (M_PI / 180.0);
|
||||||
|
float hue_g = chroma * cos(hue_at + hue_radians_g) * 2.;
|
||||||
|
|
||||||
|
float hue_radians_b = 100.0 * (M_PI / 180.0);
|
||||||
|
float hue_b = chroma * cos(hue_at + hue_radians_b) * 2.;
|
||||||
|
|
||||||
|
float msk = dot(clamp(vec3(hue_r, hue_g, hue_b), 0., 1.), vec3(satr, satg, satb)*(-1.));
|
||||||
|
src_h = mixfix(screen.rgb, vec3(dot(coeff, screen.rgb)), msk);
|
||||||
|
|
||||||
|
float sat_msk = (vibr < 0.0) ? 1.0 - abs(SatMask(src_h.x, src_h.y, src_h.z) - 1.0) * abs(vibr) : \
|
||||||
|
1.0 - (SatMask(src_h.x, src_h.y, src_h.z) * vibr) ;
|
||||||
|
|
||||||
|
src_h = mixfix(src_h, clamp(adjust * src_h, 0., 1.), clamp(sat_msk, 0., 1.));
|
||||||
|
|
||||||
|
|
||||||
|
// EOTF - Electro-Optical Transfer Function (Rec.709 does a Dim to Dark Surround adaptation)
|
||||||
|
vec3 TRC = (SPC == 3.0) ? clamp(pow(src_h, vec3(1./(563./256.))), 0., 1.) : \
|
||||||
|
(SPC == 2.0) ? moncurve_r_f3(src_h, 2.20 + 0.022222, 0.0993) : \
|
||||||
|
(SPC == 1.0) ? clamp(pow(src_h, vec3(1./(2.20 + 0.40))), 0., 1.) : \
|
||||||
|
(SPC == 0.0) ? moncurve_r_f3(src_h, 2.20 + 0.20, 0.0550) : \
|
||||||
|
clamp(pow(pow(src_h, vec3(1.019264)), vec3(1./(2.20 + 0.20))), 0., 1.) ;
|
||||||
|
|
||||||
|
|
||||||
|
// Technical LUT - (in SPC space)
|
||||||
|
float red_2 = (TRC.r * (global.LUT_Size2 - 1.0) + 0.4999) / (global.LUT_Size2 * global.LUT_Size2);
|
||||||
|
float green_2 = (TRC.g * (global.LUT_Size2 - 1.0) + 0.4999) / global.LUT_Size2;
|
||||||
|
float blue1_2 = (floor(TRC.b * (global.LUT_Size2 - 1.0)) / global.LUT_Size2) + red_2;
|
||||||
|
float blue2_2 = (ceil(TRC.b * (global.LUT_Size2 - 1.0)) / global.LUT_Size2) + red_2;
|
||||||
|
float mixer_2 = clamp(max((TRC.b - blue1_2) / (blue2_2 - blue1_2), 0.0), 0.0, 32.0);
|
||||||
|
vec3 color1_2 = texture(SamplerLUT2, vec2(blue1_2, green_2)).rgb;
|
||||||
|
vec3 color2_2 = texture(SamplerLUT2, vec2(blue2_2, green_2)).rgb;
|
||||||
|
vec3 LUT2_output = mixfix(color1_2, color2_2, mixer_2);
|
||||||
|
|
||||||
|
LUT2_output = (global.LUT2_toggle == 0.0) ? TRC : LUT2_output;
|
||||||
|
|
||||||
|
|
||||||
|
FragColor = vec4(LUT2_output + aftglow.rgb, 1.0);
|
||||||
|
}
|
|
@ -72,7 +72,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match
|
||||||
#define prescalex params.prescalex // prescale-x factor
|
#define prescalex params.prescalex // prescale-x factor
|
||||||
|
|
||||||
#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.40 0.0 1.0 0.05
|
#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.25 0.0 1.0 0.05
|
||||||
#define iscans params.iscans // interlace saturation
|
#define iscans params.iscans // interlace saturation
|
||||||
|
|
||||||
#pragma stage vertex
|
#pragma stage vertex
|
||||||
|
@ -83,13 +83,13 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord * 1.000001;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D PrePass;
|
layout(set = 0, binding = 2) uniform sampler2D NtscPass;
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
|
|
||||||
|
@ -109,15 +109,15 @@ vec3 fetch_pixel(vec2 coord)
|
||||||
vec2 d2 = dx - dy;
|
vec2 d2 = dx - dy;
|
||||||
|
|
||||||
float sum = 15.0;
|
float sum = 15.0;
|
||||||
vec3 result = 3.0*COMPAT_TEXTURE(PrePass, coord ).rgb +
|
vec3 result = 3.0*COMPAT_TEXTURE(NtscPass, coord ).rgb +
|
||||||
2.0*COMPAT_TEXTURE(PrePass, coord + dx).rgb +
|
2.0*COMPAT_TEXTURE(NtscPass, coord + dx).rgb +
|
||||||
2.0*COMPAT_TEXTURE(PrePass, coord - dx).rgb +
|
2.0*COMPAT_TEXTURE(NtscPass, coord - dx).rgb +
|
||||||
2.0*COMPAT_TEXTURE(PrePass, coord + dy).rgb +
|
2.0*COMPAT_TEXTURE(NtscPass, coord + dy).rgb +
|
||||||
2.0*COMPAT_TEXTURE(PrePass, coord - dy).rgb +
|
2.0*COMPAT_TEXTURE(NtscPass, coord - dy).rgb +
|
||||||
COMPAT_TEXTURE(PrePass, coord + d1).rgb +
|
COMPAT_TEXTURE(NtscPass, coord + d1).rgb +
|
||||||
COMPAT_TEXTURE(PrePass, coord - d1).rgb +
|
COMPAT_TEXTURE(NtscPass, coord - d1).rgb +
|
||||||
COMPAT_TEXTURE(PrePass, coord + d2).rgb +
|
COMPAT_TEXTURE(NtscPass, coord + d2).rgb +
|
||||||
COMPAT_TEXTURE(PrePass, coord - d2).rgb;
|
COMPAT_TEXTURE(NtscPass, coord - d2).rgb;
|
||||||
|
|
||||||
return result/sum;
|
return result/sum;
|
||||||
}
|
}
|
||||||
|
@ -125,8 +125,8 @@ vec3 fetch_pixel(vec2 coord)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 c1 = COMPAT_TEXTURE(PrePass, vTexCoord).rgb;
|
vec3 c1 = COMPAT_TEXTURE(NtscPass, vTexCoord).rgb;
|
||||||
vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + vec2(0.0, params.OriginalSize.w)).rgb;
|
vec3 c2 = COMPAT_TEXTURE(NtscPass, vTexCoord + vec2(0.0, params.OriginalSize.w)).rgb;
|
||||||
|
|
||||||
if ((downsample_levelx + downsample_levely) > 0.025)
|
if ((downsample_levelx + downsample_levely) > 0.025)
|
||||||
{
|
{
|
||||||
|
@ -152,7 +152,7 @@ void main()
|
||||||
|
|
||||||
if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5)
|
if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5)
|
||||||
{
|
{
|
||||||
intera = 0.5;
|
intera = 0.25;
|
||||||
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
||||||
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
||||||
float ii = abs(line_no-frame_no);
|
float ii = abs(line_no-frame_no);
|
||||||
|
@ -163,10 +163,9 @@ void main()
|
||||||
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
||||||
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
||||||
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
||||||
intera = 0.0;
|
|
||||||
}
|
}
|
||||||
if (interm == 4.0) c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b));
|
if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; }
|
||||||
if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b));}
|
if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; }
|
||||||
}
|
}
|
||||||
c = pow(c, vec3(gamma_in));
|
c = pow(c, vec3(gamma_in));
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match
|
||||||
#define prescalex params.prescalex // prescale-x factor
|
#define prescalex params.prescalex // prescale-x factor
|
||||||
|
|
||||||
#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.40 0.0 1.0 0.05
|
#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.25 0.0 1.0 0.05
|
||||||
#define iscans params.iscans // interlace saturation
|
#define iscans params.iscans // interlace saturation
|
||||||
|
|
||||||
#pragma stage vertex
|
#pragma stage vertex
|
||||||
|
@ -83,7 +83,7 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord * 1.000001;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
|
@ -152,7 +152,7 @@ void main()
|
||||||
|
|
||||||
if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5)
|
if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5)
|
||||||
{
|
{
|
||||||
intera = 0.5;
|
intera = 0.25;
|
||||||
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
||||||
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
||||||
float ii = abs(line_no-frame_no);
|
float ii = abs(line_no-frame_no);
|
||||||
|
@ -163,10 +163,9 @@ void main()
|
||||||
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
||||||
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
||||||
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
||||||
intera = 0.0;
|
|
||||||
}
|
}
|
||||||
if (interm == 4.0) c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b));
|
if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; }
|
||||||
if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b));}
|
if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; }
|
||||||
}
|
}
|
||||||
c = pow(c, vec3(gamma_in));
|
c = pow(c, vec3(gamma_in));
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 14 KiB |
153
crt/shaders/guest/advanced/ntsc/ntsc-pass1.slang
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
// NTSC-Adaptive
|
||||||
|
// 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;
|
||||||
|
} 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 2.5 0.01
|
||||||
|
#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
|
||||||
|
|
||||||
|
|
||||||
|
#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 = min(global.ntsc_scale, 1.0);
|
||||||
|
float OriginalSize = global.OriginalSize.x;
|
||||||
|
gl_Position = global.MVP * Position;
|
||||||
|
vTexCoord = TexCoord;
|
||||||
|
pix_no = TexCoord * global.SourceSize.xy * (res * 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);
|
||||||
|
|
||||||
|
CHROMA_MOD_FREQ = (phase < 2.5) ? (4.0 * PI / 15.0) : (PI / 3.0);
|
||||||
|
ARTIFACTING = (global.quality > -0.5) ? global.quality : global.cust_artifacting;
|
||||||
|
FRINGING = (global.quality > -0.5) ? global.quality : global.cust_fringing;
|
||||||
|
SATURATION = global.ntsc_sat;
|
||||||
|
BRIGHTNESS = global.ntsc_bright;
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
float res = global.ntsc_scale;
|
||||||
|
vec3 col = texture(Source, vTexCoord).rgb;
|
||||||
|
vec3 yiq = rgb2yiq(col);
|
||||||
|
float lum = yiq.x;
|
||||||
|
|
||||||
|
vec3 yiq2 = yiq;
|
||||||
|
vec3 yiqs = yiq;
|
||||||
|
vec3 yiqz = 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 = 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.
|
||||||
|
|
||||||
|
if (res > 1.025)
|
||||||
|
{
|
||||||
|
mod_phase2 = chroma_phase2 + pix_no.x * CHROMA_MOD_FREQ * res;
|
||||||
|
i_mod2 = cos(mod_phase2);
|
||||||
|
q_mod2 = sin(mod_phase2);
|
||||||
|
yiqs.yz *= vec2(i_mod2, q_mod2); // Modulate.
|
||||||
|
yiq2.x = dot(yiqs, mix_mat[0]); // Cross-talk.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 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.
|
||||||
|
|
||||||
|
if (res > 1.025)
|
||||||
|
{
|
||||||
|
mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ * res;
|
||||||
|
i_mod = cos(mod_phase);
|
||||||
|
q_mod = sin(mod_phase);
|
||||||
|
yiqz.yz *= vec2(i_mod, q_mod); // Modulate.
|
||||||
|
yiq.x = dot(yiqz, mix_mat[0]); // Cross-talk.
|
||||||
|
}
|
||||||
|
|
||||||
|
yiq = (MERGE < 0.5) ? yiq : 0.5*(yiq+yiq2);
|
||||||
|
|
||||||
|
FragColor = vec4(yiq, lum);
|
||||||
|
}
|
299
crt/shaders/guest/advanced/ntsc/ntsc-pass2.slang
Normal file
|
@ -0,0 +1,299 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
// NTSC-Adaptive
|
||||||
|
// based on Themaister's NTSC shader
|
||||||
|
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 OutputSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 SourceSize;
|
||||||
|
float ntsc_scale;
|
||||||
|
float ntsc_phase;
|
||||||
|
float auto_res;
|
||||||
|
float ntsc_ring;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
#pragma parameter ntsc_scale "NTSC Resolution Scaling" 1.0 0.20 2.5 0.01
|
||||||
|
#pragma parameter ntsc_phase "NTSC Phase: Auto | 2 phase | 3 phase" 1.0 1.0 3.0 1.0
|
||||||
|
#pragma parameter ntsc_ring "NTSC Anti-Ringing" 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;
|
||||||
|
|
||||||
|
vec3 fetch_offset(float offset, float one_x)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int TAPS_2_phase = 32;
|
||||||
|
const float luma_filter_2_phase[33] = float[33](
|
||||||
|
-0.000174844,
|
||||||
|
-0.000205844,
|
||||||
|
-0.000149453,
|
||||||
|
-0.000051693,
|
||||||
|
0.000000000,
|
||||||
|
-0.000066171,
|
||||||
|
-0.000245058,
|
||||||
|
-0.000432928,
|
||||||
|
-0.000472644,
|
||||||
|
-0.000252236,
|
||||||
|
0.000198929,
|
||||||
|
0.000687058,
|
||||||
|
0.000944112,
|
||||||
|
0.000803467,
|
||||||
|
0.000363199,
|
||||||
|
0.000013422,
|
||||||
|
0.000253402,
|
||||||
|
0.001339461,
|
||||||
|
0.002932972,
|
||||||
|
0.003983485,
|
||||||
|
0.003026683,
|
||||||
|
-0.001102056,
|
||||||
|
-0.008373026,
|
||||||
|
-0.016897700,
|
||||||
|
-0.022914480,
|
||||||
|
-0.021642347,
|
||||||
|
-0.008863273,
|
||||||
|
0.017271957,
|
||||||
|
0.054921920,
|
||||||
|
0.098342579,
|
||||||
|
0.139044281,
|
||||||
|
0.168055832,
|
||||||
|
0.178571429);
|
||||||
|
|
||||||
|
const float chroma_filter_2_phase[33] = float[33](
|
||||||
|
0.001384762,
|
||||||
|
0.001678312,
|
||||||
|
0.002021715,
|
||||||
|
0.002420562,
|
||||||
|
0.002880460,
|
||||||
|
0.003406879,
|
||||||
|
0.004004985,
|
||||||
|
0.004679445,
|
||||||
|
0.005434218,
|
||||||
|
0.006272332,
|
||||||
|
0.007195654,
|
||||||
|
0.008204665,
|
||||||
|
0.009298238,
|
||||||
|
0.010473450,
|
||||||
|
0.011725413,
|
||||||
|
0.013047155,
|
||||||
|
0.014429548,
|
||||||
|
0.015861306,
|
||||||
|
0.017329037,
|
||||||
|
0.018817382,
|
||||||
|
0.020309220,
|
||||||
|
0.021785952,
|
||||||
|
0.023227857,
|
||||||
|
0.024614500,
|
||||||
|
0.025925203,
|
||||||
|
0.027139546,
|
||||||
|
0.028237893,
|
||||||
|
0.029201910,
|
||||||
|
0.030015081,
|
||||||
|
0.030663170,
|
||||||
|
0.031134640,
|
||||||
|
0.031420995,
|
||||||
|
0.031517031);
|
||||||
|
|
||||||
|
const int TAPS_3_phase = 24;
|
||||||
|
const float luma_filter_3_phase[25] = float[25](
|
||||||
|
-0.000012020,
|
||||||
|
-0.000022146,
|
||||||
|
-0.000013155,
|
||||||
|
-0.000012020,
|
||||||
|
-0.000049979,
|
||||||
|
-0.000113940,
|
||||||
|
-0.000122150,
|
||||||
|
-0.000005612,
|
||||||
|
0.000170516,
|
||||||
|
0.000237199,
|
||||||
|
0.000169640,
|
||||||
|
0.000285688,
|
||||||
|
0.000984574,
|
||||||
|
0.002018683,
|
||||||
|
0.002002275,
|
||||||
|
-0.000909882,
|
||||||
|
-0.007049081,
|
||||||
|
-0.013222860,
|
||||||
|
-0.012606931,
|
||||||
|
0.002460860,
|
||||||
|
0.035868225,
|
||||||
|
0.084016453,
|
||||||
|
0.135563500,
|
||||||
|
0.175261268,
|
||||||
|
0.190176552);
|
||||||
|
|
||||||
|
const float chroma_filter_3_phase[25] = float[25](
|
||||||
|
-0.000118847,
|
||||||
|
-0.000271306,
|
||||||
|
-0.000502642,
|
||||||
|
-0.000930833,
|
||||||
|
-0.001451013,
|
||||||
|
-0.002064744,
|
||||||
|
-0.002700432,
|
||||||
|
-0.003241276,
|
||||||
|
-0.003524948,
|
||||||
|
-0.003350284,
|
||||||
|
-0.002491729,
|
||||||
|
-0.000721149,
|
||||||
|
0.002164659,
|
||||||
|
0.006313635,
|
||||||
|
0.011789103,
|
||||||
|
0.018545660,
|
||||||
|
0.026414396,
|
||||||
|
0.035100710,
|
||||||
|
0.044196567,
|
||||||
|
0.053207202,
|
||||||
|
0.061590275,
|
||||||
|
0.068803602,
|
||||||
|
0.074356193,
|
||||||
|
0.077856564,
|
||||||
|
0.079052396);
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float res = global.ntsc_scale;
|
||||||
|
float OriginalSize = global.OriginalSize.x;
|
||||||
|
float one_x = global.SourceSize.z / res;
|
||||||
|
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);
|
||||||
|
|
||||||
|
if(phase < 2.5)
|
||||||
|
{
|
||||||
|
vec3 sums = fetch_offset(0.0 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.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 - 32.0, one_x) + fetch_offset(32.0 - 14.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[14], chroma_filter_2_phase[14], chroma_filter_2_phase[14]);
|
||||||
|
sums = fetch_offset(15.0 - 32.0, one_x) + fetch_offset(32.0 - 15.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[15], chroma_filter_2_phase[15], chroma_filter_2_phase[15]);
|
||||||
|
sums = fetch_offset(16.0 - 32.0, one_x) + fetch_offset(32.0 - 16.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[16], chroma_filter_2_phase[16], chroma_filter_2_phase[16]);
|
||||||
|
sums = fetch_offset(17.0 - 32.0, one_x) + fetch_offset(32.0 - 17.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[17], chroma_filter_2_phase[17], chroma_filter_2_phase[17]);
|
||||||
|
sums = fetch_offset(18.0 - 32.0, one_x) + fetch_offset(32.0 - 18.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[18], chroma_filter_2_phase[18], chroma_filter_2_phase[18]);
|
||||||
|
sums = fetch_offset(19.0 - 32.0, one_x) + fetch_offset(32.0 - 19.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[19], chroma_filter_2_phase[19], chroma_filter_2_phase[19]);
|
||||||
|
sums = fetch_offset(20.0 - 32.0, one_x) + fetch_offset(32.0 - 20.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[20], chroma_filter_2_phase[20], chroma_filter_2_phase[20]);
|
||||||
|
sums = fetch_offset(21.0 - 32.0, one_x) + fetch_offset(32.0 - 21.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[21], chroma_filter_2_phase[21], chroma_filter_2_phase[21]);
|
||||||
|
sums = fetch_offset(22.0 - 32.0, one_x) + fetch_offset(32.0 - 22.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[22], chroma_filter_2_phase[22], chroma_filter_2_phase[22]);
|
||||||
|
sums = fetch_offset(23.0 - 32.0, one_x) + fetch_offset(32.0 - 23.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[23], chroma_filter_2_phase[23], chroma_filter_2_phase[23]);
|
||||||
|
sums = fetch_offset(24.0 - 32.0, one_x) + fetch_offset(32.0 - 24.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[24], chroma_filter_2_phase[24], chroma_filter_2_phase[24]);
|
||||||
|
sums = fetch_offset(25.0 - 32.0, one_x) + fetch_offset(32.0 - 25.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[25], chroma_filter_2_phase[25], chroma_filter_2_phase[25]);
|
||||||
|
sums = fetch_offset(26.0 - 32.0, one_x) + fetch_offset(32.0 - 26.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[26], chroma_filter_2_phase[26], chroma_filter_2_phase[26]);
|
||||||
|
sums = fetch_offset(27.0 - 32.0, one_x) + fetch_offset(32.0 - 27.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[27], chroma_filter_2_phase[27], chroma_filter_2_phase[27]);
|
||||||
|
sums = fetch_offset(28.0 - 32.0, one_x) + fetch_offset(32.0 - 28.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[28], chroma_filter_2_phase[28], chroma_filter_2_phase[28]);
|
||||||
|
sums = fetch_offset(29.0 - 32.0, one_x) + fetch_offset(32.0 - 29.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[29], chroma_filter_2_phase[29], chroma_filter_2_phase[29]);
|
||||||
|
sums = fetch_offset(30.0 - 32.0, one_x) + fetch_offset(32.0 - 30.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[30], chroma_filter_2_phase[30], chroma_filter_2_phase[30]);
|
||||||
|
sums = fetch_offset(31.0 - 32.0, one_x) + fetch_offset(32.0 - 31.0, one_x);
|
||||||
|
signal += sums * vec3(luma_filter_2_phase[31], chroma_filter_2_phase[31], chroma_filter_2_phase[31]);
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (global.ntsc_ring > 0.5)
|
||||||
|
{
|
||||||
|
vec2 dx = vec2(global.OriginalSize.z / min(res, 1.0), 0.0);
|
||||||
|
float a = texture(Source, vTexCoord - 1.5*dx).a;
|
||||||
|
float b = texture(Source, vTexCoord - 0.5*dx).a;
|
||||||
|
float c = texture(Source, vTexCoord + 1.5*dx).a;
|
||||||
|
float d = texture(Source, vTexCoord + 0.5*dx).a;
|
||||||
|
float e = texture(Source, vTexCoord ).a;
|
||||||
|
signal.x = clamp(signal.x, min(min(min(a,b),min(c,d)),e), max(max(max(a,b),max(c,d)),e));
|
||||||
|
}
|
||||||
|
|
||||||
|
signal.x = clamp(signal.x, -1.0, 1.0);
|
||||||
|
vec3 rgb = signal;
|
||||||
|
|
||||||
|
FragColor = vec4(rgb, 1.0);
|
||||||
|
}
|
122
crt/shaders/guest/advanced/ntsc/ntsc-pass3.slang
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
// NTSC-Adaptive
|
||||||
|
// based on Themaister's NTSC shader
|
||||||
|
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 OutputSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 SourceSize;
|
||||||
|
float auto_res;
|
||||||
|
float ntsc_sharp;
|
||||||
|
float ntsc_shape;
|
||||||
|
float blendMode;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
#pragma parameter ntsc_sharp "NTSC Sharpness (negative: Adaptive)" 0.0 -10.0 10.0 0.50
|
||||||
|
#pragma parameter ntsc_shape "NTSC Sharpness Shape" 0.75 0.5 1.0 0.05
|
||||||
|
#pragma parameter blendMode "NTSC Blend Mode (Main Mode Control)" 1.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.25 / 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 NPass1;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D PrePass0;
|
||||||
|
|
||||||
|
float fetch_offset(float offset, float one_x)
|
||||||
|
{
|
||||||
|
return texture(NPass1, vTexCoord + vec2((offset) * (one_x), 0.0)).x;
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
vec2 offsetx = vec2(0.5 * global.OriginalSize.z, 0.0);
|
||||||
|
vec2 texcoord = vTexCoord + vec2(0.25 * global.SourceSize.z, 0.0);
|
||||||
|
|
||||||
|
vec3 l1 = texture(Source, texcoord + offsetx).xyz;
|
||||||
|
vec3 l2 = texture(Source, texcoord - offsetx).xyz;
|
||||||
|
vec3 l3 = texture(Source, texcoord + 0.50*offsetx).xyz;
|
||||||
|
vec3 l4 = texture(Source, texcoord - 0.50*offsetx).xyz;
|
||||||
|
vec3 ref = texture(Source, texcoord).xyz;
|
||||||
|
|
||||||
|
float lum1 = texture(NPass1, vTexCoord).a;
|
||||||
|
float lum2 = max(ref.x, 0.0);
|
||||||
|
|
||||||
|
float dif = max(max(abs(l1.x-l2.x), abs(l1.y-l2.y)), max(abs(l1.z-l2.z), abs(l1.x*l1.x-l2.x*l2.x)));
|
||||||
|
float dff = max(max(abs(l3.x-l4.x), abs(l3.y-l4.y)), max(abs(l3.z-l4.z), abs(l3.x*l3.x-l4.x*l4.x)));
|
||||||
|
|
||||||
|
float lc = (1.0-smoothstep(0.10, 0.20, abs(lum2-lum1)))*pow(dff, 0.125);
|
||||||
|
|
||||||
|
float sweight = smoothstep(0.05-0.03*lc, 0.45 - 0.40*lc, dif);
|
||||||
|
|
||||||
|
vec3 signal = ref;
|
||||||
|
|
||||||
|
if (abs(global.ntsc_sharp) > -0.1)
|
||||||
|
{
|
||||||
|
float lummix = mix(lum2, lum1, 0.1*abs(global.ntsc_sharp));
|
||||||
|
float lm1 = mix(lum2*lum2, lum1*lum1, 0.1*abs(global.ntsc_sharp)); lm1 = sqrt(lm1);
|
||||||
|
float lm2 = mix(sqrt(lum2), sqrt(lum1), 0.1*abs(global.ntsc_sharp)); lm2 = lm2*lm2;
|
||||||
|
|
||||||
|
float k1 = abs(lummix - lm1) + 0.00001;
|
||||||
|
float k2 = abs(lummix - lm2) + 0.00001;
|
||||||
|
|
||||||
|
lummix = min((k2*lm1 + k1*lm2)/(k1+k2), 1.0);
|
||||||
|
|
||||||
|
signal.x = mix(lum2, lummix, smoothstep(0.25, 0.4, pow(dff, 0.125)));
|
||||||
|
signal.x = min(signal.x, max(global.ntsc_shape*signal.x, lum2));
|
||||||
|
}
|
||||||
|
else signal.x = clamp(signal.x, -1.0, 1.0);
|
||||||
|
|
||||||
|
vec3 rgb = signal;
|
||||||
|
if (global.ntsc_sharp < -0.1)
|
||||||
|
{
|
||||||
|
rgb.x = mix(ref.x, rgb.x, sweight);
|
||||||
|
}
|
||||||
|
|
||||||
|
rgb = clamp(yiq2rgb(rgb), 0.0, 1.0);
|
||||||
|
|
||||||
|
if (global.blendMode < 0.5)
|
||||||
|
{
|
||||||
|
vec3 orig = texture(PrePass0, vTexCoord).rgb;
|
||||||
|
rgb = normalize(rgb + 0.00001) * min(length(rgb), length(orig));
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor = vec4(rgb, 1.0);
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
CRT Advanced Afterglow, color altering
|
CRT Advanced Afterglow, color altering
|
||||||
|
|
||||||
Copyright (C) 2019-2021 guest(r) and Dr. Venom
|
Copyright (C) 2019-2022 guest(r) and Dr. Venom
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -39,12 +39,13 @@ layout(push_constant) uniform Push
|
||||||
float vigdef;
|
float vigdef;
|
||||||
float sega_fix;
|
float sega_fix;
|
||||||
float pre_bb;
|
float pre_bb;
|
||||||
|
float contr;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
#pragma parameter AS " Afterglow Strength" 0.20 0.0 0.60 0.01
|
#pragma parameter AS " Afterglow Strength" 0.20 0.0 0.60 0.01
|
||||||
#define AS params.AS
|
#define AS params.AS
|
||||||
|
|
||||||
#pragma parameter sat " Afterglow saturation" 0.20 0.0 1.0 0.01
|
#pragma parameter sat " Afterglow saturation" 0.50 0.0 1.0 0.01
|
||||||
#define sat params.sat
|
#define sat params.sat
|
||||||
|
|
||||||
#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
@ -56,7 +57,7 @@ layout(push_constant) uniform Push
|
||||||
#define CP params.CP
|
#define CP params.CP
|
||||||
#define CS params.CS
|
#define CS params.CS
|
||||||
|
|
||||||
#pragma parameter TNTC " LUT Colors: Trin. | invTrin. | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0
|
#pragma parameter TNTC " LUT Colors: Trin.1 | Trin.2 | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0
|
||||||
#define TNTC params.TNTC
|
#define TNTC params.TNTC
|
||||||
|
|
||||||
#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0
|
#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0
|
||||||
|
@ -72,13 +73,15 @@ layout(push_constant) uniform Push
|
||||||
|
|
||||||
#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01
|
#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter contr " Contrast Adjustment" 0.0 -1.0 1.0 0.05
|
||||||
|
|
||||||
#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0
|
#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter BP " Raise Black Level" 0.0 0.0 25.0 1.0
|
#pragma parameter BP " Raise Black Level" 0.0 -100.0 25.0 1.0
|
||||||
|
|
||||||
#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.025
|
#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.05
|
||||||
|
|
||||||
#pragma parameter vigdef " Vignette Definition" 7.0 0.4 15.0 0.2
|
#pragma parameter vigdef " Vignette Size" 1.0 0.5 3.0 0.10
|
||||||
|
|
||||||
#define WP params.WP
|
#define WP params.WP
|
||||||
#define wp_saturation params.wp_saturation
|
#define wp_saturation params.wp_saturation
|
||||||
|
@ -201,9 +204,9 @@ const mat3 D65_to_D55 = mat3 (
|
||||||
|
|
||||||
|
|
||||||
const mat3 D65_to_D93 = mat3 (
|
const mat3 D65_to_D93 = mat3 (
|
||||||
0.3683017655, 0.1899055978, 0.0172641453,
|
0.3412754080, 0.1759701322, 0.0159972847,
|
||||||
0.3555467892, 0.7110935785, 0.1185155964,
|
0.3646170520, 0.7292341040, 0.1215390173,
|
||||||
0.2475020592, 0.0990008237, 1.3035108450);
|
0.2369894093, 0.0947957637, 1.2481442225);
|
||||||
|
|
||||||
|
|
||||||
vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
||||||
|
@ -215,18 +218,28 @@ vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
||||||
return mix(lutcolor, ref, LUTBR);
|
return mix(lutcolor, ref, LUTBR);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ctransform (vec2 inputc)
|
|
||||||
{
|
float vignette(vec2 pos) {
|
||||||
return vec2( inputc.x * sqrt(1.0 - 0.5*inputc.y*inputc.y), inputc.y * sqrt(1.0 - 0.5*inputc.x*inputc.x));
|
vec2 b = vec2(params.vigdef, params.vigdef) * vec2(1.0, params.OriginalSize.x/params.OriginalSize.y) * 0.125;
|
||||||
|
pos = clamp(pos, 0.0, 1.0);
|
||||||
|
pos = abs(2.0*(pos - 0.5));
|
||||||
|
vec2 res = mix(0.0.xx, 1.0.xx, smoothstep(1.0.xx, 1.0.xx-b, sqrt(pos)));
|
||||||
|
res = pow(res, 0.70.xx);
|
||||||
|
return max(mix(1.0, sqrt(res.x*res.y), params.vigstr), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float vignette (vec2 coords)
|
|
||||||
|
vec3 plant (vec3 tar, float r)
|
||||||
{
|
{
|
||||||
vec2 ccoords = ctransform(2.0*(coords-0.5));
|
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
||||||
ccoords = ccoords * ccoords;
|
return tar * r / t;
|
||||||
float vstr = sqrt(ccoords.x+ccoords.y);
|
}
|
||||||
vstr = pow(vstr, params.vigdef);
|
|
||||||
return max(mix(1.0, 1.0-vstr, params.vigstr), 0.0);
|
float contrast(float x)
|
||||||
|
{
|
||||||
|
float y = 2.0*x-1.0;
|
||||||
|
y = (sin(y*1.57079632679)+1.0)*0.5;
|
||||||
|
return mix(x, y, params.contr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
@ -240,8 +253,6 @@ void main()
|
||||||
aftglow.rgb = AS*w*normalize(pow(aftglow.rgb + 0.01, vec3(sat)))*l;
|
aftglow.rgb = AS*w*normalize(pow(aftglow.rgb + 0.01, vec3(sat)))*l;
|
||||||
float bp = w * BP/255.0;
|
float bp = w * BP/255.0;
|
||||||
|
|
||||||
imgColor.rgb = imgColor.rgb * params.pre_bb;
|
|
||||||
|
|
||||||
if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0);
|
if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0);
|
||||||
|
|
||||||
imgColor.rgb = min(imgColor.rgb, 1.0);
|
imgColor.rgb = min(imgColor.rgb, 1.0);
|
||||||
|
@ -326,11 +337,13 @@ void main()
|
||||||
|
|
||||||
if (CP == -1.0) color = c;
|
if (CP == -1.0) color = c;
|
||||||
|
|
||||||
vec3 scolor1 = normalize(pow(color + 0.000000001, vec3(wp_saturation)))*length(color);
|
vec3 scolor1 = plant(pow(color, vec3(wp_saturation)), max(max(color.r,color.g),color.b));
|
||||||
float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
float luma = dot(color, vec3(0.299, 0.587, 0.114));
|
||||||
vec3 scolor2 = mix(vec3(luma), color, wp_saturation);
|
vec3 scolor2 = mix(vec3(luma), color, wp_saturation);
|
||||||
color = (wp_saturation > 1.0) ? scolor1 : scolor2;
|
color = (wp_saturation > 1.0) ? scolor1 : scolor2;
|
||||||
|
|
||||||
|
color = plant(color, contrast(max(max(color.r,color.g),color.b)));
|
||||||
|
|
||||||
p = 2.2;
|
p = 2.2;
|
||||||
|
|
||||||
color = pow(color, vec3(p));
|
color = pow(color, vec3(p));
|
||||||
|
@ -350,7 +363,12 @@ void main()
|
||||||
color = mix(color, comp, m);
|
color = mix(color, comp, m);
|
||||||
color = pow(max(color, 0.0), vec3(1.0/p));
|
color = pow(max(color, 0.0), vec3(1.0/p));
|
||||||
|
|
||||||
color = color + aftglow.rgb + bp;
|
if (BP > -0.5) color = color + aftglow.rgb + bp; else
|
||||||
|
{
|
||||||
|
color = max(color + BP/255.0, 0.0) / (1.0 + BP/255.0*step(- BP/255.0, max(max(color.r,color.g),color.b))) + aftglow.rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = min(color * params.pre_bb, 1.0);
|
||||||
|
|
||||||
FragColor = vec4(color, vignette(vTexCoord.xy));
|
FragColor = vec4(color, vignette(vTexCoord.xy));
|
||||||
}
|
}
|
|
@ -27,12 +27,9 @@ void main()
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D AfterglowPass;
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
#define PassPrev6Texture AfterglowPass
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
FragColor = vec4(pow(vec3(COMPAT_TEXTURE(PassPrev6Texture, vTexCoord).rgb), vec3(10.0)),1.0);
|
FragColor = vec4(texture(Source, vTexCoord).rgb, 1.0);
|
||||||
}
|
}
|
|
@ -1,105 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Phosphor Afterglow Shader
|
|
||||||
|
|
||||||
Copyright (C) 2018 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float AS, PR, PG, PB, sat;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter AS "Afterglow Strength" 0.07 0.0 1.0 0.01
|
|
||||||
#pragma parameter PR "Persistence Red (more is less)" 0.05 0.0 1.0 0.01
|
|
||||||
#pragma parameter PG "Persistence Green" 0.05 0.0 1.0 0.01
|
|
||||||
#pragma parameter PB "Persistence Blue" 0.05 0.0 1.0 0.01
|
|
||||||
#pragma parameter sat "Afterglow saturation" 0.10 0.0 1.0 0.01
|
|
||||||
|
|
||||||
#define AS params.AS
|
|
||||||
#define PR params.PR
|
|
||||||
#define PG params.PG
|
|
||||||
#define PB params.PB
|
|
||||||
#define sat params.sat
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
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 OriginalHistory1;
|
|
||||||
layout(set = 0, binding = 4) uniform sampler2D OriginalHistory2;
|
|
||||||
layout(set = 0, binding = 5) uniform sampler2D OriginalHistory3;
|
|
||||||
layout(set = 0, binding = 6) uniform sampler2D OriginalHistory4;
|
|
||||||
layout(set = 0, binding = 7) uniform sampler2D OriginalHistory5;
|
|
||||||
layout(set = 0, binding = 8) uniform sampler2D OriginalHistory6;
|
|
||||||
|
|
||||||
#define Prev1Texture OriginalHistory1
|
|
||||||
#define Prev2Texture OriginalHistory2
|
|
||||||
#define Prev3Texture OriginalHistory3
|
|
||||||
#define Prev4Texture OriginalHistory4
|
|
||||||
#define Prev5Texture OriginalHistory5
|
|
||||||
#define Prev6Texture OriginalHistory6
|
|
||||||
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
#define eps 1e-3
|
|
||||||
|
|
||||||
vec3 afterglow(float number)
|
|
||||||
{
|
|
||||||
return vec3(AS)*exp2(-vec3(PR, PG, PB)*vec3(number*number));
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec3 color = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
|
|
||||||
vec3 color1 = COMPAT_TEXTURE(Prev1Texture, TEX0.xy).rgb * afterglow(1.0);
|
|
||||||
vec3 color2 = COMPAT_TEXTURE(Prev2Texture, TEX0.xy).rgb * afterglow(2.0);
|
|
||||||
vec3 color3 = COMPAT_TEXTURE(Prev3Texture, TEX0.xy).rgb * afterglow(3.0);
|
|
||||||
vec3 color4 = COMPAT_TEXTURE(Prev4Texture, TEX0.xy).rgb * afterglow(4.0);
|
|
||||||
vec3 color5 = COMPAT_TEXTURE(Prev5Texture, TEX0.xy).rgb * afterglow(5.0);
|
|
||||||
vec3 color6 = COMPAT_TEXTURE(Prev6Texture, TEX0.xy).rgb * afterglow(6.0);
|
|
||||||
|
|
||||||
vec3 glow = color1 + color2 + color3 + color4 + color5 + color6;
|
|
||||||
|
|
||||||
float l = length(glow);
|
|
||||||
glow = normalize(pow(glow + vec3(eps), vec3(sat)))*l;
|
|
||||||
|
|
||||||
float w = 1.0;
|
|
||||||
if ((color.r + color.g + color.b) > 7.0/255.0) w = 0.0;
|
|
||||||
|
|
||||||
FragColor = vec4(color + w*glow,1.0);
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Average Luminance Shader
|
|
||||||
|
|
||||||
Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Thanks to HunterK for the mipmap hint. :D
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
uint FrameCount;
|
|
||||||
vec4 SourceSize;
|
|
||||||
float lsmooth;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter lsmooth "Raster Bloom Effect Smoothing" 0.90 0.50 0.99 0.01
|
|
||||||
|
|
||||||
#define lsmooth params.lsmooth
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
#define InputSize SourceSize
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
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 AvgLumPassFeedback;
|
|
||||||
|
|
||||||
#define PassPrev2Texture WhitePointPass
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
if (vTexCoord.x > 0.2 || vTexCoord.y > 0.2) discard;
|
|
||||||
|
|
||||||
float m = max(log2(SourceSize.x), log2(SourceSize.y));
|
|
||||||
m = max(m - 1.0, 1.0);
|
|
||||||
|
|
||||||
float ltotal = 0.0;
|
|
||||||
|
|
||||||
ltotal+= max(0.0, length(textureLod(Source, vec2(0.25, 0.25), m).rgb));
|
|
||||||
ltotal+= max(0.0, length(textureLod(Source, vec2(0.25, 0.75), m).rgb));
|
|
||||||
ltotal+= max(0.0, length(textureLod(Source, vec2(0.75, 0.25), m).rgb));
|
|
||||||
ltotal+= max(0.0, length(textureLod(Source, vec2(0.75, 0.75), m).rgb));
|
|
||||||
|
|
||||||
ltotal*=0.25;
|
|
||||||
|
|
||||||
ltotal = pow(0.577350269 * ltotal, 0.6);
|
|
||||||
|
|
||||||
float lhistory = texture(AvgLumPassFeedback, vec2(0.1,0.1)).a;
|
|
||||||
|
|
||||||
ltotal = mix(ltotal, lhistory, lsmooth);
|
|
||||||
|
|
||||||
FragColor = vec4(ltotal);
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float TAPSH;
|
|
||||||
float GLOW_FALLOFF_H;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
// Higher value, more centered glow.
|
|
||||||
// Lower values might need more taps.
|
|
||||||
#pragma parameter TAPSH "H. Glow Radius" 4.0 1.0 10.0 1.0
|
|
||||||
#define TAPSH params.TAPSH
|
|
||||||
#pragma parameter GLOW_FALLOFF_H "Horizontal Glow Grade" 0.30 0.00 1.0 0.01
|
|
||||||
#define GLOW_FALLOFF_H params.GLOW_FALLOFF_H
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
|
|
||||||
#define kernel(x) exp(-GLOW_FALLOFF_H * (x) * (x))
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec3 col = vec3(0.0);
|
|
||||||
float dx = SourceSize.z;
|
|
||||||
|
|
||||||
float k_total = 0.;
|
|
||||||
for (float i = -TAPSH; i <= TAPSH; i++)
|
|
||||||
{
|
|
||||||
float k = kernel(i);
|
|
||||||
k_total += k;
|
|
||||||
col += k * COMPAT_TEXTURE(Source, vTexCoord + vec2(float(i) * dx, 0.0)).rgb;
|
|
||||||
}
|
|
||||||
FragColor = vec4(col / k_total, 1.0);
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float TAPSV;
|
|
||||||
float GLOW_FALLOFF_V;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
// Higher value, more centered glow.
|
|
||||||
// Lower values might need more taps.
|
|
||||||
// Parameter lines go here:
|
|
||||||
#pragma parameter TAPSV "V. Glow Radius" 4.0 1.0 10.0 1.0
|
|
||||||
#define TAPSV params.TAPSV
|
|
||||||
#pragma parameter GLOW_FALLOFF_V "Vertical Glow Grade" 0.30 0.00 1.0 0.01
|
|
||||||
#define GLOW_FALLOFF_V params.GLOW_FALLOFF_V
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
|
|
||||||
#define kernel(x) exp(-GLOW_FALLOFF_V * (x) * (x))
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec3 col = vec3(0.0);
|
|
||||||
float dy = SourceSize.w;
|
|
||||||
|
|
||||||
float k_total = 0.;
|
|
||||||
for (float i = -TAPSV; i <= TAPSV; i++)
|
|
||||||
{
|
|
||||||
float k = kernel(i);
|
|
||||||
k_total += k;
|
|
||||||
col += k * COMPAT_TEXTURE(Source, vTexCoord + vec2(0.0, float(i) * dy)).rgb;
|
|
||||||
}
|
|
||||||
FragColor = vec4(col / k_total, 1.0);
|
|
||||||
}
|
|
|
@ -1,160 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT Color Profiles
|
|
||||||
|
|
||||||
Copyright (C) 2019 guest(r) and Dr. Venom
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float CP, CS;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter CP "CRT Color Profile" 0.0 -1.0 5.0 1.0
|
|
||||||
#pragma parameter CS "Color Space: sRGB, DCI, Adobe, Rec.2020" 0.0 0.0 3.0 1.0
|
|
||||||
|
|
||||||
#define CP params.CP
|
|
||||||
#define CS params.CS
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
const mat3 Profile0 =
|
|
||||||
mat3(
|
|
||||||
0.412391, 0.212639, 0.019331,
|
|
||||||
0.357584, 0.715169, 0.119195,
|
|
||||||
0.180481, 0.072192, 0.950532
|
|
||||||
);
|
|
||||||
|
|
||||||
const mat3 Profile1 =
|
|
||||||
mat3(
|
|
||||||
0.430554, 0.222004, 0.020182,
|
|
||||||
0.341550, 0.706655, 0.129553,
|
|
||||||
0.178352, 0.071341, 0.939322
|
|
||||||
);
|
|
||||||
|
|
||||||
const mat3 Profile2 =
|
|
||||||
mat3(
|
|
||||||
0.396686, 0.210299, 0.006131,
|
|
||||||
0.372504, 0.713766, 0.115356,
|
|
||||||
0.181266, 0.075936, 0.967571
|
|
||||||
);
|
|
||||||
|
|
||||||
const mat3 Profile3 =
|
|
||||||
mat3(
|
|
||||||
0.393521, 0.212376, 0.018739,
|
|
||||||
0.365258, 0.701060, 0.111934,
|
|
||||||
0.191677, 0.086564, 0.958385
|
|
||||||
);
|
|
||||||
|
|
||||||
const mat3 Profile4 =
|
|
||||||
mat3(
|
|
||||||
0.392258, 0.209410, 0.016061,
|
|
||||||
0.351135, 0.725680, 0.093636,
|
|
||||||
0.166603, 0.064910, 0.850324
|
|
||||||
);
|
|
||||||
|
|
||||||
const mat3 Profile5 =
|
|
||||||
mat3(
|
|
||||||
0.377923, 0.195679, 0.010514,
|
|
||||||
0.317366, 0.722319, 0.097826,
|
|
||||||
0.207738, 0.082002, 1.076960
|
|
||||||
);
|
|
||||||
|
|
||||||
const mat3 ToSRGB =
|
|
||||||
mat3(
|
|
||||||
3.240970, -0.969244, 0.055630,
|
|
||||||
-1.537383, 1.875968, -0.203977,
|
|
||||||
-0.498611, 0.041555, 1.056972
|
|
||||||
);
|
|
||||||
|
|
||||||
const mat3 ToDCI =
|
|
||||||
mat3(
|
|
||||||
2.725394, -0.795168, 0.041242,
|
|
||||||
-1.018003, 1.689732, -0.087639,
|
|
||||||
-0.440163, 0.022647, 1.100929
|
|
||||||
);
|
|
||||||
|
|
||||||
const mat3 ToAdobe =
|
|
||||||
mat3(
|
|
||||||
2.041588, -0.969244, 0.013444,
|
|
||||||
-0.565007, 1.875968, -0.11836,
|
|
||||||
-0.344731, 0.041555, 1.015175
|
|
||||||
);
|
|
||||||
|
|
||||||
const mat3 ToREC =
|
|
||||||
mat3(
|
|
||||||
1.716651, -0.666684, 0.017640,
|
|
||||||
-0.355671, 1.616481, -0.042771,
|
|
||||||
-0.253366, 0.015769, 0.942103
|
|
||||||
);
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec3 c = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
|
|
||||||
|
|
||||||
float p;
|
|
||||||
mat3 m_out;
|
|
||||||
|
|
||||||
if (CS == 0.0) { p = 2.4; m_out = ToSRGB; } else
|
|
||||||
if (CS == 1.0) { p = 2.6; m_out = ToDCI; } else
|
|
||||||
if (CS == 2.0) { p = 2.2; m_out = ToAdobe;} else
|
|
||||||
if (CS == 3.0) { p = 2.4; m_out = ToREC; }
|
|
||||||
|
|
||||||
vec3 color = pow(c, vec3(p));
|
|
||||||
|
|
||||||
mat3 m_in = Profile0;
|
|
||||||
|
|
||||||
if (CP == 0.0) { m_in = Profile0; } else
|
|
||||||
if (CP == 1.0) { m_in = Profile1; } else
|
|
||||||
if (CP == 2.0) { m_in = Profile2; } else
|
|
||||||
if (CP == 3.0) { m_in = Profile3; } else
|
|
||||||
if (CP == 4.0) { m_in = Profile4; } else
|
|
||||||
if (CP == 5.0) { m_in = Profile5; }
|
|
||||||
|
|
||||||
color = m_in*color;
|
|
||||||
color = m_out*color;
|
|
||||||
|
|
||||||
color = pow(color, vec3(1.0/p));
|
|
||||||
|
|
||||||
if (CP == -1.0) color = c;
|
|
||||||
|
|
||||||
FragColor = vec4(color,1.0);
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Average Luminance Shader
|
|
||||||
|
|
||||||
Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Thanks to HunterK for the mipmap hint. :D
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
uint FrameCount;
|
|
||||||
vec4 SourceSize;
|
|
||||||
float lsmooth;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter lsmooth "Raster Bloom Effect Smoothing" 0.90 0.50 0.99 0.01
|
|
||||||
|
|
||||||
#define lsmooth params.lsmooth
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
#define InputSize SourceSize
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
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 OriginalHistory0;
|
|
||||||
layout(set = 0, binding = 3) uniform sampler2D AvgLumPassFeedback;
|
|
||||||
|
|
||||||
#define PassPrev2Texture WhitePointPass
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
if (vTexCoord.x > 0.2 || vTexCoord.y > 0.2) discard;
|
|
||||||
|
|
||||||
float m = max(log2(SourceSize.x), log2(SourceSize.y));
|
|
||||||
m = max(m - 1.0, 1.0);
|
|
||||||
|
|
||||||
float ltotal = 0.0;
|
|
||||||
|
|
||||||
ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.25, 0.25), m).rgb));
|
|
||||||
ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.25, 0.75), m).rgb));
|
|
||||||
ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.75, 0.25), m).rgb));
|
|
||||||
ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.75, 0.75), m).rgb));
|
|
||||||
|
|
||||||
ltotal*=0.25;
|
|
||||||
|
|
||||||
ltotal = pow(0.577350269 * ltotal, 0.6);
|
|
||||||
|
|
||||||
float lhistory = texture(AvgLumPassFeedback, vec2(0.1,0.1)).a;
|
|
||||||
|
|
||||||
ltotal = mix(ltotal, lhistory, lsmooth);
|
|
||||||
|
|
||||||
FragColor = vec4(ltotal);
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Average Luminance Shader, Smart Edge Interpolation Coefficients Calculation
|
|
||||||
|
|
||||||
Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Thanks to HunterK for the mipmap hint. :D
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
uint FrameCount;
|
|
||||||
vec4 SourceSize;
|
|
||||||
float lsmooth;
|
|
||||||
float sth;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter lsmooth "Raster Bloom Effect Smoothing" 0.75 0.50 0.99 0.01
|
|
||||||
|
|
||||||
#define lsmooth params.lsmooth
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
#define InputSize SourceSize
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
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 OriginalHistory0;
|
|
||||||
layout(set = 0, binding = 3) uniform sampler2D AvgLumPassFeedback;
|
|
||||||
|
|
||||||
|
|
||||||
// Reference: http://www.compuphase.com/cmetric.htm
|
|
||||||
// Reference: ScaleFX, author Sp00kyFox
|
|
||||||
|
|
||||||
float dist(vec3 A, vec3 B)
|
|
||||||
{
|
|
||||||
float r = 0.5 * (A.r + B.r);
|
|
||||||
vec3 d = A - B;
|
|
||||||
vec3 c = vec3(2. + r, 4., 3. - r);
|
|
||||||
|
|
||||||
return sqrt(dot(c*d, d)) / 3.;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
float m = max(log2(SourceSize.x), log2(SourceSize.y));
|
|
||||||
m = max(m - 1.0, 1.0);
|
|
||||||
|
|
||||||
vec2 dx = vec2(1.0/SourceSize.x, 0.0);
|
|
||||||
vec2 dy = vec2(0.0, 1.0/SourceSize.y);
|
|
||||||
vec2 y2 = 2.0*dy;
|
|
||||||
vec2 x2 = 2.0*dx;
|
|
||||||
|
|
||||||
float ltotal = 0.0;
|
|
||||||
|
|
||||||
ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.25, 0.25), m).rgb));
|
|
||||||
ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.25, 0.75), m).rgb));
|
|
||||||
ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.75, 0.25), m).rgb));
|
|
||||||
ltotal+= max(0.0, length(textureLod(OriginalHistory0, vec2(0.75, 0.75), m).rgb));
|
|
||||||
|
|
||||||
ltotal*=0.25;
|
|
||||||
|
|
||||||
ltotal = pow(0.577350269 * ltotal, 0.6);
|
|
||||||
|
|
||||||
float lhistory = texture(AvgLumPassFeedback, vec2(0.1,0.1)).a;
|
|
||||||
|
|
||||||
ltotal = mix(ltotal, lhistory, lsmooth);
|
|
||||||
|
|
||||||
vec3 l1 = COMPAT_TEXTURE(OriginalHistory0, TEX0.xy ).rgb;
|
|
||||||
vec3 r1 = COMPAT_TEXTURE(OriginalHistory0, TEX0.xy +dx ).rgb;
|
|
||||||
vec3 l2 = COMPAT_TEXTURE(OriginalHistory0, TEX0.xy -dx ).rgb;
|
|
||||||
vec3 r2 = COMPAT_TEXTURE(OriginalHistory0, TEX0.xy +x2 ).rgb;
|
|
||||||
|
|
||||||
float c1 = dist(l2,l1);
|
|
||||||
float c2 = dist(l1,r1);
|
|
||||||
float c3 = dist(r2,r1);
|
|
||||||
|
|
||||||
FragColor = vec4(c1,c2,c3,ltotal);
|
|
||||||
}
|
|
|
@ -1,729 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - Dr. Venom
|
|
||||||
|
|
||||||
Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
|
||||||
h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask,
|
|
||||||
slotmask, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike, intres, inters;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float bloom;
|
|
||||||
float mclip;
|
|
||||||
float scans;
|
|
||||||
float scansub;
|
|
||||||
float slotms;
|
|
||||||
float gamma_c;
|
|
||||||
float mask_gamma;
|
|
||||||
float gamma_out;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter glow " Glow Strength" 0.08 0.0 2.0 0.01
|
|
||||||
#define glow params.glow // Glow Strength
|
|
||||||
|
|
||||||
#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05
|
|
||||||
#define bloom global.bloom // bloom effect
|
|
||||||
|
|
||||||
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
|
||||||
#define gamma_c global.gamma_c // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.50 10.0 0.05
|
|
||||||
#define brightboost params.brightboost // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost1 " Bright Boost bright Pixels" 1.10 0.50 3.00 0.025
|
|
||||||
#define brightboost1 params.brightboost1 // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter gsl " Scanline Type" 0.0 0.0 2.0 1.0
|
|
||||||
#define gsl params.gsl // Alternate scanlines
|
|
||||||
|
|
||||||
#pragma parameter scanline1 " Scanline beam shape low" 6.0 0.0 20.0 0.5
|
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter scanline2 " Scanline beam shape high" 8.0 3.0 40.0 1.0
|
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter beam_min " Scanline shape dark pixels" 1.30 0.5 3.5 0.05
|
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
|
||||||
|
|
||||||
#pragma parameter beam_max " Scanline shape bright pixels" 1.00 0.4 2.5 0.05
|
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
|
||||||
|
|
||||||
#pragma parameter beam_size " Increased bright scanline beam" 0.60 0.0 1.0 0.05
|
|
||||||
#define beam_size params.beam_size // increased max. beam size
|
|
||||||
|
|
||||||
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
|
||||||
#define vertmask params.vertmask // Scanline deconvergence colors
|
|
||||||
|
|
||||||
#pragma parameter scans " Scanline Saturation" 0.60 0.0 1.0 0.05
|
|
||||||
#define scans global.scans // scanline saturation
|
|
||||||
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// #pragma parameter scansub " Scanline darken 'edges'" 0.0 0.0 0.30 0.005
|
|
||||||
// #define scansub global.scansub // scanline substraction
|
|
||||||
|
|
||||||
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
|
||||||
#define spike params.spike
|
|
||||||
|
|
||||||
#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.20
|
|
||||||
#define h_sharp params.h_sharp // pixel sharpness
|
|
||||||
|
|
||||||
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
|
||||||
#define s_sharp params.s_sharp // substractive sharpness
|
|
||||||
|
|
||||||
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter intres " Internal Resolution: 1.0:240p, 1.5...y-dowsample" 0.0 0.0 4.0 0.5 // Joint parameter with linearize_ntsc pass, values must match
|
|
||||||
#define intres params.intres // interlace resolution
|
|
||||||
|
|
||||||
#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0
|
|
||||||
#define TATE params.TATE // Screen orientation
|
|
||||||
|
|
||||||
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
|
||||||
#define IOS params.IOS // Smart Integer Scaling
|
|
||||||
|
|
||||||
#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
|
|
||||||
#define OS params.OS // Do overscan
|
|
||||||
|
|
||||||
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
|
||||||
#define BLOOM params.BLOOM // Bloom overscan percentage
|
|
||||||
|
|
||||||
#pragma parameter csize " Corner size" 0.0 0.0 0.07 0.01
|
|
||||||
#define csize params.csize // corner size
|
|
||||||
|
|
||||||
#pragma parameter bsize " Border smoothness" 600.0 100.0 600.0 25.0
|
|
||||||
#define bsize params.bsize // border smoothness
|
|
||||||
|
|
||||||
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.125 0.01
|
|
||||||
#define warpX params.warpX // Curvature X
|
|
||||||
|
|
||||||
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.125 0.01
|
|
||||||
#define warpY params.warpY // Curvature Y
|
|
||||||
|
|
||||||
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0
|
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
|
||||||
|
|
||||||
#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05
|
|
||||||
#define maskstr params.maskstr // maskstr Mask Strength
|
|
||||||
|
|
||||||
#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.0 1.0
|
|
||||||
#define masksize params.masksize // Mask Size
|
|
||||||
|
|
||||||
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
|
||||||
#define maskDark params.maskDark // Dark "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter mcut " Mask 5-7 Low Strength" 1.15 0.0 2.0 0.05
|
|
||||||
#define mcut params.mcut // Mask 5-7 cutoff
|
|
||||||
|
|
||||||
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05
|
|
||||||
#define mask_gamma global.mask_gamma // Mask application gamma
|
|
||||||
|
|
||||||
#pragma parameter slotmask " Slot Mask Strength" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask params.slotmask // Slot Mask ON/OFF
|
|
||||||
|
|
||||||
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 6.0 0.5
|
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
|
||||||
|
|
||||||
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
|
||||||
|
|
||||||
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 2.0 1.0
|
|
||||||
#define slotms global.slotms // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter mclip " Keep Mask effect with clipping" 0.5 0.0 1.0 0.05
|
|
||||||
#define mclip global.mclip // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05
|
|
||||||
#define gamma_out global.gamma_out // output gamma
|
|
||||||
|
|
||||||
#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // Joint parameter with linearize-ntsc pass, values must match
|
|
||||||
#define inters params.inters // interlacing effect smoothing
|
|
||||||
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
#define OutputSize global.OutputSize
|
|
||||||
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
|
||||||
|
|
||||||
#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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma stage fragment
|
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
|
||||||
layout(location = 0) out vec4 FragColor;
|
|
||||||
layout(set = 0, binding = 2) uniform sampler2D LinearizePass;
|
|
||||||
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
|
||||||
layout(set = 0, binding = 4) uniform sampler2D GlowPass;
|
|
||||||
|
|
||||||
|
|
||||||
#define eps 1e-10
|
|
||||||
|
|
||||||
float st(float x)
|
|
||||||
{
|
|
||||||
return exp2(-10.0*x*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw0(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix(beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw1(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
x = mix (x, beam_min*x, max(x-0.4*color,0.0));
|
|
||||||
float tmp = mix(1.2*beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw2(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix(2.5*beam_min, beam_max, color);
|
|
||||||
tmp = mix(beam_max, tmp, pow(x, color+0.3));
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shadow mask (1-4 from PD CRT Lottes shader).
|
|
||||||
|
|
||||||
vec3 Mask(vec2 pos, float mx)
|
|
||||||
{
|
|
||||||
pos = floor(pos/masksize);
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 0.0) + 1.0, 1.0, mx);
|
|
||||||
float mc = 1.0 - max(maskstr, 0.0);
|
|
||||||
|
|
||||||
// No mask
|
|
||||||
if (shadowMask == -1.0)
|
|
||||||
{
|
|
||||||
mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phosphor.
|
|
||||||
else if (shadowMask == 0.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x*0.5);
|
|
||||||
if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
|
||||||
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very compressed TV style shadow mask.
|
|
||||||
else if (shadowMask == 1.0)
|
|
||||||
{
|
|
||||||
float line = maskLight;
|
|
||||||
float odd = 0.0;
|
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
|
||||||
odd = 1.0;
|
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
|
||||||
line = maskDark;
|
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
|
|
||||||
mask*=line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aperture-grille.
|
|
||||||
else if (shadowMask == 2.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stretched VGA style shadow mask (same as prior shaders).
|
|
||||||
else if (shadowMask == 3.0)
|
|
||||||
{
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA style shadow mask.
|
|
||||||
else if (shadowMask == 4.0)
|
|
||||||
{
|
|
||||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 5
|
|
||||||
else if (shadowMask == 5.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5)
|
|
||||||
{ mask.r = 1.0;
|
|
||||||
mask.b = 1.0;
|
|
||||||
}
|
|
||||||
else mask.g = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 6
|
|
||||||
else if (shadowMask == 6.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
if (pos.x < 0.333) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.666) mask.g = 1.0;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BW Trinitron mask 7
|
|
||||||
else if (shadowMask == 7.0)
|
|
||||||
{
|
|
||||||
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
mask = vec3(maskTmp);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5) mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4k mask
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mask = vec3(mc);
|
|
||||||
pos.x = fract(pos.x * 0.25);
|
|
||||||
if (pos.x < 0.2) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
|
||||||
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SlotMask(vec2 pos, float m)
|
|
||||||
{
|
|
||||||
if (slotmask == 0.0) return 1.0;
|
|
||||||
|
|
||||||
pos = floor(pos/slotms);
|
|
||||||
float mlen = slotwidth*2.0;
|
|
||||||
float px = fract(pos.x/mlen);
|
|
||||||
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
|
||||||
float slot_dark = 1.0 - slotmask*(1.0 - 0.125*m);
|
|
||||||
float slot = 1.0;
|
|
||||||
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
|
||||||
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Distortion of scanlines, and end of screen alpha (PD Lottes Curvature)
|
|
||||||
vec2 Warp(vec2 pos)
|
|
||||||
{
|
|
||||||
pos = pos*2.0-1.0;
|
|
||||||
pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY);
|
|
||||||
return pos*0.5 + 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Overscan(vec2 pos, float dx, float dy){
|
|
||||||
pos=pos*2.0-1.0;
|
|
||||||
pos*=vec2(dx,dy);
|
|
||||||
return pos*0.5+0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Borrowed from maskstr's crt-geom, under GPL
|
|
||||||
|
|
||||||
float corner(vec2 coord)
|
|
||||||
{
|
|
||||||
coord = (coord - vec2(0.5)) * 1.0 + vec2(0.5);
|
|
||||||
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
|
|
||||||
vec2 cdist = vec2(max(csize, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002)));
|
|
||||||
coord = (cdist - min(coord,cdist));
|
|
||||||
float dist = sqrt(dot(coord,coord));
|
|
||||||
return clamp((cdist.x-dist)*bsize,0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 gc(vec3 c)
|
|
||||||
{
|
|
||||||
float mc = max(max(c.r,c.g),c.b);
|
|
||||||
float mg = pow(mc, 1.0/gamma_c);
|
|
||||||
return c * mg/(mc + eps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 SourceSize = global.OriginalSize;
|
|
||||||
|
|
||||||
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.1,0.1)).a;
|
|
||||||
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
|
||||||
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
|
||||||
bool interb = (intera < 0.75);
|
|
||||||
|
|
||||||
bool notate = (TATE < 0.5);
|
|
||||||
|
|
||||||
float SourceY = mix(SourceSize.y, SourceSize.x, TATE);
|
|
||||||
float sy = 1.0;
|
|
||||||
if (intres == 1.0) sy = SourceY/240.0; else
|
|
||||||
if (intres > 1.25) sy = intres;
|
|
||||||
if (notate) SourceSize.yw*=vec2(1.0/sy, sy); else SourceSize.xz*=vec2(1.0/sy, sy);
|
|
||||||
SourceY = SourceY/sy;
|
|
||||||
|
|
||||||
// Calculating texel coordinates
|
|
||||||
|
|
||||||
vec2 texcoord = TEX0.xy;
|
|
||||||
if (IOS > 0.0){
|
|
||||||
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
|
||||||
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
|
||||||
vec2 diff = ofactor/intfactor;
|
|
||||||
float scan = mix(diff.y, diff.x, TATE);
|
|
||||||
texcoord = Overscan(texcoord, scan, scan);
|
|
||||||
if (IOS == 1.0 || IOS == 3.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
|
||||||
texcoord = Overscan(texcoord, factor, factor);
|
|
||||||
vec2 pos = Warp(texcoord);
|
|
||||||
vec2 pos0 = Warp(TEX0.xy);
|
|
||||||
|
|
||||||
vec2 coffset = vec2(0.5, 0.5);
|
|
||||||
|
|
||||||
vec2 ps = SourceSize.zw;
|
|
||||||
vec2 OGL2Pos = pos * SourceSize.xy - coffset;
|
|
||||||
vec2 fp = fract(OGL2Pos);
|
|
||||||
|
|
||||||
vec2 dx = vec2(ps.x,0.0);
|
|
||||||
vec2 dy = vec2(0.0, ps.y);
|
|
||||||
|
|
||||||
// Reading the texels
|
|
||||||
vec2 x2 = 2.0*dx;
|
|
||||||
vec2 y2 = 2.0*dy;
|
|
||||||
|
|
||||||
vec2 offx = dx;
|
|
||||||
vec2 off2 = x2;
|
|
||||||
vec2 offy = dy;
|
|
||||||
float fpx = fp.x;
|
|
||||||
if(!notate)
|
|
||||||
{
|
|
||||||
offx = dy;
|
|
||||||
off2 = y2;
|
|
||||||
offy = dx;
|
|
||||||
fpx = fp.y;
|
|
||||||
}
|
|
||||||
float f = (notate) ? fp.y : fp.x;
|
|
||||||
|
|
||||||
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
|
|
||||||
|
|
||||||
if (interb) pC4.y = pos.y - inters * SourceSize.w;
|
|
||||||
|
|
||||||
float h_sharp1 = pow(h_sharp, 1.4);
|
|
||||||
|
|
||||||
float zero = exp2(-h_sharp1);
|
|
||||||
|
|
||||||
float sharp1 = s_sharp * zero;
|
|
||||||
|
|
||||||
float wl5 = 4.0 + fpx; wl5*=0.5;
|
|
||||||
float wl4 = 3.0 + fpx; wl4*=0.5;
|
|
||||||
float wl3 = 2.0 + fpx; wl3*=0.5;
|
|
||||||
float wl2 = 1.0 + fpx; wl2*=0.5;
|
|
||||||
float wl1 = fpx; wl1*=0.5;
|
|
||||||
float wr1 = 1.0 - fpx; wr1*=0.5;
|
|
||||||
float wr2 = 2.0 - fpx; wr2*=0.5;
|
|
||||||
float wr3 = 3.0 - fpx; wr3*=0.5;
|
|
||||||
float wr4 = 4.0 - fpx; wr4*=0.5;
|
|
||||||
float wr5 = 5.0 - fpx; wr5*=0.5;
|
|
||||||
|
|
||||||
wl5*=wl5; wl5 = exp2(-h_sharp1*wl5);
|
|
||||||
wl4*=wl4; wl4 = exp2(-h_sharp1*wl4);
|
|
||||||
wl3*=wl3; wl3 = exp2(-h_sharp1*wl3);
|
|
||||||
wl2*=wl2; wl2 = exp2(-h_sharp1*wl2);
|
|
||||||
wl1*=wl1; wl1 = exp2(-h_sharp1*wl1);
|
|
||||||
wr1*=wr1; wr1 = exp2(-h_sharp1*wr1);
|
|
||||||
wr2*=wr2; wr2 = exp2(-h_sharp1*wr2);
|
|
||||||
wr3*=wr3; wr3 = exp2(-h_sharp1*wr3);
|
|
||||||
wr4*=wr4; wr4 = exp2(-h_sharp1*wr4);
|
|
||||||
wr5*=wr5; wr5 = exp2(-h_sharp1*wr5);
|
|
||||||
|
|
||||||
float fp1 = 1.-fpx;
|
|
||||||
|
|
||||||
float twl5 = max(wl5 - sharp1, 0.0);
|
|
||||||
float twl4 = max(wl4 - sharp1, mix(0.0,mix(-0.03, 0.00, fpx),float(s_sharp > 0.05))); float swl4 = max(wl4 - sharp1, 0.0);
|
|
||||||
float twl3 = max(wl3 - sharp1, mix(0.0,mix(-0.10, -0.03, fpx),float(s_sharp > 0.05))); float swl3 = max(wl3 - sharp1, 0.0);
|
|
||||||
float twl2 = max(wl2 - sharp1, 0.0);
|
|
||||||
float twl1 = max(wl1 - sharp1, 0.0);
|
|
||||||
float twr1 = max(wr1 - sharp1, 0.0);
|
|
||||||
float twr2 = max(wr2 - sharp1, 0.0);
|
|
||||||
float twr3 = max(wr3 - sharp1, mix(0.0,mix(-0.10, -0.03, fp1),float(s_sharp > 0.05))); float swr3 = max(wr3 - sharp1, 0.0);
|
|
||||||
float twr4 = max(wr4 - sharp1, mix(0.0,mix(-0.03, 0.00, fp1),float(s_sharp > 0.05))); float swr4 = max(wr4 - sharp1, 0.0);
|
|
||||||
float twr5 = max(wr5 - sharp1, 0.0);
|
|
||||||
|
|
||||||
float wtt = 1.0/(twl5+twl4+twl3+twl2+twl1+twr1+twr2+twr3+twr4+twr5);
|
|
||||||
float wt = 1.0/(swl3+twl2+twl1+twr1+twr2+swr3);
|
|
||||||
bool sharp = (s_sharp > 0.05);
|
|
||||||
|
|
||||||
vec3 l5 = COMPAT_TEXTURE(LinearizePass, pC4 -2.0*off2).xyz;
|
|
||||||
vec3 l4 = COMPAT_TEXTURE(LinearizePass, pC4 -3.0*offx).xyz;
|
|
||||||
vec3 l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).xyz;
|
|
||||||
vec3 l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).xyz;
|
|
||||||
vec3 l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).xyz;
|
|
||||||
vec3 r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).xyz;
|
|
||||||
vec3 r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).xyz;
|
|
||||||
vec3 r3 = COMPAT_TEXTURE(LinearizePass, pC4 +3.0*offx).xyz;
|
|
||||||
vec3 r4 = COMPAT_TEXTURE(LinearizePass, pC4 +4.0*offx).xyz;
|
|
||||||
vec3 r5 = COMPAT_TEXTURE(LinearizePass, pC4 +5.0*offx).xyz;
|
|
||||||
|
|
||||||
vec3 sl3 = l3*l3*l3; sl3*=sl3;
|
|
||||||
vec3 sl2 = l2*l2*l2; sl2*=sl2;
|
|
||||||
vec3 sl1 = l1*l1*l1; sl1*=sl1;
|
|
||||||
vec3 sr1 = r1*r1*r1; sr1*=sr1;
|
|
||||||
vec3 sr2 = r2*r2*r2; sr2*=sr2;
|
|
||||||
vec3 sr3 = r3*r3*r3; sr3*=sr3;
|
|
||||||
|
|
||||||
vec3 color1 = (l5*twl5+l4*twl4+l3*twl3+l2*twl2+l1*twl1+r1*twr1+r2*twr2+r3*twr3+r4*twr4+r5*twr5)*wtt;
|
|
||||||
|
|
||||||
vec3 colmin1 = min(min(l1,r1), min(l2,r2));
|
|
||||||
vec3 colmax1 = max(max(l1,r1), max(l2,r2));
|
|
||||||
vec3 colmin2 = min(min(l3,r3), min(l4,r4));
|
|
||||||
vec3 colmax2 = max(max(l3,r3), max(l4,r4));
|
|
||||||
vec3 colmin = min(colmin1, colmin2);
|
|
||||||
vec3 colmax = max(colmax1, colmax2);
|
|
||||||
|
|
||||||
if (sharp) color1 = clamp(color1, colmin, colmax);
|
|
||||||
|
|
||||||
vec3 gtmp = vec3(1.0/6.0);
|
|
||||||
vec3 scolor1 = color1;
|
|
||||||
|
|
||||||
scolor1 = (sl3*swl3 + sl2*twl2 + sl1*twl1 + sr1*twr1 + sr2*twr2 + sr3*swr3)*wt;
|
|
||||||
scolor1 = pow(scolor1, gtmp); vec3 mcolor1 = scolor1;
|
|
||||||
scolor1 = min(mix(color1, scolor1, spike),1.0);
|
|
||||||
|
|
||||||
vec3 color2, scolor2, mcolor2;
|
|
||||||
|
|
||||||
if (interb) pC4.y = pos.y + inters * SourceSize.w; else
|
|
||||||
pC4+=offy;
|
|
||||||
|
|
||||||
l5 = COMPAT_TEXTURE(LinearizePass, pC4 -2.0*off2).xyz;
|
|
||||||
l4 = COMPAT_TEXTURE(LinearizePass, pC4 -3.0*offx).xyz;
|
|
||||||
l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).xyz;
|
|
||||||
l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).xyz;
|
|
||||||
l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).xyz;
|
|
||||||
r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).xyz;
|
|
||||||
r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).xyz;
|
|
||||||
r3 = COMPAT_TEXTURE(LinearizePass, pC4 +3.0*offx).xyz;
|
|
||||||
r4 = COMPAT_TEXTURE(LinearizePass, pC4 +4.0*offx).xyz;
|
|
||||||
r5 = COMPAT_TEXTURE(LinearizePass, pC4 +5.0*offx).xyz;
|
|
||||||
|
|
||||||
sl3 = l3*l3*l3; sl3*=sl3;
|
|
||||||
sl2 = l2*l2*l2; sl2*=sl2;
|
|
||||||
sl1 = l1*l1*l1; sl1*=sl1;
|
|
||||||
sr1 = r1*r1*r1; sr1*=sr1;
|
|
||||||
sr2 = r2*r2*r2; sr2*=sr2;
|
|
||||||
sr3 = r3*r3*r3; sr3*=sr3;
|
|
||||||
|
|
||||||
color2 = (l5*twl5+l4*twl4+l3*twl3+l2*twl2+l1*twl1+r1*twr1+r2*twr2+r3*twr3+r4*twr4+r5*twr5)*wtt;
|
|
||||||
|
|
||||||
colmin1 = min(min(l1,r1), min(l2,r2));
|
|
||||||
colmax1 = max(max(l1,r1), max(l2,r2));
|
|
||||||
colmin2 = min(min(l3,r3), min(l3,r3));
|
|
||||||
colmax2 = max(max(l4,r4), max(l4,r4));
|
|
||||||
colmin = min(colmin1, colmin2);
|
|
||||||
colmax = max(colmax1, colmax2);
|
|
||||||
|
|
||||||
if (sharp) color2 = clamp(color2, colmin, colmax);
|
|
||||||
|
|
||||||
scolor2 = color2;
|
|
||||||
|
|
||||||
scolor2 = (sl3*swl3 + sl2*twl2 + sl1*twl1 + sr1*twr1 + sr2*twr2 + sr3*swr3)*wt;
|
|
||||||
scolor2 = pow(scolor2, gtmp); mcolor2 = scolor2;
|
|
||||||
scolor2 = min(mix(color2, scolor2, spike),1.0);
|
|
||||||
|
|
||||||
// calculating scanlines
|
|
||||||
|
|
||||||
vec3 ctmp; vec3 mcolor; float w3; vec3 color;
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
|
|
||||||
if (!interb)
|
|
||||||
{
|
|
||||||
float shape1 = mix(scanline1, scanline2, f);
|
|
||||||
float shape2 = mix(scanline1, scanline2, 1.0-f);
|
|
||||||
|
|
||||||
float wt1 = st(f);
|
|
||||||
float wt2 = st(1.0-f);
|
|
||||||
|
|
||||||
vec3 color00 = color1*wt1 + color2*wt2;
|
|
||||||
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
|
||||||
mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2);
|
|
||||||
|
|
||||||
ctmp = color00/(wt1+wt2);
|
|
||||||
vec3 sctmp = scolor0/(wt1+wt2);
|
|
||||||
|
|
||||||
float wf1, wf2;
|
|
||||||
|
|
||||||
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b);
|
|
||||||
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b);
|
|
||||||
|
|
||||||
float f1 = f;
|
|
||||||
float f2 = 1.0-f;
|
|
||||||
|
|
||||||
if (gsl == 0.0) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else
|
|
||||||
if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else
|
|
||||||
if (gsl == 2.0) { wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);}
|
|
||||||
|
|
||||||
if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; }
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// float ws1 = max(wf1 - scansub, 0.2*wf1*wf2); wf1 = ws1/(1.0 - wf1 + ws1);
|
|
||||||
// float ws2 = max(wf2 - scansub, 0.2*wf2*wf1); wf2 = ws2/(1.0 - wf2 + ws2);
|
|
||||||
|
|
||||||
// Scanline saturation application
|
|
||||||
|
|
||||||
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
|
||||||
|
|
||||||
cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001);
|
|
||||||
cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001);
|
|
||||||
|
|
||||||
w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1);
|
|
||||||
w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2);
|
|
||||||
|
|
||||||
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
|
||||||
|
|
||||||
float v_high1 = 1.0 + 0.3*vm;
|
|
||||||
float v_high2 = 1.0 + 0.6*vm;
|
|
||||||
float v_low = 1.0 - vm;
|
|
||||||
|
|
||||||
float ds1 = min(pow(2.0*f1 + 0.01, f2), 1.0);
|
|
||||||
float ds2 = min(pow(2.0*f2 + 0.01, f1), 1.0);
|
|
||||||
|
|
||||||
if (vertmask < 0.0)
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2);
|
|
||||||
}
|
|
||||||
|
|
||||||
color = gc(color1)*w1*cd1 + gc(color2)*w2*cd2;
|
|
||||||
color = min(color, 1.0);
|
|
||||||
w3 = wf1+wf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interb)
|
|
||||||
{
|
|
||||||
color = gc(0.5*(color1+color2));
|
|
||||||
mcolor = vec3(max(max(color.r,color.g), color.b));
|
|
||||||
}
|
|
||||||
|
|
||||||
float mx = max(max(mcolor.r,mcolor.g),mcolor.b);
|
|
||||||
mx = pow(mx, 1.40/gamma_in);
|
|
||||||
|
|
||||||
// Apply Mask
|
|
||||||
|
|
||||||
vec3 orig1 = color;
|
|
||||||
vec3 cmask = one;
|
|
||||||
|
|
||||||
float smask = (notate) ? SlotMask(gl_FragCoord.xy * 1.000001, mx) : SlotMask(gl_FragCoord.yx * 1.000001, mx);
|
|
||||||
|
|
||||||
cmask*= (notate) ? Mask(gl_FragCoord.xy * 1.000001, mx) : Mask(gl_FragCoord.yx * 1.000001, mx);
|
|
||||||
|
|
||||||
color = pow(color, vec3(mask_gamma/gamma_in));
|
|
||||||
color = color*cmask;
|
|
||||||
color = min(color,1.0);
|
|
||||||
color = color*smask;
|
|
||||||
color = pow(color, vec3(gamma_in/mask_gamma));
|
|
||||||
|
|
||||||
cmask = min(cmask*smask, 1.0);
|
|
||||||
|
|
||||||
if (interb) ctmp = color;
|
|
||||||
float colmx = pow( max( max(ctmp.r, ctmp.g), ctmp.b), 1.40/gamma_out);
|
|
||||||
float bb = mix(brightboost, brightboost1, colmx);
|
|
||||||
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
|
||||||
color*=bb;
|
|
||||||
|
|
||||||
vec3 Glow = COMPAT_TEXTURE(GlowPass, pos ).rgb;
|
|
||||||
|
|
||||||
vec3 Bloom = min(Glow*(orig1+color), max(0.5*(colmx + orig1 - color),0.0));
|
|
||||||
color = color + bloom*Bloom;
|
|
||||||
|
|
||||||
color = min(color, mix(one, cmask, mclip));
|
|
||||||
if (!interb) color = declip(color, pow(w3,0.6));
|
|
||||||
|
|
||||||
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
|
||||||
color = color + 0.5*glow*Glow;
|
|
||||||
|
|
||||||
float gmo = 1.0/gamma_out;
|
|
||||||
if (interb) gmo = gmo / 0.70;
|
|
||||||
|
|
||||||
color = pow(color, vec3(gmo));
|
|
||||||
|
|
||||||
FragColor = vec4(color*corner(pos0), 1.0);
|
|
||||||
}
|
|
|
@ -1,729 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - Dr. Venom
|
|
||||||
|
|
||||||
Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
|
||||||
h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask,
|
|
||||||
slotmask, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike, intres, inters;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float bloom;
|
|
||||||
float mclip;
|
|
||||||
float scans;
|
|
||||||
float scansub;
|
|
||||||
float slotms;
|
|
||||||
float gamma_c;
|
|
||||||
float mask_gamma;
|
|
||||||
float gamma_out;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter glow " Glow Strength" 0.08 0.0 2.0 0.01
|
|
||||||
#define glow params.glow // Glow Strength
|
|
||||||
|
|
||||||
#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05
|
|
||||||
#define bloom global.bloom // bloom effect
|
|
||||||
|
|
||||||
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
|
||||||
#define gamma_c global.gamma_c // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.50 10.0 0.05
|
|
||||||
#define brightboost params.brightboost // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost1 " Bright Boost bright Pixels" 1.10 0.50 3.00 0.025
|
|
||||||
#define brightboost1 params.brightboost1 // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter gsl " Scanline Type" 0.0 0.0 2.0 1.0
|
|
||||||
#define gsl params.gsl // Alternate scanlines
|
|
||||||
|
|
||||||
#pragma parameter scanline1 " Scanline beam shape low" 6.0 0.0 20.0 0.5
|
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter scanline2 " Scanline beam shape high" 8.0 3.0 40.0 1.0
|
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter beam_min " Scanline shape dark pixels" 1.30 0.5 3.5 0.05
|
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
|
||||||
|
|
||||||
#pragma parameter beam_max " Scanline shape bright pixels" 1.00 0.4 2.5 0.05
|
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
|
||||||
|
|
||||||
#pragma parameter beam_size " Increased bright scanline beam" 0.60 0.0 1.0 0.05
|
|
||||||
#define beam_size params.beam_size // increased max. beam size
|
|
||||||
|
|
||||||
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
|
||||||
#define vertmask params.vertmask // Scanline deconvergence colors
|
|
||||||
|
|
||||||
#pragma parameter scans " Scanline Saturation" 0.60 0.0 1.0 0.05
|
|
||||||
#define scans global.scans // scanline saturation
|
|
||||||
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// #pragma parameter scansub " Scanline darken 'edges'" 0.0 0.0 0.30 0.005
|
|
||||||
// #define scansub global.scansub // scanline substraction
|
|
||||||
|
|
||||||
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
|
||||||
#define spike params.spike
|
|
||||||
|
|
||||||
#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.20
|
|
||||||
#define h_sharp params.h_sharp // pixel sharpness
|
|
||||||
|
|
||||||
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
|
||||||
#define s_sharp params.s_sharp // substractive sharpness
|
|
||||||
|
|
||||||
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter intres " Internal Resolution: 1.0:240p, 1.5...y-dowsample" 0.0 0.0 4.0 0.5 // Joint parameter with linearize_ntsc pass, values must match
|
|
||||||
#define intres params.intres // interlace resolution
|
|
||||||
|
|
||||||
#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0
|
|
||||||
#define TATE params.TATE // Screen orientation
|
|
||||||
|
|
||||||
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
|
||||||
#define IOS params.IOS // Smart Integer Scaling
|
|
||||||
|
|
||||||
#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
|
|
||||||
#define OS params.OS // Do overscan
|
|
||||||
|
|
||||||
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
|
||||||
#define BLOOM params.BLOOM // Bloom overscan percentage
|
|
||||||
|
|
||||||
#pragma parameter csize " Corner size" 0.0 0.0 0.07 0.01
|
|
||||||
#define csize params.csize // corner size
|
|
||||||
|
|
||||||
#pragma parameter bsize " Border smoothness" 600.0 100.0 600.0 25.0
|
|
||||||
#define bsize params.bsize // border smoothness
|
|
||||||
|
|
||||||
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.125 0.01
|
|
||||||
#define warpX params.warpX // Curvature X
|
|
||||||
|
|
||||||
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.125 0.01
|
|
||||||
#define warpY params.warpY // Curvature Y
|
|
||||||
|
|
||||||
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0
|
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
|
||||||
|
|
||||||
#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05
|
|
||||||
#define maskstr params.maskstr // maskstr Mask Strength
|
|
||||||
|
|
||||||
#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.0 1.0
|
|
||||||
#define masksize params.masksize // Mask Size
|
|
||||||
|
|
||||||
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
|
||||||
#define maskDark params.maskDark // Dark "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter mcut " Mask 5-7 Low Strength" 1.15 0.0 2.0 0.05
|
|
||||||
#define mcut params.mcut // Mask 5-7 cutoff
|
|
||||||
|
|
||||||
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05
|
|
||||||
#define mask_gamma global.mask_gamma // Mask application gamma
|
|
||||||
|
|
||||||
#pragma parameter slotmask " Slot Mask Strength" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask params.slotmask // Slot Mask ON/OFF
|
|
||||||
|
|
||||||
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 6.0 0.5
|
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
|
||||||
|
|
||||||
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
|
||||||
|
|
||||||
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 2.0 1.0
|
|
||||||
#define slotms global.slotms // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter mclip " Keep Mask effect with clipping" 0.5 0.0 1.0 0.05
|
|
||||||
#define mclip global.mclip // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05
|
|
||||||
#define gamma_out global.gamma_out // output gamma
|
|
||||||
|
|
||||||
#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // Joint parameter with linearize-ntsc pass, values must match
|
|
||||||
#define inters params.inters // interlacing effect smoothing
|
|
||||||
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
#define OutputSize global.OutputSize
|
|
||||||
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
|
||||||
|
|
||||||
#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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma stage fragment
|
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
|
||||||
layout(location = 0) out vec4 FragColor;
|
|
||||||
layout(set = 0, binding = 2) uniform sampler2D LinearizePass;
|
|
||||||
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
|
||||||
layout(set = 0, binding = 4) uniform sampler2D GlowPass;
|
|
||||||
|
|
||||||
|
|
||||||
#define eps 1e-10
|
|
||||||
|
|
||||||
float st(float x)
|
|
||||||
{
|
|
||||||
return exp2(-10.0*x*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw0(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix(beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw1(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
x = mix (x, beam_min*x, max(x-0.4*color,0.0));
|
|
||||||
float tmp = mix(1.2*beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw2(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix(2.5*beam_min, beam_max, color);
|
|
||||||
tmp = mix(beam_max, tmp, pow(x, color+0.3));
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shadow mask (1-4 from PD CRT Lottes shader).
|
|
||||||
|
|
||||||
vec3 Mask(vec2 pos, float mx)
|
|
||||||
{
|
|
||||||
pos = floor(pos/masksize);
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 0.0) + 1.0, 1.0, mx);
|
|
||||||
float mc = 1.0 - max(maskstr, 0.0);
|
|
||||||
|
|
||||||
// No mask
|
|
||||||
if (shadowMask == -1.0)
|
|
||||||
{
|
|
||||||
mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phosphor.
|
|
||||||
else if (shadowMask == 0.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x*0.5);
|
|
||||||
if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
|
||||||
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very compressed TV style shadow mask.
|
|
||||||
else if (shadowMask == 1.0)
|
|
||||||
{
|
|
||||||
float line = maskLight;
|
|
||||||
float odd = 0.0;
|
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
|
||||||
odd = 1.0;
|
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
|
||||||
line = maskDark;
|
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
|
|
||||||
mask*=line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aperture-grille.
|
|
||||||
else if (shadowMask == 2.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stretched VGA style shadow mask (same as prior shaders).
|
|
||||||
else if (shadowMask == 3.0)
|
|
||||||
{
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA style shadow mask.
|
|
||||||
else if (shadowMask == 4.0)
|
|
||||||
{
|
|
||||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 5
|
|
||||||
else if (shadowMask == 5.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5)
|
|
||||||
{ mask.r = 1.0;
|
|
||||||
mask.b = 1.0;
|
|
||||||
}
|
|
||||||
else mask.g = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 6
|
|
||||||
else if (shadowMask == 6.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
if (pos.x < 0.333) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.666) mask.g = 1.0;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BW Trinitron mask 7
|
|
||||||
else if (shadowMask == 7.0)
|
|
||||||
{
|
|
||||||
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
mask = vec3(maskTmp);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5) mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4k mask
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mask = vec3(mc);
|
|
||||||
pos.x = fract(pos.x * 0.25);
|
|
||||||
if (pos.x < 0.2) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
|
||||||
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SlotMask(vec2 pos, float m)
|
|
||||||
{
|
|
||||||
if (slotmask == 0.0) return 1.0;
|
|
||||||
|
|
||||||
pos = floor(pos/slotms);
|
|
||||||
float mlen = slotwidth*2.0;
|
|
||||||
float px = fract(pos.x/mlen);
|
|
||||||
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
|
||||||
float slot_dark = 1.0 - slotmask*(1.0 - 0.125*m);
|
|
||||||
float slot = 1.0;
|
|
||||||
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
|
||||||
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Distortion of scanlines, and end of screen alpha (PD Lottes Curvature)
|
|
||||||
vec2 Warp(vec2 pos)
|
|
||||||
{
|
|
||||||
pos = pos*2.0-1.0;
|
|
||||||
pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY);
|
|
||||||
return pos*0.5 + 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Overscan(vec2 pos, float dx, float dy){
|
|
||||||
pos=pos*2.0-1.0;
|
|
||||||
pos*=vec2(dx,dy);
|
|
||||||
return pos*0.5+0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Borrowed from maskstr's crt-geom, under GPL
|
|
||||||
|
|
||||||
float corner(vec2 coord)
|
|
||||||
{
|
|
||||||
coord = (coord - vec2(0.5)) * 1.0 + vec2(0.5);
|
|
||||||
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
|
|
||||||
vec2 cdist = vec2(max(csize, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002)));
|
|
||||||
coord = (cdist - min(coord,cdist));
|
|
||||||
float dist = sqrt(dot(coord,coord));
|
|
||||||
return clamp((cdist.x-dist)*bsize,0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 gc(vec3 c)
|
|
||||||
{
|
|
||||||
float mc = max(max(c.r,c.g),c.b);
|
|
||||||
float mg = pow(mc, 1.0/gamma_c);
|
|
||||||
return c * mg/(mc + eps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 SourceSize = global.OriginalSize * vec4(2.0, 1.0, 0.5, 1.0);
|
|
||||||
|
|
||||||
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.1,0.1)).a;
|
|
||||||
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
|
||||||
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
|
||||||
bool interb = (intera < 0.75);
|
|
||||||
|
|
||||||
bool notate = (TATE < 0.5);
|
|
||||||
|
|
||||||
float SourceY = mix(SourceSize.y, SourceSize.x, TATE);
|
|
||||||
float sy = 1.0;
|
|
||||||
if (intres == 1.0) sy = SourceY/240.0; else
|
|
||||||
if (intres > 1.25) sy = intres;
|
|
||||||
if (notate) SourceSize.yw*=vec2(1.0/sy, sy); else SourceSize.xz*=vec2(1.0/sy, sy);
|
|
||||||
SourceY = SourceY/sy;
|
|
||||||
|
|
||||||
// Calculating texel coordinates
|
|
||||||
|
|
||||||
vec2 texcoord = TEX0.xy;
|
|
||||||
if (IOS > 0.0){
|
|
||||||
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
|
||||||
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
|
||||||
vec2 diff = ofactor/intfactor;
|
|
||||||
float scan = mix(diff.y, diff.x, TATE);
|
|
||||||
texcoord = Overscan(texcoord, scan, scan);
|
|
||||||
if (IOS == 1.0 || IOS == 3.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
|
||||||
texcoord = Overscan(texcoord, factor, factor);
|
|
||||||
vec2 pos = Warp(texcoord);
|
|
||||||
vec2 pos0 = Warp(TEX0.xy);
|
|
||||||
|
|
||||||
vec2 coffset = vec2(0.5, 0.5);
|
|
||||||
|
|
||||||
vec2 ps = SourceSize.zw;
|
|
||||||
vec2 OGL2Pos = pos * SourceSize.xy - coffset;
|
|
||||||
vec2 fp = fract(OGL2Pos);
|
|
||||||
|
|
||||||
vec2 dx = vec2(ps.x,0.0);
|
|
||||||
vec2 dy = vec2(0.0, ps.y);
|
|
||||||
|
|
||||||
// Reading the texels
|
|
||||||
vec2 x2 = 2.0*dx;
|
|
||||||
vec2 y2 = 2.0*dy;
|
|
||||||
|
|
||||||
vec2 offx = dx;
|
|
||||||
vec2 off2 = x2;
|
|
||||||
vec2 offy = dy;
|
|
||||||
float fpx = fp.x;
|
|
||||||
if(!notate)
|
|
||||||
{
|
|
||||||
offx = dy;
|
|
||||||
off2 = y2;
|
|
||||||
offy = dx;
|
|
||||||
fpx = fp.y;
|
|
||||||
}
|
|
||||||
float f = (notate) ? fp.y : fp.x;
|
|
||||||
|
|
||||||
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
|
|
||||||
|
|
||||||
if (interb) pC4.y = pos.y - inters * SourceSize.w;
|
|
||||||
|
|
||||||
float h_sharp1 = pow(h_sharp, 1.4);
|
|
||||||
|
|
||||||
float zero = exp2(-h_sharp1);
|
|
||||||
|
|
||||||
float sharp1 = s_sharp * zero;
|
|
||||||
|
|
||||||
float wl5 = 4.0 + fpx; wl5*=0.5;
|
|
||||||
float wl4 = 3.0 + fpx; wl4*=0.5;
|
|
||||||
float wl3 = 2.0 + fpx; wl3*=0.5;
|
|
||||||
float wl2 = 1.0 + fpx; wl2*=0.5;
|
|
||||||
float wl1 = fpx; wl1*=0.5;
|
|
||||||
float wr1 = 1.0 - fpx; wr1*=0.5;
|
|
||||||
float wr2 = 2.0 - fpx; wr2*=0.5;
|
|
||||||
float wr3 = 3.0 - fpx; wr3*=0.5;
|
|
||||||
float wr4 = 4.0 - fpx; wr4*=0.5;
|
|
||||||
float wr5 = 5.0 - fpx; wr5*=0.5;
|
|
||||||
|
|
||||||
wl5*=wl5; wl5 = exp2(-h_sharp1*wl5);
|
|
||||||
wl4*=wl4; wl4 = exp2(-h_sharp1*wl4);
|
|
||||||
wl3*=wl3; wl3 = exp2(-h_sharp1*wl3);
|
|
||||||
wl2*=wl2; wl2 = exp2(-h_sharp1*wl2);
|
|
||||||
wl1*=wl1; wl1 = exp2(-h_sharp1*wl1);
|
|
||||||
wr1*=wr1; wr1 = exp2(-h_sharp1*wr1);
|
|
||||||
wr2*=wr2; wr2 = exp2(-h_sharp1*wr2);
|
|
||||||
wr3*=wr3; wr3 = exp2(-h_sharp1*wr3);
|
|
||||||
wr4*=wr4; wr4 = exp2(-h_sharp1*wr4);
|
|
||||||
wr5*=wr5; wr5 = exp2(-h_sharp1*wr5);
|
|
||||||
|
|
||||||
float fp1 = 1.-fpx;
|
|
||||||
|
|
||||||
float twl5 = max(wl5 - sharp1, 0.0);
|
|
||||||
float twl4 = max(wl4 - sharp1, mix(0.0,mix(-0.03, 0.00, fpx),float(s_sharp > 0.05))); float swl4 = max(wl4 - sharp1, 0.0);
|
|
||||||
float twl3 = max(wl3 - sharp1, mix(0.0,mix(-0.10, -0.03, fpx),float(s_sharp > 0.05))); float swl3 = max(wl3 - sharp1, 0.0);
|
|
||||||
float twl2 = max(wl2 - sharp1, 0.0);
|
|
||||||
float twl1 = max(wl1 - sharp1, 0.0);
|
|
||||||
float twr1 = max(wr1 - sharp1, 0.0);
|
|
||||||
float twr2 = max(wr2 - sharp1, 0.0);
|
|
||||||
float twr3 = max(wr3 - sharp1, mix(0.0,mix(-0.10, -0.03, fp1),float(s_sharp > 0.05))); float swr3 = max(wr3 - sharp1, 0.0);
|
|
||||||
float twr4 = max(wr4 - sharp1, mix(0.0,mix(-0.03, 0.00, fp1),float(s_sharp > 0.05))); float swr4 = max(wr4 - sharp1, 0.0);
|
|
||||||
float twr5 = max(wr5 - sharp1, 0.0);
|
|
||||||
|
|
||||||
float wtt = 1.0/(twl5+twl4+twl3+twl2+twl1+twr1+twr2+twr3+twr4+twr5);
|
|
||||||
float wt = 1.0/(swl3+twl2+twl1+twr1+twr2+swr3);
|
|
||||||
bool sharp = (s_sharp > 0.05);
|
|
||||||
|
|
||||||
vec3 l5 = COMPAT_TEXTURE(LinearizePass, pC4 -2.0*off2).xyz;
|
|
||||||
vec3 l4 = COMPAT_TEXTURE(LinearizePass, pC4 -3.0*offx).xyz;
|
|
||||||
vec3 l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).xyz;
|
|
||||||
vec3 l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).xyz;
|
|
||||||
vec3 l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).xyz;
|
|
||||||
vec3 r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).xyz;
|
|
||||||
vec3 r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).xyz;
|
|
||||||
vec3 r3 = COMPAT_TEXTURE(LinearizePass, pC4 +3.0*offx).xyz;
|
|
||||||
vec3 r4 = COMPAT_TEXTURE(LinearizePass, pC4 +4.0*offx).xyz;
|
|
||||||
vec3 r5 = COMPAT_TEXTURE(LinearizePass, pC4 +5.0*offx).xyz;
|
|
||||||
|
|
||||||
vec3 sl3 = l3*l3*l3; sl3*=sl3;
|
|
||||||
vec3 sl2 = l2*l2*l2; sl2*=sl2;
|
|
||||||
vec3 sl1 = l1*l1*l1; sl1*=sl1;
|
|
||||||
vec3 sr1 = r1*r1*r1; sr1*=sr1;
|
|
||||||
vec3 sr2 = r2*r2*r2; sr2*=sr2;
|
|
||||||
vec3 sr3 = r3*r3*r3; sr3*=sr3;
|
|
||||||
|
|
||||||
vec3 color1 = (l5*twl5+l4*twl4+l3*twl3+l2*twl2+l1*twl1+r1*twr1+r2*twr2+r3*twr3+r4*twr4+r5*twr5)*wtt;
|
|
||||||
|
|
||||||
vec3 colmin1 = min(min(l1,r1), min(l2,r2));
|
|
||||||
vec3 colmax1 = max(max(l1,r1), max(l2,r2));
|
|
||||||
vec3 colmin2 = min(min(l3,r3), min(l4,r4));
|
|
||||||
vec3 colmax2 = max(max(l3,r3), max(l4,r4));
|
|
||||||
vec3 colmin = min(colmin1, colmin2);
|
|
||||||
vec3 colmax = max(colmax1, colmax2);
|
|
||||||
|
|
||||||
if (sharp) color1 = clamp(color1, colmin, colmax);
|
|
||||||
|
|
||||||
vec3 gtmp = vec3(1.0/6.0);
|
|
||||||
vec3 scolor1 = color1;
|
|
||||||
|
|
||||||
scolor1 = (sl3*swl3 + sl2*twl2 + sl1*twl1 + sr1*twr1 + sr2*twr2 + sr3*swr3)*wt;
|
|
||||||
scolor1 = pow(scolor1, gtmp); vec3 mcolor1 = scolor1;
|
|
||||||
scolor1 = min(mix(color1, scolor1, spike),1.0);
|
|
||||||
|
|
||||||
vec3 color2, scolor2, mcolor2;
|
|
||||||
|
|
||||||
if (interb) pC4.y = pos.y + inters * SourceSize.w; else
|
|
||||||
pC4+=offy;
|
|
||||||
|
|
||||||
l5 = COMPAT_TEXTURE(LinearizePass, pC4 -2.0*off2).xyz;
|
|
||||||
l4 = COMPAT_TEXTURE(LinearizePass, pC4 -3.0*offx).xyz;
|
|
||||||
l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).xyz;
|
|
||||||
l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).xyz;
|
|
||||||
l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).xyz;
|
|
||||||
r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).xyz;
|
|
||||||
r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).xyz;
|
|
||||||
r3 = COMPAT_TEXTURE(LinearizePass, pC4 +3.0*offx).xyz;
|
|
||||||
r4 = COMPAT_TEXTURE(LinearizePass, pC4 +4.0*offx).xyz;
|
|
||||||
r5 = COMPAT_TEXTURE(LinearizePass, pC4 +5.0*offx).xyz;
|
|
||||||
|
|
||||||
sl3 = l3*l3*l3; sl3*=sl3;
|
|
||||||
sl2 = l2*l2*l2; sl2*=sl2;
|
|
||||||
sl1 = l1*l1*l1; sl1*=sl1;
|
|
||||||
sr1 = r1*r1*r1; sr1*=sr1;
|
|
||||||
sr2 = r2*r2*r2; sr2*=sr2;
|
|
||||||
sr3 = r3*r3*r3; sr3*=sr3;
|
|
||||||
|
|
||||||
color2 = (l5*twl5+l4*twl4+l3*twl3+l2*twl2+l1*twl1+r1*twr1+r2*twr2+r3*twr3+r4*twr4+r5*twr5)*wtt;
|
|
||||||
|
|
||||||
colmin1 = min(min(l1,r1), min(l2,r2));
|
|
||||||
colmax1 = max(max(l1,r1), max(l2,r2));
|
|
||||||
colmin2 = min(min(l3,r3), min(l3,r3));
|
|
||||||
colmax2 = max(max(l4,r4), max(l4,r4));
|
|
||||||
colmin = min(colmin1, colmin2);
|
|
||||||
colmax = max(colmax1, colmax2);
|
|
||||||
|
|
||||||
if (sharp) color2 = clamp(color2, colmin, colmax);
|
|
||||||
|
|
||||||
scolor2 = color2;
|
|
||||||
|
|
||||||
scolor2 = (sl3*swl3 + sl2*twl2 + sl1*twl1 + sr1*twr1 + sr2*twr2 + sr3*swr3)*wt;
|
|
||||||
scolor2 = pow(scolor2, gtmp); mcolor2 = scolor2;
|
|
||||||
scolor2 = min(mix(color2, scolor2, spike),1.0);
|
|
||||||
|
|
||||||
// calculating scanlines
|
|
||||||
|
|
||||||
vec3 ctmp; vec3 mcolor; float w3; vec3 color;
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
|
|
||||||
if (!interb)
|
|
||||||
{
|
|
||||||
float shape1 = mix(scanline1, scanline2, f);
|
|
||||||
float shape2 = mix(scanline1, scanline2, 1.0-f);
|
|
||||||
|
|
||||||
float wt1 = st(f);
|
|
||||||
float wt2 = st(1.0-f);
|
|
||||||
|
|
||||||
vec3 color00 = color1*wt1 + color2*wt2;
|
|
||||||
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
|
||||||
mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2);
|
|
||||||
|
|
||||||
ctmp = color00/(wt1+wt2);
|
|
||||||
vec3 sctmp = scolor0/(wt1+wt2);
|
|
||||||
|
|
||||||
float wf1, wf2;
|
|
||||||
|
|
||||||
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b);
|
|
||||||
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b);
|
|
||||||
|
|
||||||
float f1 = f;
|
|
||||||
float f2 = 1.0-f;
|
|
||||||
|
|
||||||
if (gsl == 0.0) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else
|
|
||||||
if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else
|
|
||||||
if (gsl == 2.0) { wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);}
|
|
||||||
|
|
||||||
if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; }
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// float ws1 = max(wf1 - scansub, 0.2*wf1*wf2); wf1 = ws1/(1.0 - wf1 + ws1);
|
|
||||||
// float ws2 = max(wf2 - scansub, 0.2*wf2*wf1); wf2 = ws2/(1.0 - wf2 + ws2);
|
|
||||||
|
|
||||||
// Scanline saturation application
|
|
||||||
|
|
||||||
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
|
||||||
|
|
||||||
cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001);
|
|
||||||
cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001);
|
|
||||||
|
|
||||||
w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1);
|
|
||||||
w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2);
|
|
||||||
|
|
||||||
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
|
||||||
|
|
||||||
float v_high1 = 1.0 + 0.3*vm;
|
|
||||||
float v_high2 = 1.0 + 0.6*vm;
|
|
||||||
float v_low = 1.0 - vm;
|
|
||||||
|
|
||||||
float ds1 = min(pow(2.0*f1 + 0.01, f2), 1.0);
|
|
||||||
float ds2 = min(pow(2.0*f2 + 0.01, f1), 1.0);
|
|
||||||
|
|
||||||
if (vertmask < 0.0)
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2);
|
|
||||||
}
|
|
||||||
|
|
||||||
color = gc(color1)*w1*cd1 + gc(color2)*w2*cd2;
|
|
||||||
color = min(color, 1.0);
|
|
||||||
w3 = wf1+wf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interb)
|
|
||||||
{
|
|
||||||
color = gc(0.5*(color1+color2));
|
|
||||||
mcolor = vec3(max(max(color.r,color.g), color.b));
|
|
||||||
}
|
|
||||||
|
|
||||||
float mx = max(max(mcolor.r,mcolor.g),mcolor.b);
|
|
||||||
mx = pow(mx, 1.40/gamma_in);
|
|
||||||
|
|
||||||
// Apply Mask
|
|
||||||
|
|
||||||
vec3 orig1 = color;
|
|
||||||
vec3 cmask = one;
|
|
||||||
|
|
||||||
float smask = (notate) ? SlotMask(gl_FragCoord.xy * 1.000001, mx) : SlotMask(gl_FragCoord.yx * 1.000001, mx);
|
|
||||||
|
|
||||||
cmask*= (notate) ? Mask(gl_FragCoord.xy * 1.000001, mx) : Mask(gl_FragCoord.yx * 1.000001, mx);
|
|
||||||
|
|
||||||
color = pow(color, vec3(mask_gamma/gamma_in));
|
|
||||||
color = color*cmask;
|
|
||||||
color = min(color,1.0);
|
|
||||||
color = color*smask;
|
|
||||||
color = pow(color, vec3(gamma_in/mask_gamma));
|
|
||||||
|
|
||||||
cmask = min(cmask*smask, 1.0);
|
|
||||||
|
|
||||||
if (interb) ctmp = color;
|
|
||||||
float colmx = pow( max( max(ctmp.r, ctmp.g), ctmp.b), 1.40/gamma_out);
|
|
||||||
float bb = mix(brightboost, brightboost1, colmx);
|
|
||||||
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
|
||||||
color*=bb;
|
|
||||||
|
|
||||||
vec3 Glow = COMPAT_TEXTURE(GlowPass, pos ).rgb;
|
|
||||||
|
|
||||||
vec3 Bloom = min(Glow*(orig1+color), max(0.5*(colmx + orig1 - color),0.0));
|
|
||||||
color = color + bloom*Bloom;
|
|
||||||
|
|
||||||
color = min(color, mix(one, cmask, mclip));
|
|
||||||
if (!interb) color = declip(color, pow(w3,0.6));
|
|
||||||
|
|
||||||
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
|
||||||
color = color + 0.5*glow*Glow;
|
|
||||||
|
|
||||||
float gmo = 1.0/gamma_out;
|
|
||||||
if (interb) gmo = gmo / 0.70;
|
|
||||||
|
|
||||||
color = pow(color, vec3(gmo));
|
|
||||||
|
|
||||||
FragColor = vec4(color*corner(pos0), 1.0);
|
|
||||||
}
|
|
|
@ -1,756 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - Dr. Venom
|
|
||||||
|
|
||||||
Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
|
||||||
h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask,
|
|
||||||
slotmask, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, spike, inters;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float bloom;
|
|
||||||
float halation;
|
|
||||||
float scans;
|
|
||||||
float scansub;
|
|
||||||
float slotms;
|
|
||||||
float mclip;
|
|
||||||
float gamma_c;
|
|
||||||
float mask_gamma;
|
|
||||||
float smart_ei;
|
|
||||||
float ei_limit;
|
|
||||||
float sth;
|
|
||||||
float gamma_out;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter glow " Glow Strength" 0.08 0.0 2.0 0.01
|
|
||||||
#define glow params.glow // Glow Strength
|
|
||||||
|
|
||||||
#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05
|
|
||||||
#define bloom global.bloom // bloom effect
|
|
||||||
|
|
||||||
#pragma parameter halation " Halation Strength" 0.0 0.0 0.5 0.025
|
|
||||||
#define halation global.halation // halation effect
|
|
||||||
|
|
||||||
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
|
||||||
#define gamma_c global.gamma_c // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.50 10.0 0.05
|
|
||||||
#define brightboost params.brightboost // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter brightboost1 " Bright Boost bright Pixels" 1.10 0.50 3.00 0.025
|
|
||||||
#define brightboost1 params.brightboost1 // adjust brightness
|
|
||||||
|
|
||||||
#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter gsl " Scanline Type" 0.0 0.0 2.0 1.0
|
|
||||||
#define gsl params.gsl // Alternate scanlines
|
|
||||||
|
|
||||||
#pragma parameter scanline1 " Scanline beam shape low" 6.0 0.0 20.0 0.5
|
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter scanline2 " Scanline beam shape high" 8.0 3.0 40.0 1.0
|
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
|
||||||
|
|
||||||
#pragma parameter beam_min " Scanline shape dark pixels" 1.30 0.5 3.5 0.05
|
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
|
||||||
|
|
||||||
#pragma parameter beam_max " Scanline shape bright pixels" 1.00 0.4 2.5 0.05
|
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
|
||||||
|
|
||||||
#pragma parameter beam_size " Increased bright scanline beam" 0.60 0.0 1.0 0.05
|
|
||||||
#define beam_size params.beam_size // increased max. beam size
|
|
||||||
|
|
||||||
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
|
||||||
#define vertmask params.vertmask // Scanline deconvergence colors
|
|
||||||
|
|
||||||
#pragma parameter scans " Scanline Saturation" 0.60 0.0 1.0 0.05
|
|
||||||
#define scans global.scans // scanline saturation
|
|
||||||
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// #pragma parameter scansub " Scanline darken 'edges'" 0.0 0.0 0.30 0.005
|
|
||||||
// #define scansub global.scansub // scanline substraction
|
|
||||||
|
|
||||||
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
|
||||||
#define spike params.spike
|
|
||||||
|
|
||||||
#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter h_sharp " Horizontal sharpness" 5.20 0.20 15.0 0.20
|
|
||||||
#define h_sharp params.h_sharp // pixel sharpness
|
|
||||||
|
|
||||||
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
|
||||||
#define s_sharp params.s_sharp // substractive sharpness
|
|
||||||
|
|
||||||
#pragma parameter smart_ei " Smart Edges Effect Strength" 0.0 0.0 20.0 0.25
|
|
||||||
#define smart_ei global.smart_ei // smart edge handling
|
|
||||||
|
|
||||||
#pragma parameter ei_limit " Smart Edges Effect Strength Limit" 2.0 1.0 12.0 0.1
|
|
||||||
#define ei_limit global.ei_limit // smart edge handling
|
|
||||||
|
|
||||||
#pragma parameter sth " Smart Edges Smoothing Threshold" 0.20 0.0 1.0 0.01
|
|
||||||
#define sth global.sth // corner size
|
|
||||||
|
|
||||||
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter TATE " TATE Mode" 0.0 0.0 1.0 1.0
|
|
||||||
#define TATE params.TATE // Screen orientation
|
|
||||||
|
|
||||||
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
|
||||||
#define IOS params.IOS // Smart Integer Scaling
|
|
||||||
|
|
||||||
#pragma parameter OS " R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
|
|
||||||
#define OS params.OS // Do overscan
|
|
||||||
|
|
||||||
#pragma parameter BLOOM " Raster bloom %" 0.0 0.0 20.0 1.0
|
|
||||||
#define BLOOM params.BLOOM // Bloom overscan percentage
|
|
||||||
|
|
||||||
#pragma parameter csize " Corner size" 0.0 0.0 0.07 0.01
|
|
||||||
#define csize params.csize // corner size
|
|
||||||
|
|
||||||
#pragma parameter bsize " Border smoothness" 600.0 100.0 600.0 25.0
|
|
||||||
#define bsize params.bsize // border smoothness
|
|
||||||
|
|
||||||
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.125 0.01
|
|
||||||
#define warpX params.warpX // Curvature X
|
|
||||||
|
|
||||||
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.125 0.01
|
|
||||||
#define warpY params.warpY // Curvature Y
|
|
||||||
|
|
||||||
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0
|
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
|
||||||
|
|
||||||
#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05
|
|
||||||
#define maskstr params.maskstr // CGWG Mask Strength
|
|
||||||
|
|
||||||
#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.0 1.0
|
|
||||||
#define masksize params.masksize // Mask Size
|
|
||||||
|
|
||||||
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
|
||||||
#define maskDark params.maskDark // Dark "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter mcut " Mask 5-7 Low Strength" 1.15 0.0 2.0 0.05
|
|
||||||
#define mcut params.mcut // Mask 5-7 cutoff
|
|
||||||
|
|
||||||
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05
|
|
||||||
#define mask_gamma global.mask_gamma // Mask application gamma
|
|
||||||
|
|
||||||
#pragma parameter slotmask " Slot Mask Strength" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask params.slotmask // Slot Mask ON/OFF
|
|
||||||
|
|
||||||
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 6.0 0.5
|
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
|
||||||
|
|
||||||
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
|
||||||
|
|
||||||
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 2.0 1.0
|
|
||||||
#define slotms global.slotms // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter mclip " Keep Mask effect with clipping" 0.5 0.0 1.0 0.05
|
|
||||||
#define mclip global.mclip // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05
|
|
||||||
#define gamma_out global.gamma_out // output gamma
|
|
||||||
|
|
||||||
#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // Joint parameter with linearize pass, values must match
|
|
||||||
#define inters params.inters // interlacing effect smoothing
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
#define SourceSize global.OriginalSize
|
|
||||||
#define OutputSize global.OutputSize
|
|
||||||
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
|
||||||
|
|
||||||
#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.000001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma stage fragment
|
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
|
||||||
layout(location = 0) out vec4 FragColor;
|
|
||||||
layout(set = 0, binding = 2) uniform sampler2D LinearizePass;
|
|
||||||
layout(set = 0, binding = 3) uniform sampler2D AvgLumPass;
|
|
||||||
layout(set = 0, binding = 4) uniform sampler2D GlowPass;
|
|
||||||
layout(set = 0, binding = 5) uniform sampler2D BloomPass;
|
|
||||||
|
|
||||||
#define eps 1e-10
|
|
||||||
|
|
||||||
float st(float x)
|
|
||||||
{
|
|
||||||
return exp2(-10.0*x*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw0(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix(beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw1(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
x = mix (x, beam_min*x, max(x-0.4*color,0.0));
|
|
||||||
float tmp = mix(1.2*beam_min, beam_max, color);
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
float sw2(float x, float color, float scanline)
|
|
||||||
{
|
|
||||||
float tmp = mix(2.5*beam_min, beam_max, color);
|
|
||||||
tmp = mix(beam_max, tmp, pow(x, color+0.3));
|
|
||||||
float ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shadow mask (1-4 from PD CRT Lottes shader).
|
|
||||||
|
|
||||||
vec3 Mask(vec2 pos, float mx)
|
|
||||||
{
|
|
||||||
pos = floor(pos/masksize);
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 0.0) + 1.0, 1.0, mx);
|
|
||||||
float mc = 1.0 - max(maskstr, 0.0);
|
|
||||||
|
|
||||||
// No mask
|
|
||||||
if (shadowMask == -1.0)
|
|
||||||
{
|
|
||||||
mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phosphor.
|
|
||||||
else if (shadowMask == 0.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x*0.5);
|
|
||||||
if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
|
||||||
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very compressed TV style shadow mask.
|
|
||||||
else if (shadowMask == 1.0)
|
|
||||||
{
|
|
||||||
float line = maskLight;
|
|
||||||
float odd = 0.0;
|
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
|
||||||
odd = 1.0;
|
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
|
||||||
line = maskDark;
|
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
|
|
||||||
mask*=line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aperture-grille.
|
|
||||||
else if (shadowMask == 2.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stretched VGA style shadow mask (same as prior shaders).
|
|
||||||
else if (shadowMask == 3.0)
|
|
||||||
{
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA style shadow mask.
|
|
||||||
else if (shadowMask == 4.0)
|
|
||||||
{
|
|
||||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 5
|
|
||||||
else if (shadowMask == 5.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5)
|
|
||||||
{ mask.r = 1.0;
|
|
||||||
mask.b = 1.0;
|
|
||||||
}
|
|
||||||
else mask.g = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 6
|
|
||||||
else if (shadowMask == 6.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
if (pos.x < 0.333) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.666) mask.g = 1.0;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BW Trinitron mask 7
|
|
||||||
else if (shadowMask == 7.0)
|
|
||||||
{
|
|
||||||
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
mask = vec3(maskTmp);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5) mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4k mask
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mask = vec3(mc);
|
|
||||||
pos.x = fract(pos.x * 0.25);
|
|
||||||
if (pos.x < 0.2) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
|
||||||
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SlotMask(vec2 pos, float m)
|
|
||||||
{
|
|
||||||
if (slotmask == 0.0) return 1.0;
|
|
||||||
|
|
||||||
pos = floor(pos/slotms);
|
|
||||||
float mlen = slotwidth*2.0;
|
|
||||||
float px = fract(pos.x/mlen);
|
|
||||||
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
|
||||||
float slot_dark = 1.0 - slotmask*(1.0 - 0.125*m);
|
|
||||||
float slot = 1.0;
|
|
||||||
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
|
||||||
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Distortion of scanlines, and end of screen alpha (PD Lottes Curvature)
|
|
||||||
vec2 Warp(vec2 pos)
|
|
||||||
{
|
|
||||||
pos = pos*2.0-1.0;
|
|
||||||
pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY);
|
|
||||||
return pos*0.5 + 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Overscan(vec2 pos, float dx, float dy){
|
|
||||||
pos=pos*2.0-1.0;
|
|
||||||
pos*=vec2(dx,dy);
|
|
||||||
return pos*0.5+0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Borrowed from cgwg's crt-geom, under GPL
|
|
||||||
|
|
||||||
float corner(vec2 coord)
|
|
||||||
{
|
|
||||||
coord = (coord - vec2(0.5)) * 1.0 + vec2(0.5);
|
|
||||||
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
|
|
||||||
vec2 cdist = vec2(max(csize, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002)));
|
|
||||||
coord = (cdist - min(coord,cdist));
|
|
||||||
float dist = sqrt(dot(coord,coord));
|
|
||||||
return clamp((cdist.x-dist)*bsize,0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 gc(vec3 c)
|
|
||||||
{
|
|
||||||
float mc = max(max(c.r,c.g),c.b);
|
|
||||||
float mg = pow(mc, 1.0/gamma_c);
|
|
||||||
return c * mg/(mc + eps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
|
|
||||||
float lum = COMPAT_TEXTURE(AvgLumPass, vec2(0.1,0.1)).a;
|
|
||||||
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
|
||||||
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
|
||||||
bool interb = (intera < 0.75);
|
|
||||||
|
|
||||||
// Calculating texel coordinates
|
|
||||||
|
|
||||||
vec2 texcoord = TEX0.xy;
|
|
||||||
if (IOS > 0.0){
|
|
||||||
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
|
||||||
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
|
||||||
vec2 diff = ofactor/intfactor;
|
|
||||||
float scan = mix(diff.y, diff.x, TATE);
|
|
||||||
texcoord = Overscan(texcoord, scan, scan);
|
|
||||||
if (IOS == 1.0 || IOS == 3.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
|
||||||
texcoord = Overscan(texcoord, factor, factor);
|
|
||||||
vec2 pos = Warp(texcoord);
|
|
||||||
vec2 pos0 = Warp(TEX0.xy);
|
|
||||||
|
|
||||||
bool notate = (TATE < 0.5);
|
|
||||||
bool smarte = (smart_ei > 0.0 && notate); // smart edge interpolation on / off
|
|
||||||
|
|
||||||
vec2 coffset = vec2(0.5, 0.5);
|
|
||||||
|
|
||||||
vec2 ps = SourceSize.zw;
|
|
||||||
vec2 OGL2Pos = pos * SourceSize.xy - coffset;
|
|
||||||
vec2 fp = fract(OGL2Pos);
|
|
||||||
|
|
||||||
vec2 dx = vec2(ps.x,0.0);
|
|
||||||
vec2 dy = vec2(0.0, ps.y);
|
|
||||||
|
|
||||||
// Reading the texels
|
|
||||||
vec2 x2 = 2.0*dx;
|
|
||||||
vec2 y2 = 2.0*dy;
|
|
||||||
|
|
||||||
vec2 offx = dx;
|
|
||||||
vec2 off2 = x2;
|
|
||||||
vec2 offy = dy;
|
|
||||||
float fpx = fp.x;
|
|
||||||
if(!notate)
|
|
||||||
{
|
|
||||||
offx = dy;
|
|
||||||
off2 = y2;
|
|
||||||
offy = dx;
|
|
||||||
fpx = fp.y;
|
|
||||||
}
|
|
||||||
float f = (notate) ? fp.y : fp.x;
|
|
||||||
|
|
||||||
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
|
|
||||||
|
|
||||||
if (interb) pC4.y = pos.y - inters * SourceSize.w;
|
|
||||||
|
|
||||||
float zero = exp2(-h_sharp);
|
|
||||||
float sharp1 = s_sharp * zero;
|
|
||||||
|
|
||||||
float wl3 = 2.0 + fpx;
|
|
||||||
float wl2 = 1.0 + fpx;
|
|
||||||
float wl1 = fpx;
|
|
||||||
float wr1 = 1.0 - fpx;
|
|
||||||
float wr2 = 2.0 - fpx;
|
|
||||||
float wr3 = 3.0 - fpx;
|
|
||||||
|
|
||||||
wl3*=wl3; wl3 = exp2(-h_sharp*wl3);
|
|
||||||
wl2*=wl2; wl2 = exp2(-h_sharp*wl2);
|
|
||||||
wl1*=wl1; wl1 = exp2(-h_sharp*wl1);
|
|
||||||
wr1*=wr1; wr1 = exp2(-h_sharp*wr1);
|
|
||||||
wr2*=wr2; wr2 = exp2(-h_sharp*wr2);
|
|
||||||
wr3*=wr3; wr3 = exp2(-h_sharp*wr3);
|
|
||||||
|
|
||||||
float fp1 = 1.-fpx;
|
|
||||||
|
|
||||||
float wnorm = max(wl1, wr1);
|
|
||||||
|
|
||||||
float twl3 = max(wl3 - sharp1, 0.0);
|
|
||||||
float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1)); float swl2 = max(twl2, 0.0);
|
|
||||||
float twl1 = max(wl1 - sharp1, 0.0);
|
|
||||||
float twr1 = max(wr1 - sharp1, 0.0);
|
|
||||||
float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx)); float swr2 = max(twr2, 0.0);
|
|
||||||
float twr3 = max(wr3 - sharp1, 0.0);
|
|
||||||
|
|
||||||
bool sharp = (sharp1 > 0.0);
|
|
||||||
|
|
||||||
float rwl3, rwl2, rwr2;
|
|
||||||
|
|
||||||
float rwl1 = twl1;
|
|
||||||
float rwr1 = twr1;
|
|
||||||
vec3 c1, c2;
|
|
||||||
|
|
||||||
if (smarte)
|
|
||||||
{
|
|
||||||
rwl3 = wl3; rwl2 = wl2;
|
|
||||||
rwl1 = wl1; rwr1 = wr1;
|
|
||||||
rwr2 = wr2;
|
|
||||||
twl3 = 0.0; twr3 = 0.0;
|
|
||||||
vec3 t = COMPAT_TEXTURE(AvgLumPass, pC4 - offy).xyz;
|
|
||||||
vec3 a = COMPAT_TEXTURE(AvgLumPass, pC4 ).xyz;
|
|
||||||
vec3 b = COMPAT_TEXTURE(AvgLumPass, pC4 + offy).xyz;
|
|
||||||
vec3 d = COMPAT_TEXTURE(AvgLumPass, pC4 +dy+dy).xyz;
|
|
||||||
c1 = (h_sharp > 2.6) ? a : min(a,(t + a + b)/3.0); c1 = max(c1 - sth, 0.0);
|
|
||||||
c2 = (h_sharp > 2.6) ? b : min(b,(a + b + d)/3.0); c2 = max(c2 - sth, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float wts = 1.0/(swl2 + rwl1 + rwr1 + swr2);
|
|
||||||
|
|
||||||
vec3 l3, l2, l1, r1, r2, r3, sl2, sl1, sr1, sr2, color1, color2, color0, ct, colmin, colmax;
|
|
||||||
|
|
||||||
l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).rgb;
|
|
||||||
l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb;
|
|
||||||
l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb;
|
|
||||||
r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb;
|
|
||||||
r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).rgb;
|
|
||||||
r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+off2).rgb;
|
|
||||||
|
|
||||||
sl2 = l2*l2*l2; sl2*=sl2;
|
|
||||||
sl1 = l1*l1*l1; sl1*=sl1;
|
|
||||||
sr1 = r1*r1*r1; sr1*=sr1;
|
|
||||||
sr2 = r2*r2*r2; sr2*=sr2;
|
|
||||||
|
|
||||||
colmin = min(min(l1,r1), min(l2,r2));
|
|
||||||
colmax = max(max(l1,r1), max(l2,r2));
|
|
||||||
|
|
||||||
if (smarte)
|
|
||||||
{
|
|
||||||
float pc = min(1.0 + smart_ei*c1.y, ei_limit);
|
|
||||||
float pl = min(1.0 + smart_ei*max(c1.y,c1.x), ei_limit);
|
|
||||||
float pr = min(1.0 + smart_ei*max(c1.y,c1.z), ei_limit);
|
|
||||||
twl1 = pow(rwl1, pc); twr1 = pow(rwr1, pc);
|
|
||||||
twl2 = pow(rwl2, pl); twr2 = pow(rwr2, pr);
|
|
||||||
float wmax = max(twl1, twr1);
|
|
||||||
float sharp_ei = s_sharp*pow(zero, pc)/wmax;
|
|
||||||
twl2 = max(twl2/wmax - sharp_ei, mix(-0.15, 0.0, 1.0-fp1*fp1));
|
|
||||||
twl1 = max(twl1/wmax - sharp_ei, 0.0);
|
|
||||||
twr1 = max(twr1/wmax - sharp_ei, 0.0);
|
|
||||||
twr2 = max(twr2/wmax - sharp_ei, mix(-0.15, 0.0, 1.0-fpx*fpx));
|
|
||||||
}
|
|
||||||
color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
|
||||||
|
|
||||||
if (sharp) color1 = clamp(color1, colmin, colmax);
|
|
||||||
|
|
||||||
|
|
||||||
vec3 gtmp = vec3(1.0/6.0);
|
|
||||||
vec3 scolor1 = color1;
|
|
||||||
|
|
||||||
scolor1 = (sl2*swl2 + sl1*rwl1 + sr1*rwr1 + sr2*swr2)*wts;
|
|
||||||
scolor1 = pow(scolor1, gtmp); vec3 mcolor1 = scolor1;
|
|
||||||
scolor1 = min(mix(color1, scolor1, spike),1.0);
|
|
||||||
|
|
||||||
vec3 scolor2, mcolor2;
|
|
||||||
|
|
||||||
if (interb) pC4.y = pos.y + inters * SourceSize.w; else
|
|
||||||
pC4+=offy;
|
|
||||||
|
|
||||||
l3 = COMPAT_TEXTURE(LinearizePass, pC4 -off2).rgb;
|
|
||||||
l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb;
|
|
||||||
l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb;
|
|
||||||
r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb;
|
|
||||||
r2 = COMPAT_TEXTURE(LinearizePass, pC4 +off2).rgb;
|
|
||||||
r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+off2).rgb;
|
|
||||||
|
|
||||||
sl2 = l2*l2*l2; sl2*=sl2;
|
|
||||||
sl1 = l1*l1*l1; sl1*=sl1;
|
|
||||||
sr1 = r1*r1*r1; sr1*=sr1;
|
|
||||||
sr2 = r2*r2*r2; sr2*=sr2;
|
|
||||||
|
|
||||||
colmin = min(min(l1,r1), min(l2,r2));
|
|
||||||
colmax = max(max(l1,r1), max(l2,r2));
|
|
||||||
|
|
||||||
if (smarte)
|
|
||||||
{
|
|
||||||
float pc = min(1.0 + smart_ei*c2.y, ei_limit);
|
|
||||||
float pl = min(1.0 + smart_ei*max(c2.y,c2.x), ei_limit);
|
|
||||||
float pr = min(1.0 + smart_ei*max(c2.y,c2.z), ei_limit);
|
|
||||||
twl1 = pow(rwl1, pc); twr1 = pow(rwr1, pc);
|
|
||||||
twl2 = pow(rwl2, pl); twr2 = pow(rwr2, pr);
|
|
||||||
float wmax = max(twl1, twr1);
|
|
||||||
float sharp_ei = s_sharp*pow(zero, pc)/wmax;
|
|
||||||
twl2 = max(twl2/wmax - sharp_ei, mix(-0.15, 0.0, 1.0-fp1*fp1));
|
|
||||||
twl1 = max(twl1/wmax - sharp_ei, 0.0);
|
|
||||||
twr1 = max(twr1/wmax - sharp_ei, 0.0);
|
|
||||||
twr2 = max(twr2/wmax - sharp_ei, mix(-0.15, 0.0, 1.0-fpx*fpx));
|
|
||||||
}
|
|
||||||
color2 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
|
||||||
|
|
||||||
if (sharp) color2 = clamp(color2, colmin, colmax);
|
|
||||||
|
|
||||||
scolor2 = color2;
|
|
||||||
scolor2 = (sl2*swl2 + sl1*rwl1 + sr1*rwr1 + sr2*swr2)*wts;
|
|
||||||
scolor2 = pow(scolor2, gtmp); mcolor2 = scolor2;
|
|
||||||
scolor2 = min(mix(color2, scolor2, spike),1.0);
|
|
||||||
|
|
||||||
// calculating scanlines
|
|
||||||
|
|
||||||
vec3 ctmp; vec3 mcolor; float w3; vec3 color;
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
|
|
||||||
if (!interb)
|
|
||||||
{
|
|
||||||
float shape1 = mix(scanline1, scanline2, f);
|
|
||||||
float shape2 = mix(scanline1, scanline2, 1.0-f);
|
|
||||||
|
|
||||||
float wt1 = st(f);
|
|
||||||
float wt2 = st(1.0-f);
|
|
||||||
|
|
||||||
vec3 color00 = color1*wt1 + color2*wt2;
|
|
||||||
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
|
||||||
mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2);
|
|
||||||
|
|
||||||
ctmp = color00/(wt1+wt2);
|
|
||||||
vec3 sctmp = scolor0/(wt1+wt2);
|
|
||||||
|
|
||||||
float wf1, wf2;
|
|
||||||
|
|
||||||
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b);
|
|
||||||
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b);
|
|
||||||
|
|
||||||
float f1 = f;
|
|
||||||
float f2 = 1.0-f;
|
|
||||||
|
|
||||||
if (gsl == 0.0) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else
|
|
||||||
if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else
|
|
||||||
if (gsl == 2.0) { wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);}
|
|
||||||
|
|
||||||
if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; }
|
|
||||||
|
|
||||||
// Scanline darken 'edges' effect - need to uncomment it.
|
|
||||||
|
|
||||||
// float ws1 = max(wf1 - scansub, 0.2*wf1*wf2); wf1 = ws1/(1.0 - wf1 + ws1);
|
|
||||||
// float ws2 = max(wf2 - scansub, 0.2*wf2*wf1); wf2 = ws2/(1.0 - wf2 + ws2);
|
|
||||||
|
|
||||||
// Scanline saturation application
|
|
||||||
|
|
||||||
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
|
||||||
|
|
||||||
cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001);
|
|
||||||
cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001);
|
|
||||||
|
|
||||||
w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1);
|
|
||||||
w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2);
|
|
||||||
|
|
||||||
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
|
||||||
|
|
||||||
float v_high1 = 1.0 + 0.3*vm;
|
|
||||||
float v_high2 = 1.0 + 0.6*vm;
|
|
||||||
float v_low = 1.0 - vm;
|
|
||||||
|
|
||||||
float ds1 = min(pow(2.0*f1 + 0.01, f2), 1.0);
|
|
||||||
float ds2 = min(pow(2.0*f2 + 0.01, f1), 1.0);
|
|
||||||
|
|
||||||
if (vertmask < 0.0)
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1);
|
|
||||||
cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2);
|
|
||||||
}
|
|
||||||
|
|
||||||
color = gc(color1)*w1*cd1 + gc(color2)*w2*cd2;
|
|
||||||
color = min(color, 1.0);
|
|
||||||
w3 = wf1+wf2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interb)
|
|
||||||
{
|
|
||||||
color = gc(0.5*(color1+color2));
|
|
||||||
mcolor = vec3(max(max(color.r,color.g), color.b));
|
|
||||||
}
|
|
||||||
|
|
||||||
float mx = max(max(mcolor.r,mcolor.g),mcolor.b);
|
|
||||||
mx = pow(mx, 1.40/gamma_in);
|
|
||||||
|
|
||||||
// Apply Mask
|
|
||||||
|
|
||||||
vec3 orig1 = color;
|
|
||||||
vec3 cmask = one;
|
|
||||||
|
|
||||||
float smask = (notate) ? SlotMask(gl_FragCoord.xy * 1.000001, mx) : SlotMask(gl_FragCoord.yx * 1.000001, mx);
|
|
||||||
|
|
||||||
cmask*= (notate) ? Mask(gl_FragCoord.xy * 1.000001, mx) : Mask(gl_FragCoord.yx * 1.000001, mx);
|
|
||||||
|
|
||||||
color = pow(color, vec3(mask_gamma/gamma_in));
|
|
||||||
color = color*cmask;
|
|
||||||
color = min(color,1.0);
|
|
||||||
color = color*smask;
|
|
||||||
color = pow(color, vec3(gamma_in/mask_gamma));
|
|
||||||
|
|
||||||
cmask = min(cmask*smask, 1.0);
|
|
||||||
|
|
||||||
if (interb) ctmp = color;
|
|
||||||
float colmx = pow( max( max(ctmp.r, ctmp.g), ctmp.b), 1.40/gamma_out);
|
|
||||||
float bb = mix(brightboost, brightboost1, colmx);
|
|
||||||
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
|
||||||
color*=bb;
|
|
||||||
|
|
||||||
vec3 Glow = COMPAT_TEXTURE(GlowPass, pos ).rgb;
|
|
||||||
vec3 Bloom = COMPAT_TEXTURE(BloomPass, pos ).rgb;
|
|
||||||
|
|
||||||
vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0));
|
|
||||||
color = color + bloom*Bloom1;
|
|
||||||
|
|
||||||
color = min(color, mix(one, cmask, mclip));
|
|
||||||
if (!interb) color = declip(color, pow(w3,0.6));
|
|
||||||
|
|
||||||
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
|
||||||
color = color + 0.5*glow*Glow;
|
|
||||||
|
|
||||||
color = color + 0.5*(Bloom+Bloom*Bloom)*halation;
|
|
||||||
|
|
||||||
float gmo = 1.0/gamma_out;
|
|
||||||
if (interb) gmo = gmo / 0.70;
|
|
||||||
|
|
||||||
color = pow(color, vec3(gmo));
|
|
||||||
|
|
||||||
FragColor = vec4(color*corner(pos0), float(!notate));
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - Dr. Venom - Deconvergence pass
|
|
||||||
|
|
||||||
Copyright (C) 2021 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float deconr;
|
|
||||||
float decons;
|
|
||||||
float cswitch;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter bogus_hdeconvergence "[ HORIZONTAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0
|
|
||||||
#pragma parameter deconr " Hor. Deconvergence Color/Range" 0.0 -12.0 12.0 0.5
|
|
||||||
#define deconr params.deconr // Horizontal deconvergence colors range
|
|
||||||
#pragma parameter decons " Horizontal Deconvergence Strength" 0.5 0.0 1.0 0.05
|
|
||||||
#define decons params.decons // Horizontal deconvergence colors strength
|
|
||||||
#pragma parameter cswitch " Switch Deconvergence Colors" 1.0 -1.0 1.0 2.0
|
|
||||||
#define cswitch params.cswitch // Switch colors left/right
|
|
||||||
|
|
||||||
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 AvgLumPass;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
vec3 plant (vec3 tar, float r)
|
|
||||||
{
|
|
||||||
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
|
||||||
return tar * r / t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
|
|
||||||
vec3 color = COMPAT_TEXTURE(Source, vTexCoord).rgb;
|
|
||||||
vec3 result = color;
|
|
||||||
|
|
||||||
if (abs(deconr) > 0.5)
|
|
||||||
{
|
|
||||||
float step = cswitch/1920.0;
|
|
||||||
|
|
||||||
vec2 dx = vec2(step, 0.0);
|
|
||||||
|
|
||||||
float shift = step * abs(deconr);
|
|
||||||
vec4 coords = vec4(shift, -shift, 0.0, -0.5*shift);
|
|
||||||
|
|
||||||
vec2 rc = coords.rb;
|
|
||||||
vec2 gc = coords.gb;
|
|
||||||
vec2 bc = coords.rb;
|
|
||||||
|
|
||||||
if (deconr < -0.05) { rc = coords.rb; gc = coords.ab; bc = coords.gb; }
|
|
||||||
|
|
||||||
float TATE = round(COMPAT_TEXTURE(Source, vec2(0.5)).a);
|
|
||||||
|
|
||||||
if (TATE > 0.5)
|
|
||||||
{
|
|
||||||
rc = -rc.yx; gc = -gc.yx, bc = -bc.yx; dx = -dx.yx;
|
|
||||||
}
|
|
||||||
|
|
||||||
float r1 = COMPAT_TEXTURE(Source, vTexCoord + rc).r;
|
|
||||||
float g1 = COMPAT_TEXTURE(Source, vTexCoord + gc).g;
|
|
||||||
float b1 = COMPAT_TEXTURE(Source, vTexCoord + bc).b;
|
|
||||||
|
|
||||||
float r2 = COMPAT_TEXTURE(Source, vTexCoord + rc -dx).r;
|
|
||||||
float g2 = COMPAT_TEXTURE(Source, vTexCoord + gc -dx).g;
|
|
||||||
float b2 = COMPAT_TEXTURE(Source, vTexCoord + bc -dx).b;
|
|
||||||
|
|
||||||
float r3 = COMPAT_TEXTURE(Source, vTexCoord + rc +dx).r;
|
|
||||||
float g3 = COMPAT_TEXTURE(Source, vTexCoord + gc +dx).g;
|
|
||||||
float b3 = COMPAT_TEXTURE(Source, vTexCoord + bc +dx).b;
|
|
||||||
|
|
||||||
vec3 result1 = vec3(r1,g1,b1);
|
|
||||||
vec3 result2 = vec3(r2,g2,b2);
|
|
||||||
vec3 result3 = vec3(r3,g3,b3);
|
|
||||||
|
|
||||||
result1 = mix(color, result1, decons);
|
|
||||||
result2 = mix(color, result2, decons);
|
|
||||||
result3 = mix(color, result3, decons);
|
|
||||||
result = (result1+result2+result3)/3.0;
|
|
||||||
result = plant(result, 0.5*(max(max(color.r,color.g),color.b)+max(max(result.r,result.g),result.b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
FragColor = vec4(result, 1.0);
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Gaussian blur - horizontal pass, dynamic range, resizable
|
|
||||||
|
|
||||||
Copyright (C) 2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma format R16G16B16A16_SFLOAT
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 LinearizePassSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float SIZEH;
|
|
||||||
float SIGMA_H;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter bogus_glow "[ GLOW/BLOOM PASS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter SIZEH " H. Glow Radius" 5.0 1.0 30.0 1.0
|
|
||||||
#define SIZEH params.SIZEH
|
|
||||||
|
|
||||||
#pragma parameter SIGMA_H " Horizontal Glow Sigma" 1.25 0.5 15.0 0.10
|
|
||||||
#define SIGMA_H params.SIGMA_H
|
|
||||||
|
|
||||||
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 LinearizePass;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
float invsqrsigma = 1.0/(2.0*SIGMA_H*SIGMA_H);
|
|
||||||
|
|
||||||
float gaussian(float x)
|
|
||||||
{
|
|
||||||
return exp(-x*x*invsqrsigma);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 SourceSize1 = params.OriginalSize;
|
|
||||||
float f = fract(SourceSize1.x * vTexCoord.x);
|
|
||||||
f = 0.5 - f;
|
|
||||||
vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw;
|
|
||||||
vec3 color = vec3(0.0);
|
|
||||||
vec2 dx = vec2(SourceSize1.z, 0.0);
|
|
||||||
|
|
||||||
float w;
|
|
||||||
float wsum = 0.0;
|
|
||||||
vec3 pixel;
|
|
||||||
float n = -SIZEH;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx).rgb;
|
|
||||||
w = gaussian(n+f);
|
|
||||||
color = color + w * pixel;
|
|
||||||
wsum = wsum + w;
|
|
||||||
n = n + 1.0;
|
|
||||||
|
|
||||||
} while (n <= SIZEH);
|
|
||||||
|
|
||||||
color = color / wsum;
|
|
||||||
|
|
||||||
FragColor = vec4(color, 1.0);
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Gaussian blur - vertical pass, dynamic range, resizable
|
|
||||||
|
|
||||||
Copyright (C) 2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma format R16G16B16A16_SFLOAT
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float SIZEV;
|
|
||||||
float SIGMA_V;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter SIZEV " V. Glow Radius" 5.0 1.0 30.0 1.0
|
|
||||||
#define SIZEV params.SIZEV
|
|
||||||
|
|
||||||
#pragma parameter SIGMA_V " Vertical Glow Sigma" 1.25 0.5 15.0 0.10
|
|
||||||
#define SIGMA_V params.SIGMA_V
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
float invsqrsigma = 1.0/(2.0*SIGMA_V*SIGMA_V);
|
|
||||||
|
|
||||||
float gaussian(float x)
|
|
||||||
{
|
|
||||||
return exp(-x*x*invsqrsigma);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec4 SourceSize1 = params.SourceSize;
|
|
||||||
float f = fract(SourceSize1.y * vTexCoord.y);
|
|
||||||
f = 0.5 - f;
|
|
||||||
vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw;
|
|
||||||
vec3 color = vec3(0.0);
|
|
||||||
vec2 dy = vec2(0.0, SourceSize1.w);
|
|
||||||
|
|
||||||
float w;
|
|
||||||
float wsum = 0.0;
|
|
||||||
vec3 pixel;
|
|
||||||
float n = -SIZEV;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
pixel = COMPAT_TEXTURE(Source, tex + n*dy).rgb;
|
|
||||||
w = gaussian(n+f);
|
|
||||||
color = color + w * pixel;
|
|
||||||
wsum = wsum + w;
|
|
||||||
n = n + 1.0;
|
|
||||||
|
|
||||||
} while (n <= SIZEV);
|
|
||||||
|
|
||||||
color = color / wsum;
|
|
||||||
|
|
||||||
FragColor = vec4(color, 1.0);
|
|
||||||
}
|
|
|
@ -1,163 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Interlacing
|
|
||||||
|
|
||||||
Copyright (C) 2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma format R32G32B32A32_SFLOAT
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float decon;
|
|
||||||
float deconstr;
|
|
||||||
float GAMMA_INPUT;
|
|
||||||
float inter;
|
|
||||||
float interm;
|
|
||||||
float intres;
|
|
||||||
float inters;
|
|
||||||
float iscan;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05
|
|
||||||
#define GAMMA_INPUT params.GAMMA_INPUT
|
|
||||||
|
|
||||||
#pragma parameter bogus_deconvergence "[ HORIZONTAL DECONVERGENCE ]:" 0.0 0.0 1.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter decon " Horizontal Deconvergence Range" 1.0 -8.0 8.0 0.250
|
|
||||||
#define decon params.decon // Horizontal deconvergence range
|
|
||||||
|
|
||||||
#pragma parameter deconstr " Horizontal Deconvergence Strength" 0.0 0.0 1.0 0.05
|
|
||||||
#define deconstr params.deconstr // Horizontal deconvergence strength
|
|
||||||
|
|
||||||
#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter inter " Interlace Trigger Resolution :" 350.0 0.0 800.0 25.0
|
|
||||||
#define inter params.inter // interlace resolution
|
|
||||||
|
|
||||||
#pragma parameter interm " Interlace Mode: OFF, Normal 1-3, Interpolation 4-5" 1.0 0.0 5.0 1.0
|
|
||||||
#define interm params.interm // interlace mode
|
|
||||||
#define interm params.interm // interlace mode
|
|
||||||
|
|
||||||
#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // Joint parameter with main pass, values must match
|
|
||||||
#define inters params.inters // interlacing effect smoothing
|
|
||||||
|
|
||||||
#pragma parameter iscan " Interlacing Scanline Effect" 0.20 0.0 1.0 0.05
|
|
||||||
#define iscan params.iscan // interlacing effect scanlining
|
|
||||||
|
|
||||||
#pragma parameter intres " Internal Resolution: 1.0:240p, 1.5...y-dowsample" 0.0 0.0 4.0 0.5 // Joint parameter with main pass, values must match
|
|
||||||
#define intres params.intres // interlace resolution
|
|
||||||
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
|
|
||||||
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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma stage fragment
|
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
|
||||||
layout(location = 0) out vec4 FragColor;
|
|
||||||
layout(set = 0, binding = 2) uniform sampler2D PrePass;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
|
|
||||||
vec3 plant (vec3 tar, float r)
|
|
||||||
{
|
|
||||||
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
|
||||||
return tar * r / t;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 dx1 = vec2(1.0/SourceSize.x, 0.0)*decon;
|
|
||||||
vec2 dx2 = -dx1*decon;
|
|
||||||
vec2 dy = vec2(0.0, 1.0/SourceSize.y);
|
|
||||||
|
|
||||||
vec3 c1 = COMPAT_TEXTURE(PrePass, vTexCoord).rgb;
|
|
||||||
vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + dy).rgb;
|
|
||||||
|
|
||||||
float r1 = COMPAT_TEXTURE(PrePass, vTexCoord + dx1).r;
|
|
||||||
float b1 = COMPAT_TEXTURE(PrePass, vTexCoord + dx2).b;
|
|
||||||
float r2 = COMPAT_TEXTURE(PrePass, vTexCoord + dx1 + dy).r;
|
|
||||||
float b2 = COMPAT_TEXTURE(PrePass, vTexCoord + dx2 + dy).b;
|
|
||||||
|
|
||||||
vec3 res1 = c1;
|
|
||||||
vec3 res2 = c2;
|
|
||||||
|
|
||||||
res1.rb = mix(c1.rb, vec2(r1,b1), deconstr);
|
|
||||||
res2.rb = mix(c2.rb, vec2(r2,b2), deconstr);
|
|
||||||
|
|
||||||
vec3 res = res1;
|
|
||||||
float gamma_in = 1.0/GAMMA_INPUT;
|
|
||||||
float intera = 1.0;
|
|
||||||
|
|
||||||
float yres_div = 1.0; if (intres > 1.25) yres_div = intres;
|
|
||||||
|
|
||||||
if (inter < SourceSize.y/yres_div && interm > 0.5 && intres != 1.0)
|
|
||||||
{
|
|
||||||
intera = 0.5;
|
|
||||||
float line_no = floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0));
|
|
||||||
float frame_no = floor(mod(float(params.FrameCount),2.0));
|
|
||||||
float ii = abs(line_no-frame_no);
|
|
||||||
|
|
||||||
float m1 = max(max(c1.r,c1.g),c1.b);
|
|
||||||
float m2 = max(max(c2.r,c2.g),c2.b);
|
|
||||||
vec3 df = abs(c1-c2);
|
|
||||||
|
|
||||||
float d = max(max(df.r,df.g),df.b);
|
|
||||||
if (interm == 2.0) d = mix(0.1*d,10.0*d, step(m1/(m2+0.0001),m2/(m1+0.0001)));
|
|
||||||
|
|
||||||
float r;
|
|
||||||
|
|
||||||
if (interm < 3.5)
|
|
||||||
{
|
|
||||||
r = max(m1*ii, (1.0-iscan)*min(m1,m2));
|
|
||||||
res = plant( mix(mix(res1,res2, min(mix(m1, (1.0-m2), min(m1,1.0-m1))/(d+0.00001),1.0)), res1, ii), r);
|
|
||||||
if (interm == 3.0) res = (1.0-0.5*iscan)*mix(res2, res1, ii);
|
|
||||||
intera = 0.0;
|
|
||||||
}
|
|
||||||
if (interm == 5.0) { res = mix(res2, res1, 0.5); intera = 0.5; }
|
|
||||||
|
|
||||||
res = pow(res, vec3(GAMMA_INPUT*0.70));
|
|
||||||
gamma_in = 1.0/(GAMMA_INPUT*0.70);
|
|
||||||
}
|
|
||||||
else res = pow(res, vec3(GAMMA_INPUT));
|
|
||||||
|
|
||||||
if (vTexCoord.x > 0.5) gamma_in = intera;
|
|
||||||
|
|
||||||
FragColor = vec4(res, gamma_in);
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Interlacing
|
|
||||||
|
|
||||||
Copyright (C) 2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma format R32G32B32A32_SFLOAT
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
vec4 SourceSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float GAMMA_INPUT;
|
|
||||||
float inter;
|
|
||||||
float interm;
|
|
||||||
float inters;
|
|
||||||
float iscan;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05
|
|
||||||
#define GAMMA_INPUT params.GAMMA_INPUT
|
|
||||||
|
|
||||||
#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0
|
|
||||||
|
|
||||||
#pragma parameter inter " Interlace Trigger Resolution :" 350.0 0.0 800.0 25.0
|
|
||||||
#define inter params.inter // interlace resolution
|
|
||||||
|
|
||||||
#pragma parameter interm " Interlace Mode: OFF, Normal 1-3, Interpolation 4-5" 1.0 0.0 5.0 1.0
|
|
||||||
#define interm params.interm // interlace mode
|
|
||||||
|
|
||||||
#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // // Joint parameter with main pass, values must match
|
|
||||||
#define inters params.inters // interlacing effect smoothing
|
|
||||||
|
|
||||||
#pragma parameter iscan " Interlacing Scanline Effect" 0.20 0.0 1.0 0.05
|
|
||||||
#define iscan params.iscan // interlacing effect scanlining
|
|
||||||
|
|
||||||
|
|
||||||
#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.000001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma stage fragment
|
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
|
||||||
layout(location = 0) out vec4 FragColor;
|
|
||||||
layout(set = 0, binding = 2) uniform sampler2D PrePass;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
|
|
||||||
|
|
||||||
vec3 plant (vec3 tar, float r)
|
|
||||||
{
|
|
||||||
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
|
||||||
return tar * r / t;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec3 c1 = COMPAT_TEXTURE(PrePass, vTexCoord).rgb;
|
|
||||||
vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + vec2(0.0, 1.0/params.OriginalSize.y)).rgb;
|
|
||||||
vec3 c = c1;
|
|
||||||
|
|
||||||
float intera = 1.0;
|
|
||||||
float gamma_in = 1.0/GAMMA_INPUT;
|
|
||||||
|
|
||||||
if (inter < params.OriginalSize.y && interm > 0.5)
|
|
||||||
{
|
|
||||||
intera = 0.5;
|
|
||||||
float line_no = floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0));
|
|
||||||
float frame_no = floor(mod(float(params.FrameCount),2.0));
|
|
||||||
float ii = abs(line_no-frame_no);
|
|
||||||
|
|
||||||
float m1 = max(max(c1.r,c1.g),c1.b);
|
|
||||||
float m2 = max(max(c2.r,c2.g),c2.b);
|
|
||||||
vec3 df = abs(c1-c2);
|
|
||||||
|
|
||||||
float d = max(max(df.r,df.g),df.b);
|
|
||||||
if (interm == 2.0) d = mix(0.1*d,10.0*d, step(m1/(m2+0.0001),m2/(m1+0.0001)));
|
|
||||||
|
|
||||||
float r;
|
|
||||||
|
|
||||||
if (interm < 3.5)
|
|
||||||
{
|
|
||||||
r = max(m1*ii, (1.0-iscan)*min(m1,m2));
|
|
||||||
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
|
||||||
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
|
||||||
intera = 0.0;
|
|
||||||
}
|
|
||||||
if (interm == 5.0) { c = mix(c2, c1, 0.5); intera = 0.5; }
|
|
||||||
|
|
||||||
c = pow(c, vec3(GAMMA_INPUT*0.70));
|
|
||||||
gamma_in = 1.0/(GAMMA_INPUT*0.70);
|
|
||||||
}
|
|
||||||
else c = pow(c, vec3(GAMMA_INPUT));
|
|
||||||
|
|
||||||
if (vTexCoord.x > 0.5) gamma_in = intera;
|
|
||||||
|
|
||||||
FragColor = vec4(c, gamma_in);
|
|
||||||
}
|
|
|
@ -1,615 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - Dr. Venom
|
|
||||||
|
|
||||||
Copyright (C) 2018-2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float TATE, IOS, OS, BLOOM, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
|
||||||
h_sharp, s_sharp, csize, bsize, warpX, warpY, glow, shadowMask, masksize, vertmask,
|
|
||||||
slotmask, slotwidth, double_slot, mcut, maskDark, maskLight, CGWG, gamma_out, spike, inter;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float bloom;
|
|
||||||
float interm;
|
|
||||||
float scans;
|
|
||||||
float slotms;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
#pragma parameter TATE "TATE Mode" 0.0 0.0 1.0 1.0
|
|
||||||
#define TATE params.TATE // Screen orientation
|
|
||||||
#pragma parameter IOS "Smart Integer Scaling: 1.0:Y, 2.0:'X'+Y" 0.0 0.0 2.0 1.0
|
|
||||||
#define IOS params.IOS // Smart Integer Scaling
|
|
||||||
#pragma parameter OS "R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
|
|
||||||
#define OS params.OS // Do overscan
|
|
||||||
#pragma parameter BLOOM "Raster bloom %" 0.0 0.0 20.0 1.0
|
|
||||||
#define BLOOM params.BLOOM // Bloom overscan percentage
|
|
||||||
#pragma parameter brightboost "Bright Boost Dark Pixels" 1.40 0.50 4.00 0.05
|
|
||||||
#define brightboost params.brightboost // adjust brightness
|
|
||||||
#pragma parameter brightboost1 "Bright Boost Bright Pixels" 1.15 0.50 3.00 0.05
|
|
||||||
#define brightboost1 params.brightboost1 // adjust brightness
|
|
||||||
#pragma parameter gsl "Scanline Type" 0.0 0.0 2.0 1.0
|
|
||||||
#define gsl params.gsl // Alternate scanlines
|
|
||||||
#pragma parameter scanline1 "Scanline beam shape low" 6.0 1.0 15.0 1.0
|
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
|
||||||
#pragma parameter scanline2 "Scanline beam shape high" 8.0 5.0 23.0 1.0
|
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
|
||||||
#pragma parameter beam_min "Scanline dark" 1.35 0.5 2.5 0.05
|
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
|
||||||
#pragma parameter beam_max "Scanline bright" 1.05 0.5 2.5 0.05
|
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
|
||||||
#pragma parameter beam_size "Increased bright scanline beam" 0.70 0.0 1.0 0.05
|
|
||||||
#define beam_size params.beam_size // increased max. beam size
|
|
||||||
#pragma parameter h_sharp "Horizontal sharpness" 5.25 1.0 15.0 0.25
|
|
||||||
#define h_sharp params.h_sharp // pixel sharpness
|
|
||||||
#pragma parameter s_sharp "Substractive sharpness (relative)" 0.40 0.0 1.0 0.10
|
|
||||||
#define s_sharp params.s_sharp // substractive sharpness
|
|
||||||
#pragma parameter csize "Corner size" 0.0 0.0 0.07 0.01
|
|
||||||
#define csize params.csize // corner size
|
|
||||||
#pragma parameter bsize "Border smoothness" 600.0 100.0 600.0 25.0
|
|
||||||
#define bsize params.bsize // border smoothness
|
|
||||||
#pragma parameter warpX "CurvatureX (default 0.03)" 0.0 0.0 0.125 0.01
|
|
||||||
#define warpX params.warpX // Curvature X
|
|
||||||
#pragma parameter warpY "CurvatureY (default 0.04)" 0.0 0.0 0.125 0.01
|
|
||||||
#define warpY params.warpY // Curvature Y
|
|
||||||
#pragma parameter glow "Glow Strength" 0.02 0.0 0.5 0.01
|
|
||||||
#define glow params.glow // Glow Strength
|
|
||||||
#pragma parameter shadowMask "CRT Mask: 0:CGWG, 1-4:Lottes, 5-6:'Trinitron'" 0.0 -1.0 7.0 1.0
|
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
|
||||||
#pragma parameter masksize "CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.0 1.0
|
|
||||||
#define masksize params.masksize // Mask Size
|
|
||||||
#pragma parameter vertmask "PVM Like Colors" 0.0 -0.30 0.30 0.02
|
|
||||||
#define vertmask params.vertmask // Vertical mask
|
|
||||||
#pragma parameter slotmask "Slot Mask Strength" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask params.slotmask // Slot Mask ON/OFF
|
|
||||||
#pragma parameter slotwidth "Slot Mask Width" 2.0 1.0 6.0 0.5
|
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
|
||||||
#pragma parameter double_slot "Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
|
||||||
#pragma parameter slotms "Slot Mask Size" 1.0 1.0 2.0 1.0
|
|
||||||
#define slotms global.slotms // Slot Mask Size
|
|
||||||
#pragma parameter mcut "Mask 5-7 cutoff" 0.25 0.0 0.5 0.05
|
|
||||||
#define mcut params.mcut // Mask 5-7 cutoff
|
|
||||||
#pragma parameter maskDark "Lottes&Trinitron maskDark" 0.5 0.0 2.0 0.05
|
|
||||||
#define maskDark params.maskDark // Dark "Phosphor"
|
|
||||||
#pragma parameter maskLight "Lottes&Trinitron maskLight" 1.5 0.0 2.0 0.05
|
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
|
||||||
#pragma parameter CGWG "Mask 0&7 Mask Str." 0.3 0.0 1.0 0.05
|
|
||||||
#define CGWG params.CGWG // CGWG Mask Strength
|
|
||||||
#pragma parameter gamma_out "Gamma out" 2.4 1.0 3.5 0.05
|
|
||||||
#define gamma_out params.gamma_out // output gamma
|
|
||||||
#pragma parameter spike "Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
|
||||||
#define spike params.spike
|
|
||||||
#pragma parameter inter "Interlace Trigger Resolution :" 400.0 0.0 800.0 25.0
|
|
||||||
#define inter params.inter // interlace resolution
|
|
||||||
#pragma parameter interm "Interlace Mode (0.0 = OFF):" 1.0 0.0 3.0 1.0
|
|
||||||
#define interm global.interm // interlace mode
|
|
||||||
#pragma parameter bloom "Bloom Strength" 0.0 0.0 2.0 0.1
|
|
||||||
#define bloom global.bloom // bloom effect
|
|
||||||
#pragma parameter scans "Scanline 1&2 Saturation" 0.5 0.0 1.0 0.1
|
|
||||||
#define scans global.scans // scanline saturation
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
#define InputSize SourceSize
|
|
||||||
#define TextureSize SourceSize
|
|
||||||
|
|
||||||
#define SourceSize global.SourceSize
|
|
||||||
#define OutputSize global.OutputSize
|
|
||||||
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
|
||||||
|
|
||||||
#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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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 LinearizePass;
|
|
||||||
layout(set = 0, binding = 4) uniform sampler2D AvgLumPass;
|
|
||||||
layout(set = 0, binding = 5) uniform sampler2D GlowPass;
|
|
||||||
|
|
||||||
#define Texture Source
|
|
||||||
#define PassPrev5Texture AvgLumPass
|
|
||||||
#define PassPrev4Texture LinearizePass
|
|
||||||
#define PassPrev2Texture GlowPass
|
|
||||||
|
|
||||||
#define eps 1e-10
|
|
||||||
|
|
||||||
float st(float x)
|
|
||||||
{
|
|
||||||
return exp2(-10.0*x*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 sw0(vec3 x, vec3 color, float scanline)
|
|
||||||
{
|
|
||||||
vec3 tmp = mix(vec3(beam_min),vec3(beam_max), color);
|
|
||||||
vec3 ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 sw1(vec3 x, vec3 color, float scanline)
|
|
||||||
{
|
|
||||||
float mx = max(max(color.r, color.g),color.b);
|
|
||||||
x = mix (x, beam_min*x, max(x-0.4*mx,0.0));
|
|
||||||
vec3 tmp = mix(vec3(1.2*beam_min),vec3(beam_max), color);
|
|
||||||
vec3 ex = x*tmp;
|
|
||||||
float br = clamp(0.8*beam_min - 1.0, 0.2, 0.45);
|
|
||||||
vec3 res = exp2(-scanline*ex*ex)/(1.0-br+br*mx);
|
|
||||||
mx = max(max(res.r,res.g),res.b);
|
|
||||||
float scans1 = scans; if (abs(vertmask) > 0.01) scans1=1.0;
|
|
||||||
return mix(vec3(mx), res, scans1);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 sw2(vec3 x, vec3 color, float scanline)
|
|
||||||
{
|
|
||||||
float mx = max(max(color.r, color.g),color.b);
|
|
||||||
vec3 tmp = mix(vec3(2.5*beam_min),vec3(beam_max), color);
|
|
||||||
tmp = mix(vec3(beam_max), tmp, pow(abs(x), color+0.3));
|
|
||||||
vec3 ex = x*tmp;
|
|
||||||
vec3 res = exp2(-scanline*ex*ex)/(0.6 + 0.4*mx);
|
|
||||||
mx = max(max(res.r,res.g),res.b);
|
|
||||||
float scans1 = scans; if (abs(vertmask) > 0.01) scans1=0.85;
|
|
||||||
return mix(vec3(mx), res, scans1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shadow mask (1-4 from PD CRT Lottes shader).
|
|
||||||
vec3 Mask(vec2 pos, vec3 c)
|
|
||||||
{
|
|
||||||
pos = floor(pos/masksize);
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
|
||||||
|
|
||||||
// No mask
|
|
||||||
if (shadowMask == -1.0)
|
|
||||||
{
|
|
||||||
mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phosphor.
|
|
||||||
else if (shadowMask == 0.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x*0.5);
|
|
||||||
float mc = 1.0 - CGWG;
|
|
||||||
if (pos.x < 0.5) { mask.r = 1.1; mask.g = mc; mask.b = 1.1; }
|
|
||||||
else { mask.r = mc; mask.g = 1.1; mask.b = mc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very compressed TV style shadow mask.
|
|
||||||
else if (shadowMask == 1.0)
|
|
||||||
{
|
|
||||||
float line = maskLight;
|
|
||||||
float odd = 0.0;
|
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
|
||||||
odd = 1.0;
|
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
|
||||||
line = maskDark;
|
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
|
|
||||||
mask*=line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aperture-grille.
|
|
||||||
else if (shadowMask == 2.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stretched VGA style shadow mask (same as prior shaders).
|
|
||||||
else if (shadowMask == 3.0)
|
|
||||||
{
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA style shadow mask.
|
|
||||||
else if (shadowMask == 4.0)
|
|
||||||
{
|
|
||||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alternate mask 5
|
|
||||||
else if (shadowMask == 5.0)
|
|
||||||
{
|
|
||||||
float mx = max(max(c.r,c.g),c.b);
|
|
||||||
vec3 maskTmp = vec3( min( 1.25*max(mx-mcut,0.0)/(1.0-mcut) ,maskDark + 0.2*(1.0-maskDark)*mx));
|
|
||||||
float adj = 0.80*maskLight - 0.5*(0.80*maskLight - 1.0)*mx + 0.75*(1.0-mx);
|
|
||||||
mask = maskTmp;
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5)
|
|
||||||
{ mask.r = adj;
|
|
||||||
mask.b = adj;
|
|
||||||
}
|
|
||||||
else mask.g = adj;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alternate mask 6
|
|
||||||
else if (shadowMask == 6.0)
|
|
||||||
{
|
|
||||||
float mx = max(max(c.r,c.g),c.b);
|
|
||||||
vec3 maskTmp = vec3( min( 1.33*max(mx-mcut,0.0)/(1.0-mcut) ,maskDark + 0.225*(1.0-maskDark)*mx));
|
|
||||||
float adj = 0.80*maskLight - 0.5*(0.80*maskLight - 1.0)*mx + 0.75*(1.0-mx);
|
|
||||||
mask = maskTmp;
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
if (pos.x < 0.333) mask.r = adj;
|
|
||||||
else if (pos.x < 0.666) mask.g = adj;
|
|
||||||
else mask.b = adj;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alternate mask 7
|
|
||||||
else if (shadowMask == 7.0)
|
|
||||||
{
|
|
||||||
float mc = 1.0 - CGWG;
|
|
||||||
float mx = max(max(c.r,c.g),c.b);
|
|
||||||
float maskTmp = min(1.6*max(mx-mcut,0.0)/(1.0-mcut) , mc);
|
|
||||||
mask = vec3(maskTmp);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5) mask = vec3(1.0 + 0.6*(1.0-mx));
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SlotMask(vec2 pos, vec3 c)
|
|
||||||
{
|
|
||||||
if (slotmask == 0.0) return 1.0;
|
|
||||||
|
|
||||||
pos = floor(pos/slotms);
|
|
||||||
float mx = pow(max(max(c.r,c.g),c.b),1.33);
|
|
||||||
float mlen = slotwidth*2.0;
|
|
||||||
float px = fract(pos.x/mlen);
|
|
||||||
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
|
||||||
float slot_dark = mix(1.0-slotmask, 1.0-0.80*slotmask, mx);
|
|
||||||
float slot = 1.0 + 0.7*slotmask*(1.0-mx);
|
|
||||||
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
|
||||||
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Distortion of scanlines, and end of screen alpha (PD Lottes Curvature)
|
|
||||||
vec2 Warp(vec2 pos)
|
|
||||||
{
|
|
||||||
pos = pos*2.0-1.0;
|
|
||||||
pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY);
|
|
||||||
return pos*0.5 + 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Overscan(vec2 pos, float dx, float dy){
|
|
||||||
pos=pos*2.0-1.0;
|
|
||||||
pos*=vec2(dx,dy);
|
|
||||||
return pos*0.5+0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Borrowed from cgwg's crt-geom, under GPL
|
|
||||||
|
|
||||||
float corner(vec2 coord)
|
|
||||||
{
|
|
||||||
coord *= SourceSize.xy / InputSize.xy;
|
|
||||||
coord = (coord - vec2(0.5)) * 1.0 + vec2(0.5);
|
|
||||||
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
|
|
||||||
vec2 cdist = vec2(max(csize, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002)));
|
|
||||||
coord = (cdist - min(coord,cdist));
|
|
||||||
float dist = sqrt(dot(coord,coord));
|
|
||||||
return clamp((cdist.x-dist)*bsize,0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
float lum = COMPAT_TEXTURE(PassPrev5Texture, vec2(0.1,0.1)).a;
|
|
||||||
|
|
||||||
// Calculating texel coordinates
|
|
||||||
|
|
||||||
vec2 texcoord = TEX0.xy;
|
|
||||||
if (IOS > 0.0){
|
|
||||||
vec2 ofactor = OutputSize.xy/InputSize.xy;
|
|
||||||
vec2 intfactor = round(ofactor);
|
|
||||||
vec2 diff = ofactor/intfactor;
|
|
||||||
float scan = mix(diff.y, diff.x, TATE);
|
|
||||||
texcoord = Overscan(texcoord*(SourceSize.xy/InputSize.xy), scan, scan)*(InputSize.xy/SourceSize.xy);
|
|
||||||
if (IOS == 1.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
|
|
||||||
texcoord = Overscan(texcoord*(SourceSize.xy/InputSize.xy), factor, factor)*(InputSize.xy/SourceSize.xy);
|
|
||||||
vec2 pos = Warp(texcoord*(TextureSize.xy/InputSize.xy))*(InputSize.xy/TextureSize.xy);
|
|
||||||
vec2 pos0 = Warp(TEX0.xy*(TextureSize.xy/InputSize.xy))*(InputSize.xy/TextureSize.xy);
|
|
||||||
|
|
||||||
vec2 coffset = vec2(0.5, 0.5);
|
|
||||||
bool interb = (interm > 0.5 && interm < 2.5 && inter <= mix(SourceSize.y, SourceSize.x, TATE));
|
|
||||||
bool notate = (TATE < 0.5);
|
|
||||||
|
|
||||||
if (interb) coffset = ((notate) ? vec2(0.5,0.0) : vec2(0.0, 0.5));
|
|
||||||
|
|
||||||
vec2 ps = SourceSize.zw;
|
|
||||||
vec2 OGL2Pos = pos * SourceSize.xy - coffset;
|
|
||||||
vec2 fp = fract(OGL2Pos);
|
|
||||||
|
|
||||||
vec2 dx = vec2(ps.x,0.0);
|
|
||||||
vec2 dy = vec2(0.0, ps.y);
|
|
||||||
|
|
||||||
// Reading the texels
|
|
||||||
vec2 x2 = 2.0*dx;
|
|
||||||
vec2 y2 = 2.0*dy;
|
|
||||||
|
|
||||||
vec2 offx = dx;
|
|
||||||
vec2 off2 = x2;
|
|
||||||
vec2 offy = dy;
|
|
||||||
float fpx = fp.x;
|
|
||||||
if(!notate)
|
|
||||||
{
|
|
||||||
offx = dy;
|
|
||||||
off2 = y2;
|
|
||||||
offy = dx;
|
|
||||||
fpx = fp.y;
|
|
||||||
}
|
|
||||||
float f = (notate) ? fp.y : fp.x;
|
|
||||||
|
|
||||||
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
|
|
||||||
|
|
||||||
float zero = exp2(-h_sharp);
|
|
||||||
float sharp1 = s_sharp * zero;
|
|
||||||
|
|
||||||
float wl3 = 2.0 + fpx;
|
|
||||||
float wl2 = 1.0 + fpx;
|
|
||||||
float wl1 = fpx;
|
|
||||||
float wr1 = 1.0 - fpx;
|
|
||||||
float wr2 = 2.0 - fpx;
|
|
||||||
float wr3 = 3.0 - fpx;
|
|
||||||
|
|
||||||
wl3*=wl3; wl3 = exp2(-h_sharp*wl3);
|
|
||||||
wl2*=wl2; wl2 = exp2(-h_sharp*wl2);
|
|
||||||
wl1*=wl1; wl1 = exp2(-h_sharp*wl1);
|
|
||||||
wr1*=wr1; wr1 = exp2(-h_sharp*wr1);
|
|
||||||
wr2*=wr2; wr2 = exp2(-h_sharp*wr2);
|
|
||||||
wr3*=wr3; wr3 = exp2(-h_sharp*wr3);
|
|
||||||
|
|
||||||
float fp1 = 1.-fpx;
|
|
||||||
|
|
||||||
float twl3 = max(wl3 - sharp1, 0.0);
|
|
||||||
float twl2 = max(wl2 - sharp1, mix(0.0,mix(-0.18, -0.01, fpx),float(s_sharp > 0.05)));
|
|
||||||
float twl1 = max(wl1 - sharp1, 0.0);
|
|
||||||
float twr1 = max(wr1 - sharp1, 0.0);
|
|
||||||
float twr2 = max(wr2 - sharp1, mix(0.0,mix(-0.18, -0.01, fp1),float(s_sharp > 0.05)));
|
|
||||||
float twr3 = max(wr3 - sharp1, 0.0);
|
|
||||||
|
|
||||||
float wtt = 1.0/(twl3+twl2+twl1+twr1+twr2+twr3);
|
|
||||||
float wt = 1.0/(wl2+wl1+wr1+wr2);
|
|
||||||
bool sharp = (s_sharp > 0.05);
|
|
||||||
|
|
||||||
vec3 l3 = COMPAT_TEXTURE(PassPrev4Texture, pC4 -off2).xyz;
|
|
||||||
vec3 l2 = COMPAT_TEXTURE(PassPrev4Texture, pC4 -offx).xyz;
|
|
||||||
vec3 l1 = COMPAT_TEXTURE(PassPrev4Texture, pC4 ).xyz;
|
|
||||||
vec3 r1 = COMPAT_TEXTURE(PassPrev4Texture, pC4 +offx).xyz;
|
|
||||||
vec3 r2 = COMPAT_TEXTURE(PassPrev4Texture, pC4 +off2).xyz;
|
|
||||||
vec3 r3 = COMPAT_TEXTURE(PassPrev4Texture, pC4 +offx+off2).xyz;
|
|
||||||
|
|
||||||
vec3 sl2 = COMPAT_TEXTURE(Texture, pC4 -offx).xyz;
|
|
||||||
vec3 sl1 = COMPAT_TEXTURE(Texture, pC4 ).xyz;
|
|
||||||
vec3 sr1 = COMPAT_TEXTURE(Texture, pC4 +offx).xyz;
|
|
||||||
vec3 sr2 = COMPAT_TEXTURE(Texture, pC4 +off2).xyz;
|
|
||||||
|
|
||||||
vec3 color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)*wtt;
|
|
||||||
|
|
||||||
vec3 colmin = min(min(l1,r1), min(l2,r2));
|
|
||||||
vec3 colmax = max(max(l1,r1), max(l2,r2));
|
|
||||||
|
|
||||||
if (sharp) color1 = clamp(color1, colmin, colmax);
|
|
||||||
|
|
||||||
vec3 gtmp = vec3(gamma_out*0.1);
|
|
||||||
vec3 scolor1 = color1;
|
|
||||||
|
|
||||||
scolor1 = (sl2*wl2 + sl1*wl1 + sr1*wr1 + sr2*wr2)*wt;
|
|
||||||
scolor1 = pow(scolor1, gtmp); vec3 mcolor1 = scolor1;
|
|
||||||
scolor1 = mix(color1, scolor1, spike);
|
|
||||||
|
|
||||||
pC4+=offy;
|
|
||||||
|
|
||||||
l3 = COMPAT_TEXTURE(PassPrev4Texture, pC4 -off2).xyz;
|
|
||||||
l2 = COMPAT_TEXTURE(PassPrev4Texture, pC4 -offx).xyz;
|
|
||||||
l1 = COMPAT_TEXTURE(PassPrev4Texture, pC4 ).xyz;
|
|
||||||
r1 = COMPAT_TEXTURE(PassPrev4Texture, pC4 +offx).xyz;
|
|
||||||
r2 = COMPAT_TEXTURE(PassPrev4Texture, pC4 +off2).xyz;
|
|
||||||
r3 = COMPAT_TEXTURE(PassPrev4Texture, pC4 +offx+off2).xyz;
|
|
||||||
|
|
||||||
sl2 = COMPAT_TEXTURE(Texture, pC4 -offx).xyz;
|
|
||||||
sl1 = COMPAT_TEXTURE(Texture, pC4 ).xyz;
|
|
||||||
sr1 = COMPAT_TEXTURE(Texture, pC4 +offx).xyz;
|
|
||||||
sr2 = COMPAT_TEXTURE(Texture, pC4 +off2).xyz;
|
|
||||||
|
|
||||||
vec3 color2 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)*wtt;
|
|
||||||
|
|
||||||
colmin = min(min(l1,r1), min(l2,r2));
|
|
||||||
colmax = max(max(l1,r1), max(l2,r2));
|
|
||||||
|
|
||||||
if (sharp) color2 = clamp(color2, colmin, colmax);
|
|
||||||
|
|
||||||
vec3 scolor2 = color2;
|
|
||||||
|
|
||||||
scolor2 = (sl2*wl2 + sl1*wl1 + sr1*wr1 + sr2*wr2)*wt;
|
|
||||||
scolor2 = pow(scolor2, gtmp); vec3 mcolor2 = scolor2;
|
|
||||||
scolor2 = mix(color2, scolor2, spike);
|
|
||||||
|
|
||||||
vec3 color0 = color1;
|
|
||||||
|
|
||||||
if (interb)
|
|
||||||
{
|
|
||||||
pC4-= 2.*offy;
|
|
||||||
|
|
||||||
l3 = COMPAT_TEXTURE(PassPrev4Texture, pC4 -off2).xyz;
|
|
||||||
l2 = COMPAT_TEXTURE(PassPrev4Texture, pC4 -offx).xyz;
|
|
||||||
l1 = COMPAT_TEXTURE(PassPrev4Texture, pC4 ).xyz;
|
|
||||||
r1 = COMPAT_TEXTURE(PassPrev4Texture, pC4 +offx).xyz;
|
|
||||||
r2 = COMPAT_TEXTURE(PassPrev4Texture, pC4 +off2).xyz;
|
|
||||||
r3 = COMPAT_TEXTURE(PassPrev4Texture, pC4 +offx+off2).xyz;
|
|
||||||
|
|
||||||
color0 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)*wtt;
|
|
||||||
|
|
||||||
colmin = min(min(l1,r1), min(l2,r2));
|
|
||||||
colmax = max(max(l1,r1), max(l2,r2));
|
|
||||||
|
|
||||||
if (sharp) color0 = clamp(color0, colmin, colmax);
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculating scanlines
|
|
||||||
|
|
||||||
float shape1 = mix(scanline1, scanline2, f);
|
|
||||||
float shape2 = mix(scanline1, scanline2, 1.0-f);
|
|
||||||
|
|
||||||
float wt1 = st(f);
|
|
||||||
float wt2 = st(1.0-f);
|
|
||||||
|
|
||||||
vec3 color00 = color1*wt1 + color2*wt2;
|
|
||||||
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
|
||||||
vec3 mcolor = (mcolor1*wt1 + mcolor2*wt2)/(wt1+wt2);
|
|
||||||
|
|
||||||
vec3 ctmp = color00/(wt1+wt2);
|
|
||||||
vec3 sctmp = scolor0/(wt1+wt2);
|
|
||||||
|
|
||||||
vec3 tmp = pow(ctmp, vec3(1.0/gamma_out));
|
|
||||||
mcolor = clamp(mix(ctmp, mcolor, 1.5),0.0,1.0);
|
|
||||||
mcolor = pow(mcolor, vec3(1.4/gamma_out));
|
|
||||||
|
|
||||||
vec3 w1,w2 = vec3(0.0);
|
|
||||||
|
|
||||||
vec3 cref1 = mix(sctmp, scolor1, beam_size);
|
|
||||||
vec3 cref2 = mix(sctmp, scolor2, beam_size);
|
|
||||||
|
|
||||||
vec3 shift = vec3(-vertmask, vertmask, -vertmask); if (vertmask < 0.0) shift = shift.grr;
|
|
||||||
|
|
||||||
vec3 f1 = vec3(f);
|
|
||||||
vec3 f2 = vec3(1.0-f);
|
|
||||||
|
|
||||||
f1 = max(f1 + shift*0.5*(1.0+f), 0.75*f);
|
|
||||||
f2 = max(f2 - shift*0.5*(2.0-f), 0.75*(1.0-f));
|
|
||||||
|
|
||||||
if (gsl == 0.0) { w1 = sw0(f1,cref1,shape1); w2 = sw0(f2,cref2,shape2);} else
|
|
||||||
if (gsl == 1.0) { w1 = sw1(f1,cref1,shape1); w2 = sw1(f2,cref2,shape2);} else
|
|
||||||
if (gsl == 2.0) { w1 = sw2(f1,cref1,shape1); w2 = sw2(f2,cref2,shape2);}
|
|
||||||
|
|
||||||
vec3 color = color1*w1 + color2*w2;
|
|
||||||
color = min(color, 1.0);
|
|
||||||
|
|
||||||
if (interm > 0.5 && inter <= mix(SourceSize.y, SourceSize.x, TATE))
|
|
||||||
{
|
|
||||||
if (interm < 2.5)
|
|
||||||
{
|
|
||||||
float line_no = floor(mod(mix( OGL2Pos.y, OGL2Pos.x, TATE),2.0));
|
|
||||||
float frame_no = floor(mod(float(global.FrameCount),2.0));
|
|
||||||
float ii = (interm > 1.5) ? 0.5 : abs(line_no-frame_no);
|
|
||||||
|
|
||||||
vec3 icolor1 = mix(color1, color0, ii);
|
|
||||||
vec3 icolor2 = mix(color1, color2, ii);
|
|
||||||
|
|
||||||
color = mix(icolor1, icolor2, f);
|
|
||||||
mcolor = sqrt(color);
|
|
||||||
}
|
|
||||||
else color = mix(color1, color2, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctmp = 0.5*(ctmp+tmp);
|
|
||||||
color*=mix(brightboost, brightboost1, max(max(ctmp.r,ctmp.g),ctmp.b));
|
|
||||||
|
|
||||||
// Apply Mask
|
|
||||||
|
|
||||||
vec3 orig1 = color; float pixbr = max(max(ctmp.r,ctmp.g),ctmp.b); vec3 orig = ctmp; w1 = w1+w2; float w3 = max(max(w1.r,w1.g),w1.b);
|
|
||||||
vec3 cmask = vec3(1.0); vec3 cmask1 = cmask; vec3 one = vec3(1.0);
|
|
||||||
|
|
||||||
cmask*= (notate) ? Mask(gl_FragCoord.xy * 1.000001,mcolor) :
|
|
||||||
Mask(gl_FragCoord.yx * 1.000001,mcolor);
|
|
||||||
|
|
||||||
color = color*cmask;
|
|
||||||
|
|
||||||
color = min(color,1.0);
|
|
||||||
|
|
||||||
cmask1 *= (notate) ? SlotMask(gl_FragCoord.xy * 1.000001,tmp) :
|
|
||||||
SlotMask(gl_FragCoord.yx * 1.000001,tmp);
|
|
||||||
|
|
||||||
color = color*cmask1; cmask = cmask*cmask1; cmask = min(cmask, 1.0);
|
|
||||||
|
|
||||||
vec3 Bloom = COMPAT_TEXTURE(PassPrev2Texture, pos).xyz;
|
|
||||||
|
|
||||||
vec3 Bloom1 = 2.0*Bloom*Bloom;
|
|
||||||
Bloom1 = min(Bloom1, 0.75);
|
|
||||||
float bmax = max(max(Bloom1.r,Bloom1.g),Bloom1.b);
|
|
||||||
float pmax = 0.80;
|
|
||||||
Bloom1 = min(Bloom1, pmax*bmax)/pmax;
|
|
||||||
|
|
||||||
Bloom1 = mix(min( Bloom1, color), Bloom1, 0.5*(orig1+color));
|
|
||||||
|
|
||||||
Bloom1 = bloom*Bloom1;
|
|
||||||
|
|
||||||
color = color + Bloom1;
|
|
||||||
|
|
||||||
color = min(color, 1.0);
|
|
||||||
if (interm < 0.5 || inter > mix(SourceSize.y, SourceSize.x, TATE)) color = declip(color, pow(w3,0.6));
|
|
||||||
color = min(color, mix(cmask,one,0.6));
|
|
||||||
|
|
||||||
color = color + glow*Bloom;
|
|
||||||
|
|
||||||
color = pow(color, vec3(1.0/gamma_out));
|
|
||||||
|
|
||||||
FragColor = vec4(color*corner(pos0), 1.0);
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float TAPSH;
|
|
||||||
float GLOW_FALLOFF_H;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
// Higher value, more centered glow.
|
|
||||||
// Lower values might need more taps.
|
|
||||||
// Adapted from crt-easymode-halation by Easymode.
|
|
||||||
|
|
||||||
#pragma parameter TAPSH "H. Glow Radius" 4.0 1.0 10.0 1.0
|
|
||||||
#define TAPSH params.TAPSH
|
|
||||||
#pragma parameter GLOW_FALLOFF_H "Horizontal Glow Grade" 0.35 0.00 1.5 0.02
|
|
||||||
#define GLOW_FALLOFF_H params.GLOW_FALLOFF_H
|
|
||||||
|
|
||||||
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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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 RotPass;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
|
|
||||||
#define kernel(x) exp(-GLOW_FALLOFF_H * (x) * (x))
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
float ratio = COMPAT_TEXTURE(RotPass, vec2(0.5,0.1)).a;
|
|
||||||
if (vTexCoord.y > ratio) discard;
|
|
||||||
|
|
||||||
vec3 col = vec3(0.0); vec3 tmp;
|
|
||||||
float dx = SourceSize.z;
|
|
||||||
|
|
||||||
float k_total = 0.;
|
|
||||||
for (float i = -TAPSH; i <= TAPSH; i++)
|
|
||||||
{
|
|
||||||
float k = kernel(i);
|
|
||||||
k_total += k;
|
|
||||||
tmp = COMPAT_TEXTURE(Source, vTexCoord + vec2(float(i) * dx, 0.0)).rgb;
|
|
||||||
col += k * tmp;
|
|
||||||
}
|
|
||||||
FragColor = vec4(col / k_total, ratio);
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float TAPSV;
|
|
||||||
float GLOW_FALLOFF_V;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
// Higher value, more centered glow.
|
|
||||||
// Lower values might need more taps.
|
|
||||||
// Adapted from crt-easymode-halation by Easymode.
|
|
||||||
|
|
||||||
// Parameter lines go here:
|
|
||||||
#pragma parameter TAPSV "V. Glow Radius" 4.0 1.0 10.0 1.0
|
|
||||||
#define TAPSV params.TAPSV
|
|
||||||
#pragma parameter GLOW_FALLOFF_V "Vertical Glow Grade" 0.35 0.00 1.5 0.02
|
|
||||||
#define GLOW_FALLOFF_V params.GLOW_FALLOFF_V
|
|
||||||
|
|
||||||
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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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 RotPass;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
|
|
||||||
#define kernel(x) exp(-GLOW_FALLOFF_V * (x) * (x))
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
float ratio = COMPAT_TEXTURE(RotPass, vec2(0.5,0.1)).a;
|
|
||||||
if (vTexCoord.y > ratio) discard;
|
|
||||||
|
|
||||||
vec3 col = vec3(0.0);
|
|
||||||
float dy = SourceSize.w;
|
|
||||||
|
|
||||||
float k_total = 0.;
|
|
||||||
for (float i = -TAPSV; i <= TAPSV; i++)
|
|
||||||
{
|
|
||||||
float k = kernel(i);
|
|
||||||
k_total += k;
|
|
||||||
col += k * COMPAT_TEXTURE(Source, vTexCoord + vec2(0.0, float(i) * dy)).rgb;
|
|
||||||
}
|
|
||||||
FragColor = vec4(col / k_total, ratio);
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma stage fragment
|
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
|
||||||
layout(location = 0) out vec4 FragColor;
|
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
|
||||||
|
|
||||||
float Overscan(float pos, float dy){
|
|
||||||
pos=pos*2.0-1.0;
|
|
||||||
pos*=dy;
|
|
||||||
return pos*0.5+0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
float sm_tate = COMPAT_TEXTURE(Source, vec2(0.5)).a;
|
|
||||||
float ratio = 1.0;
|
|
||||||
vec2 tex = TEX0.xy; vec3 color = vec3(0.0);
|
|
||||||
|
|
||||||
if (sm_tate < 0.5) { ratio = 1.0/3.0; tex.y = tex.y / ratio; color = COMPAT_TEXTURE(Source, tex).rgb; }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ratio = (1.0/3.0) * params.SourceSize.x / params.SourceSize.y;
|
|
||||||
tex = tex.yx;
|
|
||||||
tex.x = tex.x / ratio;
|
|
||||||
tex.y = Overscan(tex.y, params.SourceSize.x / params.SourceSize.y);
|
|
||||||
color = COMPAT_TEXTURE(Source, tex).rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
FragColor = vec4(color,ratio);
|
|
||||||
}
|
|
|
@ -1,479 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - SM (Scanline Mask) Shader
|
|
||||||
|
|
||||||
Copyright (C) 2019-2020 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
Big thanks to Nesguy from the Libretro forums for the masks and other ideas.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* README - MASKS GUIDE
|
|
||||||
|
|
||||||
To obtain the best results with masks 0, 1, 3, 4:
|
|
||||||
must leave “mask size” at 1 and the display must be set to its native resolution to result in evenly spaced “active” LCD subpixels.
|
|
||||||
|
|
||||||
Mask 0: Uses a magenta and green pattern for even spacing of the LCD subpixels.
|
|
||||||
|
|
||||||
Mask 1: Similar to Mask 0, but with "ZigZag"
|
|
||||||
|
|
||||||
Mask 2: Intended for displays that have RBG subpixels (as opposed to the more common RGB).
|
|
||||||
Uses a yellow/blue pattern for even spacing of the LCD subpixels.
|
|
||||||
|
|
||||||
Mask 3: Common red/green/blue pattern.
|
|
||||||
|
|
||||||
Mask 4: This is useful for 4K displays, where masks 0 and 1 can look too fine.
|
|
||||||
Uses a red/yellow/cyan/blue pattern to result in even spacing of the LCD subpixels.
|
|
||||||
|
|
||||||
Mask 5: Intended for displays that have the less common RBG subpixel pattern.
|
|
||||||
This is useful for 4K displays, where masks 0 and 1 can look too fine.
|
|
||||||
Uses a red/magenta/cyan/green pattern for even spacing of the LCD subpixels.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
// vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
|
|
||||||
uint FrameCount;
|
|
||||||
float smart, brightboost1, brightboost2, stype, scanline1, scanline2, beam_min, beam_max, s_beam;
|
|
||||||
float h_sharp, cubic, mask, maskmode, maskdark, maskbright, masksize, gamma_out;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
vec4 FinalViewportSize;
|
|
||||||
float bglow;
|
|
||||||
float warpx;
|
|
||||||
float warpy;
|
|
||||||
float bloom;
|
|
||||||
float halation;
|
|
||||||
float autobrm;
|
|
||||||
float sclip;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
#pragma parameter bglow "Base Glow" 0.0 0.0 1.0 0.01
|
|
||||||
#pragma parameter bloom "Bloom" 0.40 0.0 2.0 0.05
|
|
||||||
#pragma parameter halation "Halation" 0.0 0.0 2.0 0.05
|
|
||||||
#pragma parameter autobrm "Automatic Brightness (Mask)" 0.5 0.0 1.0 0.1
|
|
||||||
#pragma parameter smart "1:Smart 2:Crop 3:Overscan Y Integer Scaling" 0.0 0.0 3.0 1.0
|
|
||||||
#pragma parameter brightboost1 "Bright boost dark colors" 1.40 0.5 5.0 0.10
|
|
||||||
#pragma parameter brightboost2 "Bright boost bright colors" 1.15 0.5 3.0 0.05
|
|
||||||
#pragma parameter stype "Scanline Type" 1.0 0.0 3.0 1.0
|
|
||||||
#pragma parameter scanline1 "Scanline Shape Center" 5.0 2.0 20.0 0.5
|
|
||||||
#pragma parameter scanline2 "Scanline Shape Edges" 7.0 4.0 20.0 0.5
|
|
||||||
#pragma parameter beam_min "Scanline dark" 1.25 0.5 3.0 0.05
|
|
||||||
#pragma parameter beam_max "Scanline bright" 1.10 0.5 3.0 0.05
|
|
||||||
#pragma parameter sclip "Allow Scanline/Mask Clipping With Bloom" 0.50 0.0 1.0 0.05
|
|
||||||
#pragma parameter s_beam "Overgrown Bright Beam" 0.70 0.0 1.0 0.05
|
|
||||||
#pragma parameter h_sharp "Horizontal sharpness" 3.0 1.0 10.0 0.10
|
|
||||||
#pragma parameter cubic "Cubic Filtering" 1.0 0.0 1.0 0.10
|
|
||||||
#pragma parameter mask "CRT Mask (4&5 are 4k masks)" 0.0 0.0 5.0 1.0
|
|
||||||
#pragma parameter maskmode "CRT Mask Mode: Classic, Fine, Coarse" 0.0 0.0 2.0 1.0
|
|
||||||
#pragma parameter maskdark "CRT Mask Strength Dark Pixels" 1.0 0.0 1.5 0.05
|
|
||||||
#pragma parameter maskbright "CRT Mask Strength Bright Pixels" 0.25 -0.5 1.0 0.05
|
|
||||||
#pragma parameter masksize "CRT Mask Size" 1.0 1.0 2.0 1.0
|
|
||||||
#pragma parameter warpx "Curvature X" 0.0 0.0 0.25 0.01
|
|
||||||
#pragma parameter warpy "Curvature Y" 0.0 0.0 0.25 0.01
|
|
||||||
#pragma parameter gamma_out "Gamma Out" 2.50 1.0 3.5 0.05
|
|
||||||
|
|
||||||
#define bglow global.bglow
|
|
||||||
#define autobrm global.autobrm
|
|
||||||
#define smart params.smart
|
|
||||||
#define brightboost1 params.brightboost1
|
|
||||||
#define brightboost2 params.brightboost2
|
|
||||||
#define bloom global.bloom
|
|
||||||
#define halation global.halation
|
|
||||||
#define stype params.stype
|
|
||||||
#define scanline1 params.scanline1
|
|
||||||
#define scanline2 params.scanline2
|
|
||||||
#define beam_min params.beam_min
|
|
||||||
#define beam_max params.beam_max
|
|
||||||
#define sclip global.sclip
|
|
||||||
#define s_beam params.s_beam
|
|
||||||
#define h_sharp params.h_sharp
|
|
||||||
#define cubic params.cubic
|
|
||||||
#define mask params.mask
|
|
||||||
#define maskmode params.maskmode
|
|
||||||
#define maskdark params.maskdark
|
|
||||||
#define maskbright params.maskbright
|
|
||||||
#define masksize params.masksize
|
|
||||||
#define warpx global.warpx
|
|
||||||
#define warpy global.warpy
|
|
||||||
#define gamma_out params.gamma_out
|
|
||||||
|
|
||||||
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define Texture Source
|
|
||||||
#define InputSize SourceSize
|
|
||||||
#define gl_FragCoord (vTexCoord * params.OutputSize.xy)
|
|
||||||
|
|
||||||
#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 WpPass;
|
|
||||||
layout(set = 0, binding = 4) uniform sampler2D RotPass;
|
|
||||||
layout(set = 0, binding = 5) uniform sampler2D LinPass;
|
|
||||||
|
|
||||||
float st(float x)
|
|
||||||
{
|
|
||||||
return exp2(-10.0*x*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vec3 sw0(float x, vec3 color, float scan)
|
|
||||||
{
|
|
||||||
vec3 tmp = mix(vec3(beam_min),vec3(beam_max), color);
|
|
||||||
vec3 ex = x*tmp;
|
|
||||||
return exp2(-scan*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec3 sw1(float x, vec3 color, float scan)
|
|
||||||
{
|
|
||||||
float mx1 = max(max(color.r,color.g),color.b);
|
|
||||||
vec3 tmp = mix(vec3(2.50*beam_min),vec3(beam_max), color);
|
|
||||||
tmp = mix(vec3(beam_max), tmp, pow(vec3(x), color + 0.30));
|
|
||||||
vec3 ex = vec3(x)*tmp;
|
|
||||||
vec3 res = exp2(-scan*ex*ex);
|
|
||||||
float mx2 = max(max(res.r,res.g),res.b);
|
|
||||||
float br = clamp(mix(0.30, 0.50, 2.0*(beam_min-1.0)),0.10, 0.60);
|
|
||||||
return mix(vec3(mx2), res, 0.50)/(1.0 - br + br*mx1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec3 sw2(float x, vec3 color, float scan)
|
|
||||||
{
|
|
||||||
float mx1 = max(max(color.r,color.g),color.b);
|
|
||||||
vec3 ex = mix(vec3(2.0*beam_min), vec3(beam_max), color);
|
|
||||||
vec3 m = min(0.3 + 0.35*ex, 1.0);
|
|
||||||
ex = x*ex;
|
|
||||||
vec3 xx = ex*ex;
|
|
||||||
xx = mix(xx, ex*xx, m);
|
|
||||||
vec3 res = exp2(-1.25*scan*xx);
|
|
||||||
float mx2 = max(max(res.r,res.g),res.b);
|
|
||||||
float br = clamp(mix(0.20, 0.50, 2.0*(beam_min-1.0)),0.10, 0.60);
|
|
||||||
return mix(vec3(mx2), res, 0.50)/(1.0 - br + br*mx1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float Overscan(float pos, float dy){
|
|
||||||
pos=pos*2.0-1.0;
|
|
||||||
pos*=dy;
|
|
||||||
return pos*0.5+0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Distortion of scanlines, and end of screen alpha (PD CRT Lottes Curvature)
|
|
||||||
vec2 Warp(vec2 pos)
|
|
||||||
{
|
|
||||||
pos = pos*2.0-1.0;
|
|
||||||
pos *= vec2(1.0 + (pos.y*pos.y)*warpx, 1.0 + (pos.x*pos.x)*warpy);
|
|
||||||
return pos*0.5 + 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 gc (vec3 c, float bd, float mb)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b)+0.00001;
|
|
||||||
float b2 = mix(bd, 1.0, pow(m,0.50));
|
|
||||||
return b2*c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 tex = TEX0.xy * 1.00001;
|
|
||||||
float sm_tate = COMPAT_TEXTURE(WpPass, vec2(0.5)).a;
|
|
||||||
float ratio = COMPAT_TEXTURE(RotPass, vec2(0.5, 0.1)).a;
|
|
||||||
|
|
||||||
vec4 SourceSize1 = params.SourceSize;
|
|
||||||
float vertres = SourceSize1.y*ratio;
|
|
||||||
|
|
||||||
tex.y *= ratio;
|
|
||||||
if (sm_tate > 0.25) { tex.x = Overscan(tex.x, (1.0/3.0)*SourceSize1.y/SourceSize1.x); }
|
|
||||||
|
|
||||||
float factor = params.OutputSize.y/vertres;
|
|
||||||
|
|
||||||
float gamma = COMPAT_TEXTURE(LinPass, vec2(0.5,0.1)).a;
|
|
||||||
|
|
||||||
if (smart == 1.0 || smart == 2.0 || smart == 3.0)
|
|
||||||
{
|
|
||||||
float intfactor = round(factor); if (smart == 2.0) intfactor = floor(factor); if (smart == 3.0) intfactor = ceil(factor);
|
|
||||||
float diff = factor/intfactor;
|
|
||||||
tex.y = Overscan(tex.y/(ratio), diff)*ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
tex = Warp(tex/vec2(1.0,ratio))*vec2(1.0,ratio);
|
|
||||||
|
|
||||||
vec2 OGL2Pos = tex * SourceSize1.xy - vec2(0.5,0.5);
|
|
||||||
vec2 fp = fract(OGL2Pos);
|
|
||||||
float fpx = fp.x;
|
|
||||||
float fp1 = 1.0-fpx;
|
|
||||||
|
|
||||||
vec2 pC4 = (floor(OGL2Pos) + vec2(0.5)) * SourceSize1.zw;
|
|
||||||
|
|
||||||
// Reading the texels
|
|
||||||
vec2 dx = vec2(SourceSize1.z,0.0);
|
|
||||||
vec2 dy = vec2(0.0,SourceSize1.w);
|
|
||||||
vec2 x2 = dx+dx;
|
|
||||||
float zero = mix(0.0, exp2(-h_sharp), cubic);
|
|
||||||
|
|
||||||
float wl2 = 1.0 + fp.x;
|
|
||||||
float wl1 = fp.x;
|
|
||||||
float wr1 = 1.0 - fp.x;
|
|
||||||
float wr2 = 2.0 - fp.x;
|
|
||||||
|
|
||||||
wl2*=wl2; wl2 = exp2(-h_sharp*wl2);
|
|
||||||
wl1*=wl1; wl1 = exp2(-h_sharp*wl1);
|
|
||||||
wr1*=wr1; wr1 = exp2(-h_sharp*wr1);
|
|
||||||
wr2*=wr2; wr2 = exp2(-h_sharp*wr2);
|
|
||||||
|
|
||||||
wl2 = max(wl2 - zero, mix(0.0,mix(-0.14, 0.0, 1.0-fp1*fp1),float(cubic > 0.05)));
|
|
||||||
wl1 = max(wl1 - zero, 0.0);
|
|
||||||
wr1 = max(wr1 - zero, 0.0);
|
|
||||||
wr2 = max(wr2 - zero, mix(0.0,mix(-0.14, 0.0, 1.0-fpx*fpx),float(cubic > 0.05)));
|
|
||||||
|
|
||||||
float sl2 = max(wl2,0.0);
|
|
||||||
float sl1 = wl1;
|
|
||||||
float sr1 = wr1;
|
|
||||||
float sr2 = max(wr2,0.0);
|
|
||||||
|
|
||||||
float wtt = 1.0/(wl2+wl1+wr1+wr2);
|
|
||||||
float wts = 1.0/(sl2+sl1+sr1+sr2);
|
|
||||||
|
|
||||||
vec3 l2 = COMPAT_TEXTURE(LinPass, pC4 - dx).rgb;
|
|
||||||
vec3 l1 = COMPAT_TEXTURE(LinPass, pC4 ).rgb;
|
|
||||||
vec3 r1 = COMPAT_TEXTURE(LinPass, pC4 + dx).rgb;
|
|
||||||
vec3 r2 = COMPAT_TEXTURE(LinPass, pC4 + x2).rgb;
|
|
||||||
|
|
||||||
vec3 color1 = (wl2*l2+wl1*l1+wr1*r1+wr2*r2)*wtt;
|
|
||||||
|
|
||||||
vec3 colmin = min(min(l2,l1),min(r1,r2));
|
|
||||||
vec3 colmax = max(max(l2,l1),max(r1,r2));
|
|
||||||
|
|
||||||
if (cubic > 0.05) color1 = clamp(color1, colmin, colmax);
|
|
||||||
|
|
||||||
l1*=l1; l1*=l1*l1; r1*=r1; r1*=r1*r1; l2*=l2; l2*=l2*l2; r2*=r2; r2*=r2*r2;
|
|
||||||
vec3 scolor1 = (sl2*l2+sl1*l1+sr1*r1+sr2*r2)*wts;
|
|
||||||
scolor1 = pow(scolor1, vec3(1.0/6.0)); vec3 mscolor1 = scolor1;
|
|
||||||
|
|
||||||
scolor1 = mix(color1, scolor1, 1.0);
|
|
||||||
|
|
||||||
pC4+=dy;
|
|
||||||
l2 = COMPAT_TEXTURE(LinPass, pC4 - dx).rgb;
|
|
||||||
l1 = COMPAT_TEXTURE(LinPass, pC4 ).rgb;
|
|
||||||
r1 = COMPAT_TEXTURE(LinPass, pC4 + dx).rgb;
|
|
||||||
r2 = COMPAT_TEXTURE(LinPass, pC4 + x2).rgb;
|
|
||||||
|
|
||||||
vec3 color2 = (wl2*l2+wl1*l1+wr1*r1+wr2*r2)*wtt;
|
|
||||||
|
|
||||||
colmin = min(min(l2,l1),min(r1,r2));
|
|
||||||
colmax = max(max(l2,l1),max(r1,r2));
|
|
||||||
|
|
||||||
if (cubic > 0.05) color2 = clamp(color2, colmin, colmax);
|
|
||||||
|
|
||||||
l1*=l1; l1*=l1*l1; r1*=r1; r1*=r1*r1; l2*=l2; l2*=l2*l2; r2*=r2; r2*=r2*r2;
|
|
||||||
vec3 scolor2 = (sl2*l2+sl1*l1+sr1*r1+sr2*r2)*wts;
|
|
||||||
scolor2 = pow(scolor2, vec3(1.0/6.0)); vec3 mscolor2 = scolor2;
|
|
||||||
|
|
||||||
scolor2 = mix(color2, scolor2, 1.0);
|
|
||||||
|
|
||||||
float f1 = fp.y;
|
|
||||||
float f2 = 1.0 - fp.y;
|
|
||||||
float f3 = fract(tex.y * SourceSize1.y);
|
|
||||||
|
|
||||||
vec3 color;
|
|
||||||
float t1 = st(f1);
|
|
||||||
float t2 = st(f2);
|
|
||||||
float wt = 1.0/(t1+t2);
|
|
||||||
|
|
||||||
// calculating scanlines
|
|
||||||
|
|
||||||
float scan1 = mix(scanline1, scanline2, f1);
|
|
||||||
float scan2 = mix(scanline1, scanline2, f2);
|
|
||||||
|
|
||||||
vec3 sctemp = (t1*scolor1 + t2*scolor2)*wt;
|
|
||||||
vec3 msctemp = (t1*mscolor1 + t2*mscolor2)*wt;
|
|
||||||
|
|
||||||
vec3 ref1 = mix(sctemp, scolor1.rgb, s_beam); ref1 = pow(ref1, mix(vec3(1.25), vec3(0.65), ref1));
|
|
||||||
vec3 ref2 = mix(sctemp, scolor2.rgb, s_beam); ref2 = pow(ref2, mix(vec3(1.25), vec3(0.65), ref2));
|
|
||||||
|
|
||||||
vec3 w1, w2 = vec3(0.0);
|
|
||||||
|
|
||||||
if (stype < 0.5)
|
|
||||||
{
|
|
||||||
w1 = sw0(f1, ref1, scan1);
|
|
||||||
w2 = sw0(f2, ref2, scan2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (stype < 1.5)
|
|
||||||
{
|
|
||||||
w1 = sw1(f1, ref1, scan1);
|
|
||||||
w2 = sw1(f2, ref2, scan2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (stype < 2.5)
|
|
||||||
{
|
|
||||||
w1 = sw2(f1, ref1, scan1);
|
|
||||||
w2 = sw2(f2, ref2, scan2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
w1 = vec3(f2);
|
|
||||||
w2 = vec3(f1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec3 ctemp = (t1*color1 + t2*color2)*wt; vec3 orig = ctemp; float pixbr = max(max(orig.r,orig.g),orig.b); vec3 one = vec3(1.0);
|
|
||||||
vec3 tmp1 = clamp(mix(orig, msctemp, 1.25),0.0,1.0);
|
|
||||||
ctemp = w1+w2;
|
|
||||||
float w3 = max(max(ctemp.r,ctemp.g),ctemp.b);
|
|
||||||
|
|
||||||
tmp1 = pow(tmp1, vec3(0.65));
|
|
||||||
float pixbr1 = max(max(tmp1.r,tmp1.g),tmp1.b);
|
|
||||||
|
|
||||||
float maskd = mix(min(maskdark,1.0), 0.25*max(maskbright,0.0), pixbr1); if (mask == 3.0 || mask == 4.0) maskd*=1.33; maskd = mix(1.0, 1.0/(1.0-0.5*maskd), autobrm);
|
|
||||||
maskd = mix(maskd, 1.0, pow(pixbr,0.85));
|
|
||||||
|
|
||||||
float brightboost_d = brightboost1;
|
|
||||||
float brightboost_b = brightboost2;
|
|
||||||
|
|
||||||
if (stype == 1.0) { brightboost_d = min(brightboost1, 1.40); maskd = 1.0; }
|
|
||||||
|
|
||||||
color1 = gc(color1, brightboost_d, maskd);
|
|
||||||
color2 = gc(color2, brightboost_d, maskd);
|
|
||||||
|
|
||||||
color1 = min(color1, 1.0);
|
|
||||||
color2 = min(color2, 1.0);
|
|
||||||
|
|
||||||
color = w1*color1.rgb + w2*color2.rgb;
|
|
||||||
color = maskd*color;
|
|
||||||
|
|
||||||
vec3 scan3 = vec3(0.0);
|
|
||||||
|
|
||||||
float spos = (gl_FragCoord.x);
|
|
||||||
float spos2 = floor(1.000001*gl_FragCoord.x/masksize) + floor(1.000001*gl_FragCoord.y/masksize);
|
|
||||||
|
|
||||||
spos = floor((spos * 1.000001)/masksize); float spos1 = 0.0;
|
|
||||||
|
|
||||||
|
|
||||||
if (mask == 0.0 || mask == 1.0)
|
|
||||||
{
|
|
||||||
if (mask == 1.0) spos = spos2;
|
|
||||||
spos1 = fract(spos*0.5);
|
|
||||||
if (spos1 < 0.5) scan3.rb = one.rb;
|
|
||||||
else scan3.g = one.g;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (mask == 2.0)
|
|
||||||
{
|
|
||||||
spos1 = fract(spos*0.5);
|
|
||||||
if (spos1 < 0.5) scan3.rg = one.rg;
|
|
||||||
else scan3.b = one.b;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (mask == 3.0)
|
|
||||||
{
|
|
||||||
spos1 = fract(spos/3.0);
|
|
||||||
if (spos1 < 0.3333) scan3.r = one.r;
|
|
||||||
else if (spos1 < 0.6666) scan3.g = one.g;
|
|
||||||
else scan3.b = one.b;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (mask == 4.0)
|
|
||||||
{
|
|
||||||
spos1 = fract(spos*0.25);
|
|
||||||
if (spos1 < 0.25) scan3.r = one.r;
|
|
||||||
else if (spos1 < 0.50) scan3.rg = one.rg;
|
|
||||||
else if (spos1 < 0.75) scan3.gb = one.gb;
|
|
||||||
else scan3.b = one.b;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spos1 = fract(spos*0.25);
|
|
||||||
if (spos1 < 0.25) scan3.r = one.r;
|
|
||||||
else if (spos1 < 0.50) scan3.rb = one.rb;
|
|
||||||
else if (spos1 < 0.75) scan3.gb = one.gb;
|
|
||||||
else scan3.g = one.g;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 mixmask = tmp1;
|
|
||||||
if (maskmode == 1.0) mixmask = vec3(pixbr1); else
|
|
||||||
if (maskmode == 2.0) mixmask = tmp1*w3;
|
|
||||||
|
|
||||||
vec3 cmask = clamp(mix( mix(one, scan3, maskdark), mix(one, scan3, maskbright), mixmask), 0.0, 1.0);
|
|
||||||
vec3 orig1 = color;
|
|
||||||
color = color*cmask*brightboost_b;
|
|
||||||
|
|
||||||
vec3 Bloom = COMPAT_TEXTURE(Source, tex).rgb;
|
|
||||||
vec3 Bglow = COMPAT_TEXTURE(LinPass, tex).rgb;
|
|
||||||
Bglow = clamp(Bloom - Bglow,0.0,1.0);
|
|
||||||
vec3 hglow = 0.5*(Bloom + Bglow);
|
|
||||||
float maxb = max(max(hglow.r,hglow.g),hglow.b); maxb*=maxb;
|
|
||||||
|
|
||||||
vec3 Bloom1 = 2.0*Bloom*Bloom;
|
|
||||||
Bloom1 = min(Bloom1, 0.75);
|
|
||||||
float bmax = max(max(Bloom1.r,Bloom1.g),Bloom1.b);
|
|
||||||
float pmax = 0.85;
|
|
||||||
Bloom1 = min(Bloom1, pmax*bmax)/pmax;
|
|
||||||
|
|
||||||
Bloom1 = mix(min( Bloom1, 0.5*(orig1+color)), Bloom1, 0.5*(orig1+color));
|
|
||||||
Bloom1 = Bloom1*mix(w1+w2,one,1.0-color);
|
|
||||||
|
|
||||||
Bloom1 = bloom*Bloom1*cmask;
|
|
||||||
|
|
||||||
color = color + Bloom1;
|
|
||||||
color = min(color,1.0);
|
|
||||||
color = declip(color, pow(w3, 1.0-sclip));
|
|
||||||
|
|
||||||
float colmx = pixbr1;
|
|
||||||
Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx);
|
|
||||||
color = color + 0.75*(0.75+maxb)*Bloom*(0.75+sqrt(colmx))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation;
|
|
||||||
|
|
||||||
color = color + bglow*Bglow;
|
|
||||||
color = min(color, mix(cmask,one,sclip));
|
|
||||||
|
|
||||||
float fgamma = 1.0/gamma_out;
|
|
||||||
if (stype == 1.0) fgamma = gamma;
|
|
||||||
vec3 color1g = pow(color, vec3(fgamma));
|
|
||||||
|
|
||||||
FragColor = vec4(color1g, 1.0);
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float WP;
|
|
||||||
float wp_saturation;
|
|
||||||
float tate, fliph, flipv;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter tate "TATE Mode" 0.0 0.0 1.0 1.0
|
|
||||||
#pragma parameter fliph "Flip The Image Horizontally" -1.0 -1.0 1.0 2.0
|
|
||||||
#pragma parameter flipv "Flip The Image Vertically" 1.0 -1.0 1.0 2.0
|
|
||||||
#pragma parameter WP "Color Temperature %" 0.0 -100.0 100.0 5.0
|
|
||||||
#pragma parameter wp_saturation "Saturation Adjustment" 1.0 0.0 2.0 0.05
|
|
||||||
|
|
||||||
#define WP params.WP
|
|
||||||
#define wp_saturation params.wp_saturation
|
|
||||||
#define tate params.tate
|
|
||||||
#define fliph params.fliph
|
|
||||||
#define flipv params.flipv
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
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 * mix(vec4(1.0), vec4(flipv, fliph, 1.0, 1.0), tate);
|
|
||||||
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;
|
|
||||||
|
|
||||||
const mat3 D65_to_XYZ = mat3 (
|
|
||||||
0.4306190, 0.2220379, 0.0201853,
|
|
||||||
0.3415419, 0.7066384, 0.1295504,
|
|
||||||
0.1783091, 0.0713236, 0.9390944);
|
|
||||||
|
|
||||||
const mat3 XYZ_to_D65 = mat3 (
|
|
||||||
3.0628971, -0.9692660, 0.0678775,
|
|
||||||
-1.3931791, 1.8760108, -0.2288548,
|
|
||||||
-0.4757517, 0.0415560, 1.0693490);
|
|
||||||
|
|
||||||
const mat3 D50_to_XYZ = mat3 (
|
|
||||||
0.4552773, 0.2323025, 0.0145457,
|
|
||||||
0.3675500, 0.7077956, 0.1049154,
|
|
||||||
0.1413926, 0.0599019, 0.7057489);
|
|
||||||
|
|
||||||
const mat3 XYZ_to_D50 = mat3 (
|
|
||||||
2.9603944, -0.9787684, 0.0844874,
|
|
||||||
-1.4678519, 1.9161415, -0.2545973,
|
|
||||||
-0.4685105, 0.0334540, 1.4216174);
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec3 color = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
|
|
||||||
|
|
||||||
color = normalize(pow(color + 1e-4, vec3(wp_saturation)))*length(color);
|
|
||||||
|
|
||||||
float p = 2.4;
|
|
||||||
|
|
||||||
color = pow(color, vec3(p));
|
|
||||||
|
|
||||||
vec3 warmer = D50_to_XYZ*color;
|
|
||||||
warmer = XYZ_to_D65*warmer;
|
|
||||||
|
|
||||||
vec3 cooler = D65_to_XYZ*color;
|
|
||||||
cooler = XYZ_to_D50*cooler;
|
|
||||||
|
|
||||||
float m = abs(WP)/100.0;
|
|
||||||
|
|
||||||
vec3 comp = (WP < 0.0) ? cooler : warmer;
|
|
||||||
|
|
||||||
color = mix(color, comp, m);
|
|
||||||
|
|
||||||
color = pow(color, vec3(1.0/p));
|
|
||||||
|
|
||||||
float a = 0.0; if (tate > 0.5) a = 0.5;
|
|
||||||
|
|
||||||
FragColor = vec4(color,a);
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float GAMMA_INPUT;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 0.5 5.0 0.05
|
|
||||||
#define GAMMA_INPUT params.GAMMA_INPUT
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
float ratio = texture(Source, vec2(0.5,0.1)).a;
|
|
||||||
if (vTexCoord.y > ratio) discard;
|
|
||||||
float gamma = 2.4;
|
|
||||||
if ( (GAMMA_INPUT > 0.4) || (GAMMA_INPUT < 4.1) ) gamma = GAMMA_INPUT;
|
|
||||||
gamma = 1.0/gamma;
|
|
||||||
|
|
||||||
FragColor = vec4(pow(vec3(texture(Source, vTexCoord).rgb), vec3(GAMMA_INPUT)),gamma);
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float WP;
|
|
||||||
float wp_saturation;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter WP "Color Temperature %" 0.0 -100.0 100.0 5.0
|
|
||||||
#pragma parameter wp_saturation "Saturation Adjustment" 1.0 0.0 2.0 0.05
|
|
||||||
|
|
||||||
#define WP params.WP
|
|
||||||
#define wp_saturation params.wp_saturation
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define TEX0 vTexCoord
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
const mat3 D65_to_XYZ = mat3 (
|
|
||||||
0.4306190, 0.2220379, 0.0201853,
|
|
||||||
0.3415419, 0.7066384, 0.1295504,
|
|
||||||
0.1783091, 0.0713236, 0.9390944);
|
|
||||||
|
|
||||||
const mat3 XYZ_to_D65 = mat3 (
|
|
||||||
3.0628971, -0.9692660, 0.0678775,
|
|
||||||
-1.3931791, 1.8760108, -0.2288548,
|
|
||||||
-0.4757517, 0.0415560, 1.0693490);
|
|
||||||
|
|
||||||
const mat3 D50_to_XYZ = mat3 (
|
|
||||||
0.4552773, 0.2323025, 0.0145457,
|
|
||||||
0.3675500, 0.7077956, 0.1049154,
|
|
||||||
0.1413926, 0.0599019, 0.7057489);
|
|
||||||
|
|
||||||
const mat3 XYZ_to_D50 = mat3 (
|
|
||||||
2.9603944, -0.9787684, 0.0844874,
|
|
||||||
-1.4678519, 1.9161415, -0.2545973,
|
|
||||||
-0.4685105, 0.0334540, 1.4216174);
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec3 color = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
|
|
||||||
|
|
||||||
color = normalize(pow(color + 1e-4, vec3(wp_saturation)))*length(color);
|
|
||||||
|
|
||||||
float p = 2.4;
|
|
||||||
|
|
||||||
color = pow(color, vec3(p));
|
|
||||||
|
|
||||||
vec3 warmer = D50_to_XYZ*color;
|
|
||||||
warmer = XYZ_to_D65*warmer;
|
|
||||||
|
|
||||||
vec3 cooler = D65_to_XYZ*color;
|
|
||||||
cooler = XYZ_to_D50*cooler;
|
|
||||||
|
|
||||||
float m = abs(WP)/100.0;
|
|
||||||
|
|
||||||
vec3 comp = (WP < 0.0) ? cooler : warmer;
|
|
||||||
|
|
||||||
color = mix(color, comp, m);
|
|
||||||
|
|
||||||
color = pow(color, vec3(1.0/p));
|
|
||||||
|
|
||||||
FragColor = vec4(color,1.0);
|
|
||||||
}
|
|
|
@ -21,11 +21,9 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma format R16G16B16A16_SFLOAT
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
vec4 LinearizePassSize;
|
vec4 SourceSize;
|
||||||
vec4 OriginalSize;
|
vec4 OriginalSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
|
@ -38,7 +36,7 @@ layout(push_constant) uniform Push
|
||||||
#pragma parameter SIZEHB " H. Bloom/Halation/Glow Radius" 4.0 1.0 30.0 1.0
|
#pragma parameter SIZEHB " H. Bloom/Halation/Glow Radius" 4.0 1.0 30.0 1.0
|
||||||
#define SIZEHB params.SIZEHB
|
#define SIZEHB params.SIZEHB
|
||||||
|
|
||||||
#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/Glow Sigma" 0.70 0.5 15.0 0.05
|
#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/Glow Sigma" 1.0 0.25 15.0 0.05
|
||||||
#define SIGMA_HB params.SIGMA_HB
|
#define SIGMA_HB params.SIGMA_HB
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma format R16G16B16A16_SFLOAT
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
|
@ -37,7 +36,7 @@ layout(push_constant) uniform Push
|
||||||
#pragma parameter SIZEVB " V. Bloom/Halation/Glow Radius" 4.0 1.0 30.0 1.0
|
#pragma parameter SIZEVB " V. Bloom/Halation/Glow Radius" 4.0 1.0 30.0 1.0
|
||||||
#define SIZEVB params.SIZEVB
|
#define SIZEVB params.SIZEVB
|
||||||
|
|
||||||
#pragma parameter SIGMA_VB " Vertical Bloom/Halation/Glow Sigma" 0.70 0.5 15.0 0.05
|
#pragma parameter SIGMA_VB " Vertical Bloom/Halation/Glow Sigma" 1.0 0.25 15.0 0.05
|
||||||
#define SIGMA_VB params.SIGMA_VB
|
#define SIGMA_VB params.SIGMA_VB
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
|
|
@ -30,7 +30,7 @@ layout(push_constant) uniform Push
|
||||||
vec4 OriginalSize;
|
vec4 OriginalSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
float IOS, h_sharp, s_sharp, spike;
|
float IOS, h_sharp, s_sharp, spike, ring;
|
||||||
float prescalex;
|
float prescalex;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
|
@ -48,6 +48,9 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
||||||
#define s_sharp params.s_sharp // substractive sharpness
|
#define s_sharp params.s_sharp // substractive sharpness
|
||||||
|
|
||||||
|
#pragma parameter ring " Substractive sharpness Ringing" 0.0 0.0 3.0 0.05
|
||||||
|
#define ring params.ring // substractive sharpness ringing
|
||||||
|
|
||||||
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
||||||
#define spike params.spike
|
#define spike params.spike
|
||||||
|
|
||||||
|
@ -68,7 +71,7 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord * 1.000001;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
|
@ -146,18 +149,19 @@ void main()
|
||||||
|
|
||||||
color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
||||||
|
|
||||||
if (sharp) color1 = clamp(color1, colmin, colmax);
|
if (sharp) color1 = clamp(mix(clamp(color1, colmin, colmax), color1, ring), 0.0, 1.0);
|
||||||
float ts = 0.033;
|
float ts = 0.025;
|
||||||
|
vec3 luma = vec3(0.2126, 0.7152, 0.0722);
|
||||||
|
|
||||||
float lm2 = max(max(l2.r,l2.g),l2.b);
|
float lm2 = max(max(l2.r,l2.g),l2.b);
|
||||||
float lm1 = max(max(l1.r,l1.g),l1.b);
|
float lm1 = max(max(l1.r,l1.g),l1.b);
|
||||||
float rm1 = max(max(r1.r,r1.g),r1.b);
|
float rm1 = max(max(r1.r,r1.g),r1.b);
|
||||||
float rm2 = max(max(r2.r,r2.g),r2.b);
|
float rm2 = max(max(r2.r,r2.g),r2.b);
|
||||||
|
|
||||||
float swl2 = max(twl2,0.0) * (lm2+ts);
|
float swl2 = max(twl2, 0.0) * (dot(l2,luma) + ts);
|
||||||
float swl1 = twl1 * (lm1+ts);
|
float swl1 = twl1 * (dot(l1,luma) + ts);
|
||||||
float swr1 = twr1 * (rm1+ts);
|
float swr1 = twr1 * (dot(r1,luma) + ts);
|
||||||
float swr2 = max(twr2,0.0) * (rm2+ts);
|
float swr2 = max(twr2, 0.0) * (dot(r2,luma) + ts);
|
||||||
|
|
||||||
float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
||||||
float sresult = clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0);
|
float sresult = clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0);
|
||||||
|
|
|
@ -30,7 +30,7 @@ layout(push_constant) uniform Push
|
||||||
vec4 OriginalSize;
|
vec4 OriginalSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
float IOS, h_sharp, s_sharp, spike;
|
float IOS, h_sharp, s_sharp, spike, ring;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
@ -47,6 +47,9 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
#pragma parameter s_sharp " Substractive sharpness (1.0 recommended)" 0.50 0.0 1.5 0.10
|
||||||
#define s_sharp params.s_sharp // substractive sharpness
|
#define s_sharp params.s_sharp // substractive sharpness
|
||||||
|
|
||||||
|
#pragma parameter ring " Substractive sharpness Ringing" 0.0 0.0 3.0 0.05
|
||||||
|
#define ring params.ring // substractive sharpness ringing
|
||||||
|
|
||||||
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
||||||
#define spike params.spike
|
#define spike params.spike
|
||||||
|
|
||||||
|
@ -65,7 +68,7 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord * 1.000001;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
|
@ -100,57 +103,50 @@ void main()
|
||||||
float zero = exp2(-h_sharp);
|
float zero = exp2(-h_sharp);
|
||||||
float sharp1 = s_sharp * zero;
|
float sharp1 = s_sharp * zero;
|
||||||
|
|
||||||
float wl3 = 2.0 + fpx;
|
|
||||||
float wl2 = 1.0 + fpx;
|
float wl2 = 1.0 + fpx;
|
||||||
float wl1 = fpx;
|
float wl1 = fpx;
|
||||||
float wr1 = 1.0 - fpx;
|
float wr1 = 1.0 - fpx;
|
||||||
float wr2 = 2.0 - fpx;
|
float wr2 = 2.0 - fpx;
|
||||||
float wr3 = 3.0 - fpx;
|
|
||||||
|
|
||||||
wl3*=wl3; wl3 = exp2(-h_sharp*wl3);
|
|
||||||
wl2*=wl2; wl2 = exp2(-h_sharp*wl2);
|
wl2*=wl2; wl2 = exp2(-h_sharp*wl2);
|
||||||
wl1*=wl1; wl1 = exp2(-h_sharp*wl1);
|
wl1*=wl1; wl1 = exp2(-h_sharp*wl1);
|
||||||
wr1*=wr1; wr1 = exp2(-h_sharp*wr1);
|
wr1*=wr1; wr1 = exp2(-h_sharp*wr1);
|
||||||
wr2*=wr2; wr2 = exp2(-h_sharp*wr2);
|
wr2*=wr2; wr2 = exp2(-h_sharp*wr2);
|
||||||
wr3*=wr3; wr3 = exp2(-h_sharp*wr3);
|
|
||||||
|
|
||||||
float fp1 = 1.-fpx;
|
float fp1 = 1.-fpx;
|
||||||
|
|
||||||
float twl3 = max(wl3 - sharp1, 0.0);
|
|
||||||
float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1));
|
float twl2 = max(wl2 - sharp1, mix(-0.12, 0.0, 1.0-fp1*fp1));
|
||||||
float twl1 = max(wl1 - sharp1, 0.0);
|
float twl1 = max(wl1 - sharp1, 0.0);
|
||||||
float twr1 = max(wr1 - sharp1, 0.0);
|
float twr1 = max(wr1 - sharp1, 0.0);
|
||||||
float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx));
|
float twr2 = max(wr2 - sharp1, mix(-0.12, 0.0, 1.0-fpx*fpx));
|
||||||
float twr3 = max(wr3 - sharp1, 0.0);
|
|
||||||
|
|
||||||
bool sharp = (sharp1 > 0.0);
|
bool sharp = (sharp1 > 0.0);
|
||||||
|
|
||||||
vec3 l3, l2, l1, r1, r2, r3, color1, colmin, colmax;
|
vec3 l2, l1, r1, r2, color1, colmin, colmax;
|
||||||
|
|
||||||
l3 = COMPAT_TEXTURE(LinearizePass, pC4 -x2).rgb;
|
|
||||||
l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb;
|
l2 = COMPAT_TEXTURE(LinearizePass, pC4 -offx).rgb;
|
||||||
l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb;
|
l1 = COMPAT_TEXTURE(LinearizePass, pC4 ).rgb;
|
||||||
r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb;
|
r1 = COMPAT_TEXTURE(LinearizePass, pC4 +offx).rgb;
|
||||||
r2 = COMPAT_TEXTURE(LinearizePass, pC4 +x2).rgb;
|
r2 = COMPAT_TEXTURE(LinearizePass, pC4 +x2).rgb;
|
||||||
r3 = COMPAT_TEXTURE(LinearizePass, pC4 +offx+x2).rgb;
|
|
||||||
|
|
||||||
colmin = min(min(l1,r1), min(l2,r2));
|
colmin = min(min(l1,r1), min(l2,r2));
|
||||||
colmax = max(max(l1,r1), max(l2,r2));
|
colmax = max(max(l1,r1), max(l2,r2));
|
||||||
|
|
||||||
color1 = (l3*twl3 + l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2 + r3*twr3)/(twl3+twl2+twl1+twr1+twr2+twr3);
|
color1 = (l2*twl2 + l1*twl1 + r1*twr1 + r2*twr2)/(twl2+twl1+twr1+twr2);
|
||||||
|
|
||||||
if (sharp) color1 = clamp(color1, colmin, colmax);
|
if (sharp) color1 = clamp(mix(clamp(color1, colmin, colmax), color1, ring), 0.0, 1.0);
|
||||||
float ts = 0.033;
|
float ts = 0.025;
|
||||||
|
vec3 luma = vec3(0.2126, 0.7152, 0.0722);
|
||||||
|
|
||||||
float lm2 = max(max(l2.r,l2.g),l2.b);
|
float lm2 = max(max(l2.r,l2.g),l2.b);
|
||||||
float lm1 = max(max(l1.r,l1.g),l1.b);
|
float lm1 = max(max(l1.r,l1.g),l1.b);
|
||||||
float rm1 = max(max(r1.r,r1.g),r1.b);
|
float rm1 = max(max(r1.r,r1.g),r1.b);
|
||||||
float rm2 = max(max(r2.r,r2.g),r2.b);
|
float rm2 = max(max(r2.r,r2.g),r2.b);
|
||||||
|
|
||||||
float swl2 = max(twl2,0.0) * (lm2+ts);
|
float swl2 = max(twl2, 0.0) * (dot(l2,luma) + ts);
|
||||||
float swl1 = twl1 * (lm1+ts);
|
float swl1 = twl1 * (dot(l1,luma) + ts);
|
||||||
float swr1 = twr1 * (rm1+ts);
|
float swr1 = twr1 * (dot(r1,luma) + ts);
|
||||||
float swr2 = max(twr2,0.0) * (rm2+ts);
|
float swr2 = max(twr2, 0.0) * (dot(r2,luma) + ts);
|
||||||
|
|
||||||
float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
float fscolor1 = (lm2*swl2 + lm1*swl1 + rm1*swr1 + rm2*swr2)/(swl2+swl1+swr1+swr2);
|
||||||
float sresult = clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0);
|
float sresult = clamp(mix(max(max(color1.r,color1.g),color1.b), fscolor1, spike), 0.0, 1.0);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
CRT - Guest - Advanced - Fast - Pass2
|
CRT - Guest - Advanced - Fast - Pass2
|
||||||
|
|
||||||
Copyright (C) 2018-2021 guest(r) - guest.r@gmail.com
|
Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
@ -27,8 +27,7 @@
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
float brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
float brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
||||||
glow, shadowMask, masksize, vertmask, slotmask, slotwidth, double_slot, mcut, maskDark, maskLight,
|
glow, vertmask, maskstr, inters, bloom, halation, scans, gamma_c, gamma_out, IOS;
|
||||||
maskstr, inters, bloom, halation, scans, slotms, mclip, gamma_c, gamma_out, DER, DEG, DEB, DES, IOS;
|
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
@ -42,13 +41,17 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
float warpX;
|
float warpX;
|
||||||
float warpY;
|
float warpY;
|
||||||
float csize;
|
float csize;
|
||||||
float bsize;
|
float bsize1;
|
||||||
float intres;
|
float intres;
|
||||||
float c_shape;
|
float c_shape;
|
||||||
float barspeed;
|
float barspeed;
|
||||||
float barintensity;
|
float barintensity;
|
||||||
float bardir;
|
float bardir;
|
||||||
float slotmask1;
|
float sborder;
|
||||||
|
float scan_falloff;
|
||||||
|
float overscanX;
|
||||||
|
float overscanY;
|
||||||
|
float bloom_dist;
|
||||||
} global;
|
} global;
|
||||||
|
|
||||||
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
@ -67,11 +70,20 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
||||||
#define c_shape global.c_shape // curvature shape
|
#define c_shape global.c_shape // curvature shape
|
||||||
|
|
||||||
#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01
|
#pragma parameter overscanX " Overscan X original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanX global.overscanX // OverscanX pixels
|
||||||
|
|
||||||
|
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanY global.overscanY // OverscanY pixels
|
||||||
|
|
||||||
|
#pragma parameter csize " Corner Size" 0.0 0.0 0.25 0.005
|
||||||
#define csize global.csize // corner size
|
#define csize global.csize // corner size
|
||||||
|
|
||||||
#pragma parameter bsize " Border smoothness" 400.0 100.0 700.0 10.0
|
#pragma parameter bsize1 " Border Size" 0.01 0.0 3.0 0.01
|
||||||
#define bsize global.bsize // border smoothness
|
#define bsize1 global.bsize1 // border size
|
||||||
|
|
||||||
|
#pragma parameter sborder " Border Intensity" 0.75 0.25 2.0 0.05
|
||||||
|
#define sborder global.sborder // border intensity
|
||||||
|
|
||||||
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
||||||
|
|
||||||
|
@ -84,9 +96,15 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
||||||
#define glow params.glow // Glow Strength
|
#define glow params.glow // Glow Strength
|
||||||
|
|
||||||
#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05
|
#pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05
|
||||||
#define bloom params.bloom // bloom effect
|
#define bloom params.bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter mask_bloom " Mask Bloom" 0.0 0.0 2.0 0.05
|
||||||
|
#define mask_bloom params.mask_bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter bloom_dist " Bloom Distribution" 0.0 0.0 3.0 0.05
|
||||||
|
#define bloom_dist global.bloom_dist // bloom effect distribution
|
||||||
|
|
||||||
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
||||||
#define halation params.halation // halation effect
|
#define halation params.halation // halation effect
|
||||||
|
|
||||||
|
@ -104,16 +122,16 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
||||||
#define gsl params.gsl // Alternate scanlines
|
#define gsl params.gsl // Alternate scanlines
|
||||||
|
|
||||||
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 0.0 20.0 0.5
|
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
||||||
|
|
||||||
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 3.0 40.0 1.0
|
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 3.0 70.0 1.0
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
||||||
|
|
||||||
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 0.05
|
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 5.0 0.05
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
#define beam_min params.beam_min // dark area beam min - narrow
|
||||||
|
|
||||||
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 2.5 0.05
|
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
#define beam_max params.beam_max // bright area beam max - wide
|
||||||
|
|
||||||
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
||||||
|
@ -122,49 +140,13 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
||||||
#define vertmask params.vertmask // Scanline deconvergence colors
|
#define vertmask params.vertmask // Scanline deconvergence colors
|
||||||
|
|
||||||
#pragma parameter scans " Scanline Saturation" 0.60 0.0 1.0 0.05
|
#pragma parameter scans " Scanline Saturation / Mask Falloff" 0.60 0.0 2.5 0.05
|
||||||
#define scans params.scans // scanline saturation
|
#define scans params.scans // scanline saturation
|
||||||
|
|
||||||
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.25 2.0 0.05
|
||||||
|
#define scan_falloff global.scan_falloff // scanline falloff
|
||||||
|
|
||||||
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0
|
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
|
||||||
|
|
||||||
#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05
|
|
||||||
#define maskstr params.maskstr // CGWG Mask Strength
|
|
||||||
|
|
||||||
#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05
|
|
||||||
#define mcut params.mcut // Mask 5-7 dark color strength
|
|
||||||
|
|
||||||
#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0
|
|
||||||
#define masksize params.masksize // Mask Size
|
|
||||||
|
|
||||||
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
|
||||||
#define maskDark params.maskDark // Dark "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
|
||||||
|
|
||||||
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask params.slotmask
|
|
||||||
|
|
||||||
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask1 global.slotmask1
|
|
||||||
|
|
||||||
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 6.0 0.5
|
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
|
||||||
|
|
||||||
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
|
||||||
|
|
||||||
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
|
||||||
#define slotms params.slotms // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05
|
|
||||||
#define mclip params.mclip // Slot Mask Size
|
|
||||||
|
|
||||||
#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05
|
|
||||||
#define gamma_out params.gamma_out // output gamma
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
#define TEX0 vTexCoord
|
#define TEX0 vTexCoord
|
||||||
|
@ -180,13 +162,13 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord * 1.000001;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
layout(set = 0, binding = 2) uniform sampler2D Pass1;
|
||||||
layout(set = 0, binding = 3) uniform sampler2D LinearizePass;
|
layout(set = 0, binding = 3) uniform sampler2D LinearizePass;
|
||||||
layout(set = 0, binding = 4) uniform sampler2D BloomPass;
|
layout(set = 0, binding = 4) uniform sampler2D BloomPass;
|
||||||
layout(set = 0, binding = 5) uniform sampler2D PrePass;
|
layout(set = 0, binding = 5) uniform sampler2D PrePass;
|
||||||
|
@ -222,155 +204,6 @@ float sw2(float x, float color, float scanline)
|
||||||
return exp2(-scanline*ex*ex);
|
return exp2(-scanline*ex*ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shadow mask (1-4 from PD CRT Lottes shader).
|
|
||||||
|
|
||||||
vec3 Mask(vec2 pos, float mx)
|
|
||||||
{
|
|
||||||
pos = floor(pos/masksize);
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
|
||||||
vec3 one = vec3(1.0);
|
|
||||||
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 0.0) + 1.0, 1.0, mx);
|
|
||||||
float mc = 1.0 - max(maskstr, 0.0);
|
|
||||||
|
|
||||||
// No mask
|
|
||||||
if (shadowMask == -1.0)
|
|
||||||
{
|
|
||||||
mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phosphor.
|
|
||||||
else if (shadowMask == 0.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x*0.5);
|
|
||||||
if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
|
||||||
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very compressed TV style shadow mask.
|
|
||||||
else if (shadowMask == 1.0)
|
|
||||||
{
|
|
||||||
float line = maskLight;
|
|
||||||
float odd = 0.0;
|
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
|
||||||
odd = 1.0;
|
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
|
||||||
line = maskDark;
|
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
|
|
||||||
mask*=line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aperture-grille.
|
|
||||||
else if (shadowMask == 2.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stretched VGA style shadow mask (same as prior shaders).
|
|
||||||
else if (shadowMask == 3.0)
|
|
||||||
{
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA style shadow mask.
|
|
||||||
else if (shadowMask == 4.0)
|
|
||||||
{
|
|
||||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 5
|
|
||||||
else if (shadowMask == 5.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5)
|
|
||||||
{ mask.r = 1.0;
|
|
||||||
mask.b = 1.0;
|
|
||||||
}
|
|
||||||
else mask.g = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trinitron mask 6
|
|
||||||
else if (shadowMask == 6.0)
|
|
||||||
{
|
|
||||||
mask = vec3(0.0);
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
if (pos.x < 0.333) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.666) mask.g = 1.0;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BW Trinitron mask 7
|
|
||||||
else if (shadowMask == 7.0)
|
|
||||||
{
|
|
||||||
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
|
||||||
mask = vec3(maskTmp);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5) mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4k mask
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mask = vec3(mc);
|
|
||||||
pos.x = fract(pos.x * 0.25);
|
|
||||||
if (pos.x < 0.2) mask.r = 1.0;
|
|
||||||
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
|
||||||
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
|
||||||
else mask.b = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SlotMask(vec2 pos, float m)
|
|
||||||
{
|
|
||||||
if (slotmask == 0.0) return 1.0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pos = floor(pos/slotms);
|
|
||||||
float mlen = slotwidth*2.0;
|
|
||||||
float px = fract(pos.x/mlen);
|
|
||||||
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
|
||||||
float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m);
|
|
||||||
float slot = 1.0;
|
|
||||||
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
|
||||||
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec3 declip(vec3 c, float b)
|
|
||||||
{
|
|
||||||
float m = max(max(c.r,c.g),c.b);
|
|
||||||
if (m > b) c = c*b/m;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 gc(vec3 c)
|
vec3 gc(vec3 c)
|
||||||
{
|
{
|
||||||
|
@ -379,12 +212,6 @@ vec3 gc(vec3 c)
|
||||||
return c * mg/(mc + eps);
|
return c * mg/(mc + eps);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 plant (vec3 tar, float r)
|
|
||||||
{
|
|
||||||
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
|
||||||
return tar * r / t;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Overscan(vec2 pos, float dx, float dy){
|
vec2 Overscan(vec2 pos, float dx, float dy){
|
||||||
pos=pos*2.0-1.0;
|
pos=pos*2.0-1.0;
|
||||||
pos*=vec2(dx,dy);
|
pos*=vec2(dx,dy);
|
||||||
|
@ -398,34 +225,13 @@ vec2 Warp(vec2 pos)
|
||||||
return pos*0.5 + 0.5;
|
return pos*0.5 + 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
float humbar(float pos)
|
|
||||||
{
|
|
||||||
if (global.barintensity == 0.0) return 1.0; else
|
|
||||||
{
|
|
||||||
pos = (global.barintensity >= 0.0) ? pos : (1.0-pos);
|
|
||||||
pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0));
|
|
||||||
pos = (global.barintensity < 0.0) ? pos : (1.0-pos);
|
|
||||||
return (1.0-global.barintensity) + global.barintensity*pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Borrowed from cgwg's crt-geom, under GPL
|
|
||||||
|
|
||||||
float corner(vec2 coord)
|
|
||||||
{
|
|
||||||
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
|
|
||||||
vec2 cdist = vec2(max(csize/3.0, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002)));
|
|
||||||
coord = (cdist - min(coord,cdist));
|
|
||||||
float dist = sqrt(dot(coord,coord));
|
|
||||||
return clamp((cdist.x-dist)*bsize,0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 SourceSize = vec4(global.SourceSize.x, global.OriginalSize.y, global.SourceSize.z, global.OriginalSize.w);
|
vec4 SourceSize = vec4(global.SourceSize.x, global.OriginalSize.y, global.SourceSize.z, global.OriginalSize.w);
|
||||||
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
||||||
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
||||||
bool interb = (intera < 0.75);
|
bool interb = (intera < 0.5);
|
||||||
|
|
||||||
float SourceY = SourceSize.y;
|
float SourceY = SourceSize.y;
|
||||||
float sy = 1.0;
|
float sy = 1.0;
|
||||||
|
@ -438,7 +244,7 @@ void main()
|
||||||
|
|
||||||
vec2 texcoord = TEX0.xy;
|
vec2 texcoord = TEX0.xy;
|
||||||
|
|
||||||
if (IOS > 0.0){
|
if (IOS > 0.0 && !interb){
|
||||||
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
||||||
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
||||||
vec2 diff = ofactor/intfactor;
|
vec2 diff = ofactor/intfactor;
|
||||||
|
@ -447,9 +253,9 @@ void main()
|
||||||
if (IOS == 1.0 || IOS == 3.0) texcoord = vec2(TEX0.x, texcoord.y);
|
if (IOS == 1.0 || IOS == 3.0) texcoord = vec2(TEX0.x, texcoord.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
texcoord = Overscan(texcoord, (global.OriginalSize.x - overscanX)/global.OriginalSize.x, (global.OriginalSize.y - overscanY)/global.OriginalSize.y);
|
||||||
|
|
||||||
vec2 pos = Warp(texcoord);
|
vec2 pos = Warp(texcoord);
|
||||||
vec2 cpos = (IOS > 2.5) ? TEX0 : texcoord;
|
|
||||||
float corner0 = corner(Warp(cpos));
|
|
||||||
|
|
||||||
float coffset = 0.5;
|
float coffset = 0.5;
|
||||||
|
|
||||||
|
@ -469,17 +275,17 @@ void main()
|
||||||
|
|
||||||
if (interb) pC4.y = pos.y;
|
if (interb) pC4.y = pos.y;
|
||||||
|
|
||||||
vec3 color1 = COMPAT_TEXTURE(Source, pC4 ).rgb;
|
vec3 color1 = COMPAT_TEXTURE(Pass1, pC4 ).rgb;
|
||||||
vec3 scolor1 = COMPAT_TEXTURE(Source, pC4 ).aaa;
|
vec3 scolor1 = COMPAT_TEXTURE(Pass1, pC4 ).aaa;
|
||||||
|
|
||||||
pC4+=dy;
|
pC4+=dy;
|
||||||
|
|
||||||
vec3 color2 = COMPAT_TEXTURE(Source, pC4 ).rgb;
|
vec3 color2 = COMPAT_TEXTURE(Pass1, pC4 ).rgb;
|
||||||
vec3 scolor2 = COMPAT_TEXTURE(Source, pC4 ).aaa;
|
vec3 scolor2 = COMPAT_TEXTURE(Pass1, pC4 ).aaa;
|
||||||
|
|
||||||
// calculating scanlines
|
// calculating scanlines
|
||||||
|
|
||||||
vec3 ctmp; vec3 mcolor; float w3; vec3 color;
|
vec3 ctmp = color1; float w3 = 1.0; vec3 color = color1;
|
||||||
vec3 one = vec3(1.0);
|
vec3 one = vec3(1.0);
|
||||||
|
|
||||||
if (!interb)
|
if (!interb)
|
||||||
|
@ -495,12 +301,11 @@ if (!interb)
|
||||||
|
|
||||||
ctmp = color00/(wt1+wt2);
|
ctmp = color00/(wt1+wt2);
|
||||||
vec3 sctmp = max(scolor0/(wt1+wt2), ctmp);
|
vec3 sctmp = max(scolor0/(wt1+wt2), ctmp);
|
||||||
mcolor = sctmp;
|
|
||||||
|
|
||||||
float wf1, wf2;
|
float wf1, wf2;
|
||||||
|
|
||||||
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b);
|
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = pow(max(max(cref1.r,cref1.g),cref1.b), scan_falloff);
|
||||||
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b);
|
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = pow(max(max(cref2.r,cref2.g),cref2.b), scan_falloff);
|
||||||
|
|
||||||
float f1 = f;
|
float f1 = f;
|
||||||
float f2 = 1.0-f;
|
float f2 = 1.0-f;
|
||||||
|
@ -516,11 +321,16 @@ if (!interb)
|
||||||
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
||||||
w3 = wf1+wf2;
|
w3 = wf1+wf2;
|
||||||
|
|
||||||
cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001);
|
float mc1 = max(max(color1.r,color1.g),color1.b) + eps;
|
||||||
cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001);
|
float mc2 = max(max(color2.r,color2.g),color2.b) + eps;
|
||||||
|
|
||||||
w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1);
|
cref1 = color1 / mc1; cref1=cref1*cref1; cref1*=cref1;
|
||||||
w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2);
|
cref2 = color2 / mc2; cref2=cref2*cref2; cref2*=cref2;
|
||||||
|
|
||||||
|
w1 = max( mix(w1*mix(one, cref1, scans), w1, wf1*min((1.0+0.15*scans), 1.2)), 0.0); w1 = min(w1*color1, mc1)/(color1 + eps);
|
||||||
|
w2 = max( mix(w2*mix(one, cref2, scans), w2, wf2*min((1.0+0.15*scans), 1.2)), 0.0); w2 = min(w2*color2, mc2)/(color2 + eps);
|
||||||
|
|
||||||
|
// Scanline Deconvergence
|
||||||
|
|
||||||
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
||||||
|
|
||||||
|
@ -549,53 +359,9 @@ if (!interb)
|
||||||
if (interb)
|
if (interb)
|
||||||
{
|
{
|
||||||
color = gc(color1);
|
color = gc(color1);
|
||||||
mcolor = clamp(mix(color1, scolor1, 1.25), 0.0, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float mx = max(max(mcolor.r,mcolor.g),mcolor.b);
|
float colmx = pow(max(max(ctmp.r,ctmp.g),ctmp.b), 1.40/gamma_in);
|
||||||
mx = pow(mx, 1.20/gamma_in);
|
|
||||||
|
|
||||||
// Apply Mask
|
FragColor = vec4(color, colmx);
|
||||||
|
|
||||||
vec3 orig1 = color;
|
|
||||||
vec3 cmask = one;
|
|
||||||
|
|
||||||
float smask = SlotMask(gl_FragCoord.xy * 1.000001, mx);
|
|
||||||
cmask*= Mask(gl_FragCoord.xy * 1.000001, mx);
|
|
||||||
|
|
||||||
color = color*cmask;
|
|
||||||
color = min(color,1.0);
|
|
||||||
color = color*smask;
|
|
||||||
|
|
||||||
cmask = min(cmask*smask, 1.0);
|
|
||||||
|
|
||||||
if (interb) ctmp = color;
|
|
||||||
float colmx = pow( max( max(ctmp.r, ctmp.g), ctmp.b), 1.40/gamma_out);
|
|
||||||
float bb = mix(brightboost, brightboost1, colmx);
|
|
||||||
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
|
||||||
color*=bb;
|
|
||||||
|
|
||||||
vec3 Glow = COMPAT_TEXTURE(BloomPass, pos ).rgb;
|
|
||||||
vec3 Bloom = Glow;
|
|
||||||
float maxb = COMPAT_TEXTURE(BloomPass, pos ).a;
|
|
||||||
float vig = COMPAT_TEXTURE(PrePass, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a;
|
|
||||||
|
|
||||||
vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0));
|
|
||||||
color = color + bloom*Bloom1;
|
|
||||||
|
|
||||||
color = min(color, mix(one, cmask, mclip));
|
|
||||||
if (!interb) color = declip(color, pow(w3,0.60));
|
|
||||||
|
|
||||||
if (halation > 0.025) {
|
|
||||||
Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx);
|
|
||||||
color = color + (1.1-0.25*colmx)*(0.75+maxb)*Bloom*(0.75 + 0.70*pow(colmx,0.33333))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; }
|
|
||||||
|
|
||||||
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
|
||||||
if (glow >= 0.0) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + (-glow)*cmask*Glow; }
|
|
||||||
|
|
||||||
color = min(color, 1.0);
|
|
||||||
|
|
||||||
color = pow(color, vec3(1.0/gamma_out));
|
|
||||||
|
|
||||||
FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir)), corner0);
|
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
CRT - Guest - Advanced - Fastest - Pass2
|
CRT - Guest - Advanced - Fastest - Pass2
|
||||||
|
|
||||||
Copyright (C) 2018-2021 guest(r) - guest.r@gmail.com
|
Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
@ -44,6 +44,10 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
float bsize;
|
float bsize;
|
||||||
float c_shape;
|
float c_shape;
|
||||||
float slotmask1;
|
float slotmask1;
|
||||||
|
float scan_falloff;
|
||||||
|
float bloom_dist;
|
||||||
|
float mshift;
|
||||||
|
float mask_layout;
|
||||||
} global;
|
} global;
|
||||||
|
|
||||||
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
@ -60,7 +64,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
||||||
#define c_shape global.c_shape // curvature shape
|
#define c_shape global.c_shape // curvature shape
|
||||||
|
|
||||||
#pragma parameter csize " Corner size" 0.0 0.0 0.25 0.01
|
#pragma parameter csize " Corner Size" 0.0 0.0 0.25 0.01
|
||||||
#define csize global.csize // corner size
|
#define csize global.csize // corner size
|
||||||
|
|
||||||
#pragma parameter bsize " Border smoothness" 400.0 100.0 700.0 10.0
|
#pragma parameter bsize " Border smoothness" 400.0 100.0 700.0 10.0
|
||||||
|
@ -74,6 +78,9 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05
|
#pragma parameter bloom " Bloom Strength" 0.0 0.0 2.0 0.05
|
||||||
#define bloom params.bloom // bloom effect
|
#define bloom params.bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter bloom_dist " Bloom Distribution" 0.0 0.0 3.0 0.05
|
||||||
|
#define bloom_dist global.bloom_dist // bloom effect distribution
|
||||||
|
|
||||||
#pragma parameter halation " Halation Strength" 0.0 0.0 1.0 0.025
|
#pragma parameter halation " Halation Strength" 0.0 0.0 1.0 0.025
|
||||||
#define halation params.halation // halation effect
|
#define halation params.halation // halation effect
|
||||||
|
|
||||||
|
@ -91,16 +98,16 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
||||||
#define gsl params.gsl // Alternate scanlines
|
#define gsl params.gsl // Alternate scanlines
|
||||||
|
|
||||||
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 0.0 20.0 0.5
|
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
||||||
|
|
||||||
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 3.0 40.0 1.0
|
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 3.0 70.0 1.0
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
||||||
|
|
||||||
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 3.5 0.05
|
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.30 0.25 5.0 0.05
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
#define beam_min params.beam_min // dark area beam min - narrow
|
||||||
|
|
||||||
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 2.5 0.05
|
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
#define beam_max params.beam_max // bright area beam max - wide
|
||||||
|
|
||||||
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
||||||
|
@ -109,21 +116,24 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
||||||
#define vertmask params.vertmask // Scanline deconvergence colors
|
#define vertmask params.vertmask // Scanline deconvergence colors
|
||||||
|
|
||||||
#pragma parameter scans " Scanline Saturation" 0.60 0.0 1.0 0.05
|
#pragma parameter scans " Scanline Saturation / Mask Falloff" 0.60 0.0 3.5 0.05
|
||||||
#define scans params.scans // scanline saturation
|
#define scans params.scans // scanline saturation
|
||||||
|
|
||||||
|
#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.25 2.0 0.05
|
||||||
|
#define scan_falloff global.scan_falloff // scanline falloff
|
||||||
|
|
||||||
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-7:'Trinitron'" 0.0 -1.0 8.0 1.0
|
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-12:'Trinitron'" 0.0 -1.0 12.0 1.0
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
#define shadowMask params.shadowMask // Mask Style
|
||||||
|
|
||||||
#pragma parameter maskstr " Mask Strength (0, 5-8)" 0.3 -0.5 1.0 0.05
|
#pragma parameter maskstr " Mask Strength (0, 5-12)" 0.3 -0.5 1.0 0.025
|
||||||
#define maskstr params.maskstr // CGWG Mask Strength
|
#define maskstr params.maskstr // Mask Strength
|
||||||
|
|
||||||
#pragma parameter mcut " Mask 5-7 Low Strength" 1.10 0.0 2.0 0.05
|
#pragma parameter mcut " Mask 5-12 Low Strength" 1.10 0.0 2.0 0.05
|
||||||
#define mcut params.mcut // Mask 5-7 dark color strength
|
#define mcut params.mcut // Mask 5-12 dark color strength
|
||||||
|
|
||||||
#pragma parameter masksize " CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 4.0 1.0
|
#pragma parameter masksize " CRT Mask Size" 1.0 1.0 4.0 1.0
|
||||||
#define masksize params.masksize // Mask Size
|
#define masksize params.masksize // Mask Size
|
||||||
|
|
||||||
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
||||||
|
@ -132,16 +142,22 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
#define maskLight params.maskLight // Light "Phosphor"
|
||||||
|
|
||||||
|
#pragma parameter mshift " Mask Shift/Stagger" 0.0 -8.0 8.0 1.0
|
||||||
|
#define mshift global.mshift // mask 'line' shift/stagger
|
||||||
|
|
||||||
|
#pragma parameter mask_layout " Mask Layout: RGB or BGR (check LCD panel) " 0.0 0.0 1.0 1.0
|
||||||
|
#define mask_layout global.mask_layout // mask layout: RGB or BGR
|
||||||
|
|
||||||
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
||||||
#define slotmask params.slotmask
|
#define slotmask params.slotmask
|
||||||
|
|
||||||
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
||||||
#define slotmask1 global.slotmask1
|
#define slotmask1 global.slotmask1
|
||||||
|
|
||||||
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 6.0 0.5
|
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
#define slotwidth params.slotwidth // Slot Mask Width
|
||||||
|
|
||||||
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
#define double_slot params.double_slot // Slot Mask Height
|
||||||
|
|
||||||
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
||||||
|
@ -166,6 +182,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // Joint parameter with linearize pass, values must match
|
#pragma parameter inters " Interlacing Effect Smoothness" 0.0 0.0 0.5 0.05 // Joint parameter with linearize pass, values must match
|
||||||
#define inters params.inters // interlacing effect smoothing
|
#define inters params.inters // interlacing effect smoothing
|
||||||
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
#define TEX0 vTexCoord
|
#define TEX0 vTexCoord
|
||||||
|
|
||||||
|
@ -227,10 +244,15 @@ float sw2(float x, float color, float scanline)
|
||||||
|
|
||||||
vec3 Mask(vec2 pos, float mx)
|
vec3 Mask(vec2 pos, float mx)
|
||||||
{
|
{
|
||||||
pos = floor(pos/masksize);
|
vec2 pos0 = pos;
|
||||||
|
pos.y = floor(pos.y/masksize);
|
||||||
|
float next_line = float(fract(pos.y*0.5) > 0.25);
|
||||||
|
pos0.x = pos0.x + next_line * mshift;
|
||||||
|
pos = floor(pos0/masksize);
|
||||||
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
||||||
vec3 one = vec3(1.0);
|
vec3 one = vec3(1.0);
|
||||||
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.3, 0.0) + 1.0, 1.0, mx);
|
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.4, 0.0) + 1.0, 1.0, mx);
|
||||||
float mc = 1.0 - max(maskstr, 0.0);
|
float mc = 1.0 - max(maskstr, 0.0);
|
||||||
|
|
||||||
// No mask
|
// No mask
|
||||||
|
@ -243,7 +265,7 @@ vec3 Mask(vec2 pos, float mx)
|
||||||
else if (shadowMask == 0.0)
|
else if (shadowMask == 0.0)
|
||||||
{
|
{
|
||||||
pos.x = fract(pos.x*0.5);
|
pos.x = fract(pos.x*0.5);
|
||||||
if (pos.x < 0.5) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
||||||
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,15 +275,15 @@ vec3 Mask(vec2 pos, float mx)
|
||||||
float line = maskLight;
|
float line = maskLight;
|
||||||
float odd = 0.0;
|
float odd = 0.0;
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
if (fract(pos.x/6.0) < 0.49)
|
||||||
odd = 1.0;
|
odd = 1.0;
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
if (fract((pos.y + odd)/2.0) < 0.49)
|
||||||
line = maskDark;
|
line = maskDark;
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
else mask.b = maskLight;
|
else mask.b = maskLight;
|
||||||
|
|
||||||
mask*=line;
|
mask*=line;
|
||||||
|
@ -272,8 +294,8 @@ vec3 Mask(vec2 pos, float mx)
|
||||||
{
|
{
|
||||||
pos.x = fract(pos.x/3.0);
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
else mask.b = maskLight;
|
else mask.b = maskLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,8 +305,8 @@ vec3 Mask(vec2 pos, float mx)
|
||||||
pos.x += pos.y*3.0;
|
pos.x += pos.y*3.0;
|
||||||
pos.x = fract(pos.x/6.0);
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
else mask.b = maskLight;
|
else mask.b = maskLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,8 +317,8 @@ vec3 Mask(vec2 pos, float mx)
|
||||||
pos.x += pos.y*3.0;
|
pos.x += pos.y*3.0;
|
||||||
pos.x = fract(pos.x/6.0);
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
else mask.b = maskLight;
|
else mask.b = maskLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +327,7 @@ vec3 Mask(vec2 pos, float mx)
|
||||||
{
|
{
|
||||||
mask = vec3(0.0);
|
mask = vec3(0.0);
|
||||||
pos.x = fract(pos.x/2.0);
|
pos.x = fract(pos.x/2.0);
|
||||||
if (pos.x < 0.5)
|
if (pos.x < 0.49)
|
||||||
{ mask.r = 1.0;
|
{ mask.r = 1.0;
|
||||||
mask.b = 1.0;
|
mask.b = 1.0;
|
||||||
}
|
}
|
||||||
|
@ -318,8 +340,8 @@ vec3 Mask(vec2 pos, float mx)
|
||||||
{
|
{
|
||||||
mask = vec3(0.0);
|
mask = vec3(0.0);
|
||||||
pos.x = fract(pos.x/3.0);
|
pos.x = fract(pos.x/3.0);
|
||||||
if (pos.x < 0.333) mask.r = 1.0;
|
if (pos.x < 0.3) mask.r = 1.0;
|
||||||
else if (pos.x < 0.666) mask.g = 1.0;
|
else if (pos.x < 0.6) mask.g = 1.0;
|
||||||
else mask.b = 1.0;
|
else mask.b = 1.0;
|
||||||
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
}
|
}
|
||||||
|
@ -327,14 +349,51 @@ vec3 Mask(vec2 pos, float mx)
|
||||||
// BW Trinitron mask 7
|
// BW Trinitron mask 7
|
||||||
else if (shadowMask == 7.0)
|
else if (shadowMask == 7.0)
|
||||||
{
|
{
|
||||||
float maskTmp = clamp(mix( mix(1.0, 0.0, mcut), mix(1.0, 0.0, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
mask = vec3(0.0);
|
||||||
mask = vec3(maskTmp);
|
|
||||||
pos.x = fract(pos.x/2.0);
|
pos.x = fract(pos.x/2.0);
|
||||||
if (pos.x < 0.5) mask = vec3(1.0);
|
if (pos.x < 0.49)
|
||||||
|
{ mask = 0.0.xxx;
|
||||||
|
}
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BW Trinitron mask 8
|
||||||
|
else if (shadowMask == 8.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask = 1.0.xxx;
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magenta - Green - Black mask
|
||||||
|
else if (shadowMask == 9.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask.rb = 1.0.xx;
|
||||||
|
else mask.g = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RGBX
|
||||||
|
else if (shadowMask == 10.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.4) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.7) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4k mask
|
// 4k mask
|
||||||
else
|
else if (shadowMask == 11.0)
|
||||||
{
|
{
|
||||||
mask = vec3(mc);
|
mask = vec3(mc);
|
||||||
pos.x = fract(pos.x * 0.25);
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
@ -343,13 +402,34 @@ vec3 Mask(vec2 pos, float mx)
|
||||||
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
||||||
else mask.b = 1.0;
|
else mask.b = 1.0;
|
||||||
}
|
}
|
||||||
|
else if (shadowMask == 12.0)
|
||||||
|
{
|
||||||
|
mask = vec3(mc);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.4) mask.rb = 1.0.xx;
|
||||||
|
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
||||||
|
else mask.g = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RRGGBBX mask
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = floor(mod(pos.x,7.0));
|
||||||
|
if (pos.x < 1.0) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 3.0) mask.r = 1.0;
|
||||||
|
else if (pos.x < 5.0) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SlotMask(vec2 pos, float m)
|
float SlotMask(vec2 pos, float m)
|
||||||
{
|
{
|
||||||
if (slotmask == 0.0) return 1.0;
|
if (slotmask == 0.0 && slotmask1 == 0.0) return 1.0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pos = floor(pos/slotms);
|
pos = floor(pos/slotms);
|
||||||
|
@ -431,7 +511,7 @@ void main()
|
||||||
|
|
||||||
vec2 texcoord = TEX0.xy;
|
vec2 texcoord = TEX0.xy;
|
||||||
|
|
||||||
if (IOS > 0.0){
|
if (IOS > 0.0 && !interb){
|
||||||
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
||||||
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
||||||
vec2 diff = ofactor/intfactor;
|
vec2 diff = ofactor/intfactor;
|
||||||
|
@ -510,7 +590,7 @@ if ( not_same || frames || interb )
|
||||||
|
|
||||||
// calculating scanlines
|
// calculating scanlines
|
||||||
|
|
||||||
vec3 ctmp; vec3 mcolor; float w3; vec3 color;
|
vec3 ctmp = color1; vec3 mcolor = scolor1; float w3 = 1.0; vec3 color = color1;
|
||||||
vec3 one = vec3(1.0);
|
vec3 one = vec3(1.0);
|
||||||
|
|
||||||
if (!interb)
|
if (!interb)
|
||||||
|
@ -530,8 +610,8 @@ if (!interb)
|
||||||
|
|
||||||
float wf1, wf2;
|
float wf1, wf2;
|
||||||
|
|
||||||
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = max(max(cref1.r,cref1.g),cref1.b);
|
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = pow(max(max(cref1.r,cref1.g),cref1.b), scan_falloff);
|
||||||
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = max(max(cref2.r,cref2.g),cref2.b);
|
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = pow(max(max(cref2.r,cref2.g),cref2.b), scan_falloff);
|
||||||
|
|
||||||
float f1 = f;
|
float f1 = f;
|
||||||
float f2 = 1.0-f;
|
float f2 = 1.0-f;
|
||||||
|
@ -547,11 +627,16 @@ if (!interb)
|
||||||
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
||||||
w3 = wf1+wf2;
|
w3 = wf1+wf2;
|
||||||
|
|
||||||
cref1 = color1 / (max(max(color1.r,color1.g),color1.b) + 0.00001);
|
float mc1 = max(max(color1.r,color1.g),color1.b) + eps;
|
||||||
cref2 = color2 / (max(max(color2.r,color2.g),color2.b) + 0.00001);
|
float mc2 = max(max(color2.r,color2.g),color2.b) + eps;
|
||||||
|
|
||||||
w1 = mix(w1*mix(one, cref1*cref1*cref1, scans), w1, wf1);
|
cref1 = color1 / mc1; cref1=cref1*cref1; cref1*=cref1;
|
||||||
w2 = mix(w2*mix(one, cref2*cref2*cref2, scans), w2, wf2);
|
cref2 = color2 / mc2; cref2=cref2*cref2; cref2*=cref2;
|
||||||
|
|
||||||
|
w1 = max( mix(w1*mix(one, cref1, scans), w1, wf1*min((1.0+0.15*scans), 1.2)), 0.0); w1 = min(w1*color1, mc1)/(color1 + eps);
|
||||||
|
w2 = max( mix(w2*mix(one, cref2, scans), w2, wf2*min((1.0+0.15*scans), 1.2)), 0.0); w2 = min(w2*color2, mc2)/(color2 + eps);
|
||||||
|
|
||||||
|
// Scanline Deconvergence
|
||||||
|
|
||||||
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
||||||
|
|
||||||
|
@ -579,8 +664,8 @@ if (!interb)
|
||||||
|
|
||||||
if (interb)
|
if (interb)
|
||||||
{
|
{
|
||||||
color = gc(0.5*(color1+color2));
|
color = gc(color1);
|
||||||
mcolor = clamp(mix(color1, scolor1, 1.25), 0.0, 1.0);
|
mcolor = scolor1;
|
||||||
}
|
}
|
||||||
|
|
||||||
float mx = max(max(mcolor.r,mcolor.g),mcolor.b);
|
float mx = max(max(mcolor.r,mcolor.g),mcolor.b);
|
||||||
|
@ -594,6 +679,8 @@ if (!interb)
|
||||||
float smask = SlotMask(gl_FragCoord.xy * 1.000001, mx);
|
float smask = SlotMask(gl_FragCoord.xy * 1.000001, mx);
|
||||||
cmask*= Mask(gl_FragCoord.xy * 1.000001, mx);
|
cmask*= Mask(gl_FragCoord.xy * 1.000001, mx);
|
||||||
|
|
||||||
|
if (mask_layout > 0.5) cmask = cmask.rbg;
|
||||||
|
|
||||||
color = color*cmask;
|
color = color*cmask;
|
||||||
color = min(color,1.0);
|
color = min(color,1.0);
|
||||||
color = color*smask;
|
color = color*smask;
|
||||||
|
@ -612,13 +699,17 @@ if (!interb)
|
||||||
vec3 Bloom = Glow;
|
vec3 Bloom = Glow;
|
||||||
|
|
||||||
vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0));
|
vec3 Bloom1 = min(Bloom*(orig1+color), max(0.5*(colmx + orig1 - color),0.0));
|
||||||
|
Bloom1 = 0.5*(Bloom1 + mix(Bloom1, mix(colmx*orig1, Bloom1, 0.5), 1.0-color));
|
||||||
|
|
||||||
|
Bloom1 = Bloom1 * mix(1.0, 2.0-colmx, bloom_dist);
|
||||||
|
|
||||||
color = color + bloom * Bloom1;
|
color = color + bloom * Bloom1;
|
||||||
|
|
||||||
color = min(color, mix(one, cmask, mclip));
|
color = min(color, mix(one, cmask, mclip));
|
||||||
if (!interb) color = declip(color, pow(w3,0.60));
|
if (!interb) color = declip(color, pow(w3,0.60));
|
||||||
|
|
||||||
if (halation > 0.025) {
|
if (halation > 0.025) {
|
||||||
Bloom = mix(0.5*(Bloom + Bloom*Bloom), Bloom*Bloom, colmx);
|
Bloom = mix(0.5*(Bloom + Bloom*Bloom), 0.75*Bloom*Bloom, colmx);
|
||||||
color = color + 0.75*(0.75+maxb)*Bloom*(0.4+sqrt(colmx))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; }
|
color = color + 0.75*(0.75+maxb)*Bloom*(0.4+sqrt(colmx))*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.35 + 0.4*maxb)*halation; }
|
||||||
|
|
||||||
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
||||||
|
@ -628,6 +719,7 @@ if (!interb)
|
||||||
color = min(color, 1.0);
|
color = min(color, 1.0);
|
||||||
|
|
||||||
result = vec4(color*corner0, corner0);
|
result = vec4(color*corner0, corner0);
|
||||||
|
|
||||||
}
|
}
|
||||||
FragColor = result;
|
FragColor = result;
|
||||||
}
|
}
|
|
@ -1,126 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - Dr. Venom - Pass1
|
|
||||||
|
|
||||||
Copyright (C) 2018-2019 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float h_sharp;
|
|
||||||
float s_sharp;
|
|
||||||
float h_smart;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter h_sharp "Horizontal sharpness" 5.00 1.5 20.0 0.25
|
|
||||||
#define h_sharp params.h_sharp
|
|
||||||
#pragma parameter s_sharp "Substractive sharpness" 0.05 0.0 0.20 0.01
|
|
||||||
#define s_sharp params.s_sharp
|
|
||||||
#pragma parameter h_smart "Smart Horizontal Smoothing" 0.0 0.0 1.0 0.1
|
|
||||||
#define h_smart params.h_smart
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
|
|
||||||
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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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 SmoothPass;
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define PassPrev2Texture SmoothPass
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 ps = SourceSize.zw;
|
|
||||||
vec2 OGL2Pos = vTexCoord * SourceSize.xy;
|
|
||||||
vec2 fp = fract(OGL2Pos);
|
|
||||||
vec2 dx = vec2(ps.x,0.0);
|
|
||||||
vec2 dy = vec2(0.0, ps.y);
|
|
||||||
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
|
|
||||||
|
|
||||||
// Reading the texels
|
|
||||||
vec2 x2 = 2.0*dx;
|
|
||||||
vec2 y2 = 2.0*dy;
|
|
||||||
|
|
||||||
bool sharp = (s_sharp > 0.0);
|
|
||||||
|
|
||||||
float hsharp_tl, hsharp_tr, hsharp_tc; float s_sharpl = s_sharp; float s_sharpr = s_sharp; float s_sharpc = s_sharp;
|
|
||||||
|
|
||||||
if (h_smart == 0.0)
|
|
||||||
{
|
|
||||||
hsharp_tl = h_sharp; hsharp_tr = h_sharp; hsharp_tc = h_sharp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// reading differences for smoothing
|
|
||||||
vec2 diffs = COMPAT_TEXTURE(PassPrev2Texture, pC4).xy;
|
|
||||||
|
|
||||||
float ls = mix (4.25, 2.25, h_smart);
|
|
||||||
hsharp_tl = mix(h_sharp, ls, diffs.x);
|
|
||||||
hsharp_tr = mix(h_sharp, ls, diffs.y);
|
|
||||||
|
|
||||||
s_sharpl = mix(s_sharp, 0.0, diffs.x);
|
|
||||||
s_sharpr = mix(s_sharp, 0.0, diffs.y);
|
|
||||||
|
|
||||||
hsharp_tc = hsharp_tl;
|
|
||||||
if (fp.x == 0.5) { hsharp_tc = 0.5*(hsharp_tl + hsharp_tr); s_sharpc = 0.5*(s_sharpl + s_sharpr); }
|
|
||||||
if (fp.x > 0.5) { hsharp_tc = hsharp_tr; }
|
|
||||||
}
|
|
||||||
|
|
||||||
float wl2 = 1.5 + fp.x; wl2*=wl2; float twl2 = exp2(-hsharp_tl*wl2); twl2 = max(twl2 - s_sharpl, -twl2);
|
|
||||||
float wl1 = 0.5 + fp.x; wl1*=wl1; float twl1 = exp2(-hsharp_tl*wl1); twl1 = max(twl1 - s_sharpl, -0.4*s_sharpl);
|
|
||||||
float wct = 0.5 - fp.x; wct*=wct; float twct = exp2(-hsharp_tc*wct); twct = max(twct - s_sharpc, s_sharpc);
|
|
||||||
float wr1 = 1.5 - fp.x; wr1*=wr1; float twr1 = exp2(-hsharp_tr*wr1); twr1 = max(twr1 - s_sharpr, -0.4*s_sharpr);
|
|
||||||
float wr2 = 2.5 - fp.x; wr2*=wr2; float twr2 = exp2(-hsharp_tr*wr2); twr2 = max(twr2 - s_sharpr, -twr2);
|
|
||||||
|
|
||||||
float wtt = 1.0/(twl2+twl1+twct+twr1+twr2);
|
|
||||||
|
|
||||||
vec3 l2 = COMPAT_TEXTURE(Source, pC4 -x2).xyz;
|
|
||||||
vec3 l1 = COMPAT_TEXTURE(Source, pC4 -dx).xyz;
|
|
||||||
vec3 ct = COMPAT_TEXTURE(Source, pC4 ).xyz;
|
|
||||||
vec3 r1 = COMPAT_TEXTURE(Source, pC4 +dx).xyz;
|
|
||||||
vec3 r2 = COMPAT_TEXTURE(Source, pC4 +x2).xyz;
|
|
||||||
|
|
||||||
vec3 color = (l2*twl2 + l1*twl1 + ct*twct + r1*twr1 + r2*twr2)*wtt;
|
|
||||||
if (sharp) color = clamp(color, 0.8*min(min(l1,r1),ct), 1.2*max(max(l1,r1),ct));
|
|
||||||
|
|
||||||
FragColor = vec4(color, 1.0);
|
|
||||||
}
|
|
|
@ -1,328 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
CRT - Guest - Dr. Venom - Pass2
|
|
||||||
|
|
||||||
Copyright (C) 2018-2019 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
Incorporates many good ideas and suggestions from Dr. Venom.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
float brightboost, IOS, gsl, scanline1, scanline2, beam_min, beam_max, s_power, beam_size, shadowMask,
|
|
||||||
masksize, vertmask, slotmask, slotwidth, double_slot, mcut, maskDark, maskLight, CGWG, gamma_out;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter brightboost "Bright boost" 1.30 0.50 2.00 0.01
|
|
||||||
#define brightboost params.brightboost // adjust brightness
|
|
||||||
#pragma parameter IOS "Smart Y Integer Scaling" 0.0 0.0 1.0 1.0
|
|
||||||
#define IOS params.IOS // smart integer scaling
|
|
||||||
#pragma parameter gsl "Scanline Type" 1.0 0.0 2.0 1.0
|
|
||||||
#define gsl params.gsl // Alternate scanlines
|
|
||||||
#pragma parameter scanline1 "Scanline beam shape low" 8.0 1.0 15.0 1.0
|
|
||||||
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
|
||||||
#pragma parameter scanline2 "Scanline beam shape high" 8.0 5.0 23.0 1.0
|
|
||||||
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
|
||||||
#pragma parameter beam_min "Scanline dark" 1.25 0.5 2.0 0.05
|
|
||||||
#define beam_min params.beam_min // dark area beam min - narrow
|
|
||||||
#pragma parameter beam_max "Scanline bright" 1.05 0.5 2.0 0.05
|
|
||||||
#define beam_max params.beam_max // bright area beam max - wide
|
|
||||||
#pragma parameter s_power "Scanline intensity" 1.0 0.5 2.5 0.05
|
|
||||||
#define s_power params.s_power // scanline intensity
|
|
||||||
#pragma parameter beam_size "Increased bright scanline beam" 0.65 0.0 1.0 0.05
|
|
||||||
#define beam_size params.beam_size // increased max. beam size
|
|
||||||
#pragma parameter shadowMask "CRT Mask: 0:CGWG, 1-4:Lottes, 5-6:'Trinitron'" 5.0 -1.0 6.0 1.0
|
|
||||||
#define shadowMask params.shadowMask // Mask Style
|
|
||||||
#pragma parameter masksize "CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.0 1.0
|
|
||||||
#define masksize params.masksize // Mask Size
|
|
||||||
#pragma parameter vertmask "PVM Like Colors" 0.05 0.0 0.25 0.01
|
|
||||||
#define vertmask params.vertmask // Vertical mask
|
|
||||||
#pragma parameter slotmask "Slot Mask Strength" 0.0 0.0 1.0 0.05
|
|
||||||
#define slotmask params.slotmask // Slot Mask ON/OFF
|
|
||||||
#pragma parameter slotwidth "Slot Mask Width" 2.0 2.0 6.0 0.5
|
|
||||||
#define slotwidth params.slotwidth // Slot Mask Width
|
|
||||||
#pragma parameter double_slot "Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
|
|
||||||
#define double_slot params.double_slot // Slot Mask Height
|
|
||||||
#pragma parameter mcut "Mask 5&6 cutoff" 0.2 0.0 0.5 0.05
|
|
||||||
#define mcut params.mcut // Mask 5&6 cutoff
|
|
||||||
#pragma parameter maskDark "Mask Dark" 0.5 0.0 2.0 0.05
|
|
||||||
#define maskDark params.maskDark // Dark "Phosphor"
|
|
||||||
#pragma parameter maskLight "Mask Light" 1.5 0.0 2.0 0.05
|
|
||||||
#define maskLight params.maskLight // Light "Phosphor"
|
|
||||||
#pragma parameter CGWG "CGWG Mask Str." 0.3 0.0 1.0 0.05
|
|
||||||
#define CGWG params.CGWG // CGWG Mask Strength
|
|
||||||
#pragma parameter gamma_out "Gamma out" 2.4 1.0 3.5 0.05
|
|
||||||
#define gamma_out params.gamma_out // output gamma
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
|
||||||
{
|
|
||||||
mat4 MVP;
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
} global;
|
|
||||||
|
|
||||||
#define SourceSize global.SourceSize
|
|
||||||
#define OutputSize global.OutputSize
|
|
||||||
#define FrameCount global.FrameCount
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
#define gl_FragCoord (vTexCoord.xy * OutputSize.xy)
|
|
||||||
#define InputSize SourceSize
|
|
||||||
|
|
||||||
#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.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma stage fragment
|
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
|
||||||
layout(location = 0) out vec4 FragColor;
|
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
|
||||||
|
|
||||||
#define eps 1e-10
|
|
||||||
|
|
||||||
float st(float x, float scanline)
|
|
||||||
{
|
|
||||||
return exp2(-scanline*x*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 sw0(vec3 x, vec3 color, float scanline)
|
|
||||||
{
|
|
||||||
vec3 tmp = mix(vec3(beam_min),vec3(beam_max), color);
|
|
||||||
vec3 ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 sw1(vec3 x, vec3 color, float scanline)
|
|
||||||
{
|
|
||||||
float mx = max(max(color.r, color.g),color.b);
|
|
||||||
x = mix (x, beam_min*x, max(x-0.4*mx,0.0));
|
|
||||||
vec3 tmp = mix(vec3(1.2*beam_min),vec3(beam_max), color);
|
|
||||||
vec3 ex = x*tmp;
|
|
||||||
float br = clamp(0.8*beam_min - 1.0, 0.2, 0.45);
|
|
||||||
return exp2(-scanline*ex*ex)/(1.0-br+br*color);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 sw2(vec3 x, vec3 color, float scanline)
|
|
||||||
{
|
|
||||||
vec3 tmp = mix(vec3(2.75*beam_min),vec3(beam_max), color);
|
|
||||||
tmp = mix(vec3(beam_max), tmp, pow(x, vec3(max(max(color.r, color.g),color.b)+0.3)));
|
|
||||||
vec3 ex = x*tmp;
|
|
||||||
return exp2(-scanline*ex*ex)/(0.6 + 0.4*color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shadow mask (1-4 from PD CRT Lottes shader).
|
|
||||||
vec3 Mask(vec2 pos, vec3 c)
|
|
||||||
{
|
|
||||||
pos = floor(pos/masksize);
|
|
||||||
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
|
||||||
|
|
||||||
|
|
||||||
// No mask
|
|
||||||
if (shadowMask == -1.0)
|
|
||||||
{
|
|
||||||
mask = vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phosphor.
|
|
||||||
else if (shadowMask == 0.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x*0.5);
|
|
||||||
float mc = 1.0 - CGWG;
|
|
||||||
if (pos.x < 0.5) { mask.r = 1.1; mask.g = mc; mask.b = 1.1; }
|
|
||||||
else { mask.r = mc; mask.g = 1.1; mask.b = mc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very compressed TV style shadow mask.
|
|
||||||
else if (shadowMask == 1.0)
|
|
||||||
{
|
|
||||||
float line = maskLight;
|
|
||||||
float odd = 0.0;
|
|
||||||
|
|
||||||
if (fract(pos.x/6.0) < 0.5)
|
|
||||||
odd = 1.0;
|
|
||||||
if (fract((pos.y + odd)/2.0) < 0.5)
|
|
||||||
line = maskDark;
|
|
||||||
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
|
|
||||||
mask*=line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aperture-grille.
|
|
||||||
else if (shadowMask == 2.0)
|
|
||||||
{
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stretched VGA style shadow mask (same as prior shaders).
|
|
||||||
else if (shadowMask == 3.0)
|
|
||||||
{
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA style shadow mask.
|
|
||||||
else if (shadowMask == 4.0)
|
|
||||||
{
|
|
||||||
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
|
||||||
pos.x += pos.y*3.0;
|
|
||||||
pos.x = fract(pos.x/6.0);
|
|
||||||
|
|
||||||
if (pos.x < 0.333) mask.r = maskLight;
|
|
||||||
else if (pos.x < 0.666) mask.g = maskLight;
|
|
||||||
else mask.b = maskLight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alternate mask 5
|
|
||||||
else if (shadowMask == 5.0)
|
|
||||||
{
|
|
||||||
float mx = max(max(c.r,c.g),c.b);
|
|
||||||
vec3 maskTmp = vec3( min( 1.25*max(mx-mcut,0.0)/(1.0-mcut) ,maskDark + 0.2*(1.0-maskDark)*mx));
|
|
||||||
float adj = 0.80*maskLight - 0.5*(0.80*maskLight - 1.0)*mx + 0.75*(1.0-mx);
|
|
||||||
mask = maskTmp;
|
|
||||||
pos.x = fract(pos.x/2.0);
|
|
||||||
if (pos.x < 0.5)
|
|
||||||
{ mask.r = adj;
|
|
||||||
mask.b = adj;
|
|
||||||
}
|
|
||||||
else mask.g = adj;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alternate mask 6
|
|
||||||
else if (shadowMask == 6.0)
|
|
||||||
{
|
|
||||||
float mx = max(max(c.r,c.g),c.b);
|
|
||||||
vec3 maskTmp = vec3( min( 1.5*max(mx-mcut,0.0)/(1.0-mcut) ,maskDark + 0.225*(1.0-maskDark)*mx));
|
|
||||||
float adj = 0.80*maskLight - 0.5*(0.80*maskLight - 1.0)*mx + 0.75*(1.0-mx);
|
|
||||||
mask = maskTmp;
|
|
||||||
pos.x = fract(pos.x/3.0);
|
|
||||||
if (pos.x < 0.333) mask.r = adj;
|
|
||||||
else if (pos.x < 0.666) mask.g = adj;
|
|
||||||
else mask.b = adj;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SlotMask(vec2 pos, vec3 c)
|
|
||||||
{
|
|
||||||
if (slotmask == 0.0) return 1.0;
|
|
||||||
|
|
||||||
float mx = pow(max(max(c.r,c.g),c.b),1.33);
|
|
||||||
float mlen = slotwidth*2.0;
|
|
||||||
float px = fract(pos.x/mlen);
|
|
||||||
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
|
||||||
float slot_dark = mix(1.0-slotmask, 1.0-0.80*slotmask, mx);
|
|
||||||
float slot = 1.0 + 0.7*slotmask*(1.0-mx);
|
|
||||||
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
|
||||||
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Overscan2(float pos, float dy){
|
|
||||||
pos=pos*2.0-1.0;
|
|
||||||
pos*=dy;
|
|
||||||
return pos*0.5+0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 texcoord = vTexCoord;
|
|
||||||
|
|
||||||
if (IOS == 1.0){
|
|
||||||
float ofactor = OutputSize.y/InputSize.y;
|
|
||||||
float intfactor = round(ofactor);
|
|
||||||
float diff = ofactor/intfactor;
|
|
||||||
texcoord.y = Overscan2(texcoord.y*(SourceSize.y/InputSize.y), diff)*(InputSize.y/SourceSize.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 ps = SourceSize.zw;
|
|
||||||
vec2 OGL2Pos = texcoord * SourceSize.xy - vec2(0.0,0.5);
|
|
||||||
vec2 fp = fract(OGL2Pos);
|
|
||||||
vec2 dx = vec2(ps.x,0.0);
|
|
||||||
vec2 dy = vec2(0.0, ps.y);
|
|
||||||
|
|
||||||
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
|
|
||||||
|
|
||||||
vec3 color1 = COMPAT_TEXTURE(Source, pC4 ).xyz;
|
|
||||||
vec3 color2 = COMPAT_TEXTURE(Source, pC4 +dy).xyz;
|
|
||||||
|
|
||||||
// calculating scanlines
|
|
||||||
|
|
||||||
float f = fp.y;
|
|
||||||
float shape1 = mix(scanline1, scanline2, f);
|
|
||||||
float shape2 = mix(scanline1, scanline2, 1.0-f);
|
|
||||||
|
|
||||||
float wt1 = st(f, shape1);
|
|
||||||
float wt2 = st(1.0-f, shape2);
|
|
||||||
vec3 color0 = color1*wt1 + color2*wt2;
|
|
||||||
vec3 ctmp = color0/(wt1+wt2);
|
|
||||||
vec3 tmp = pow(ctmp, vec3(1.0/gamma_out));
|
|
||||||
|
|
||||||
vec3 w1,w2 = vec3(0.0);
|
|
||||||
|
|
||||||
vec3 cref1 = mix(ctmp, color1, beam_size);
|
|
||||||
vec3 cref2 = mix(ctmp, color2, beam_size);
|
|
||||||
|
|
||||||
vec3 shift = vec3(-vertmask, vertmask, -vertmask);
|
|
||||||
|
|
||||||
vec3 f1 = clamp(vec3(f) + shift*0.5*(1.0+f), 0.0, 1.0);
|
|
||||||
vec3 f2 = clamp(vec3(1.0-f) - shift*0.5*(2.0-f), 0.0, 1.0);
|
|
||||||
|
|
||||||
if (gsl == 0.0) { w1 = sw0(f1,cref1,shape1); w2 = sw0(f2,cref2,shape2);} else
|
|
||||||
if (gsl == 1.0) { w1 = sw1(f1,cref1,shape1); w2 = sw1(f2,cref2,shape2);} else
|
|
||||||
if (gsl == 2.0) { w1 = sw2(f1,cref1,shape1); w2 = sw2(f2,cref2,shape2);}
|
|
||||||
|
|
||||||
vec3 color = color1*pow(w1, vec3(s_power)) + color2*pow(w2, vec3(s_power));
|
|
||||||
|
|
||||||
color*=brightboost;
|
|
||||||
color = min(color, 1.0);
|
|
||||||
|
|
||||||
// Apply Mask
|
|
||||||
|
|
||||||
color *= Mask(gl_FragCoord.xy * 1.000001,tmp);
|
|
||||||
|
|
||||||
color = min(color,1.0);
|
|
||||||
|
|
||||||
color *= SlotMask(gl_FragCoord.xy * 1.000001,tmp);
|
|
||||||
|
|
||||||
color = pow(color, vec3(1.0/gamma_out));
|
|
||||||
FragColor = vec4(color, 1.0);
|
|
||||||
}
|
|
|
@ -1,9 +1,12 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CRT - Guest - Advanced - Deconvergence pass (NTSC) + noise
|
CRT - Guest - Advanced
|
||||||
|
|
||||||
Copyright (C) 2021 guest(r) - guest.r@gmail.com
|
Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -23,11 +26,34 @@
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
|
float IOS, brightboost, brightboost1, csize, bsize1, warpX, warpY, glow, shadowMask, masksize,
|
||||||
|
slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, addnoised, noiseresd, barintensity, mshift, mask_layout, mask_bloom;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
|
float bloom;
|
||||||
|
float halation;
|
||||||
|
float slotms;
|
||||||
|
float mclip;
|
||||||
|
float mask_gamma;
|
||||||
|
float gamma_out;
|
||||||
|
float overscanX;
|
||||||
|
float overscanY;
|
||||||
|
float intres;
|
||||||
|
float prescalex;
|
||||||
|
float c_shape;
|
||||||
|
float barspeed;
|
||||||
|
float bardir;
|
||||||
|
float sborder;
|
||||||
|
float bloom_dist;
|
||||||
|
float deconr;
|
||||||
float decons;
|
float decons;
|
||||||
float addnoised;
|
|
||||||
float noiseresd;
|
|
||||||
float deconrr;
|
float deconrr;
|
||||||
float deconrg;
|
float deconrg;
|
||||||
float deconrb;
|
float deconrb;
|
||||||
|
@ -36,40 +62,157 @@ layout(push_constant) uniform Push
|
||||||
float deconrby;
|
float deconrby;
|
||||||
float dctypex;
|
float dctypex;
|
||||||
float dctypey;
|
float dctypey;
|
||||||
} params;
|
float post_br;
|
||||||
|
float noisetype;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
||||||
|
#define glow params.glow // Glow Strength
|
||||||
|
|
||||||
|
#pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05
|
||||||
|
#define bloom global.bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter mask_bloom " Mask Bloom" 0.0 0.0 2.0 0.05
|
||||||
|
#define mask_bloom params.mask_bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter bloom_dist " Bloom Distribution" 0.0 0.0 3.0 0.05
|
||||||
|
#define bloom_dist global.bloom_dist // bloom effect distribution
|
||||||
|
|
||||||
|
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
||||||
|
#define halation global.halation // halation effect
|
||||||
|
|
||||||
|
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
||||||
|
#define gamma_c global.gamma_c // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05
|
||||||
|
#define brightboost params.brightboost // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025
|
||||||
|
#define brightboost1 params.brightboost1 // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
||||||
|
#define IOS params.IOS // Smart Integer Scaling
|
||||||
|
|
||||||
|
#pragma parameter csize " Corner Size" 0.0 0.0 0.25 0.005
|
||||||
|
#define csize params.csize // corner size
|
||||||
|
|
||||||
|
#pragma parameter bsize1 " Border Size" 0.01 0.0 3.0 0.01
|
||||||
|
#define bsize1 params.bsize1 // border Size
|
||||||
|
|
||||||
|
#pragma parameter sborder " Border Intensity" 0.75 0.25 2.0 0.05
|
||||||
|
#define sborder global.sborder // border intensity
|
||||||
|
|
||||||
|
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpX params.warpX // Curvature X
|
||||||
|
|
||||||
|
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpY params.warpY // Curvature Y
|
||||||
|
|
||||||
|
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
||||||
|
#define c_shape global.c_shape // curvature shape
|
||||||
|
|
||||||
|
#pragma parameter overscanX " Overscan X original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanX global.overscanX // OverscanX pixels
|
||||||
|
|
||||||
|
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanY global.overscanY // OverscanY pixels
|
||||||
|
|
||||||
|
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-12:'Trinitron'" 0.0 -1.0 12.0 1.0
|
||||||
|
#define shadowMask params.shadowMask // Mask Style
|
||||||
|
|
||||||
|
#pragma parameter maskstr " Mask Strength (0, 5-12)" 0.3 -0.5 1.0 0.025
|
||||||
|
#define maskstr params.maskstr // Mask Strength
|
||||||
|
|
||||||
|
#pragma parameter mcut " Mask 5-12 Low Strength" 1.10 0.0 2.0 0.05
|
||||||
|
#define mcut params.mcut // Mask 5-12 dark color strength
|
||||||
|
|
||||||
|
#pragma parameter masksize " CRT Mask Size" 1.0 1.0 4.0 1.0
|
||||||
|
#define masksize params.masksize // Mask Size
|
||||||
|
|
||||||
|
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
||||||
|
#define maskDark params.maskDark // Dark "Phosphor"
|
||||||
|
|
||||||
|
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
||||||
|
#define maskLight params.maskLight // Light "Phosphor"
|
||||||
|
|
||||||
|
#pragma parameter mshift " Mask Shift/Stagger" 0.0 -8.0 8.0 1.0
|
||||||
|
#define mshift params.mshift // mask 'line' shift/stagger
|
||||||
|
|
||||||
|
#pragma parameter mask_layout " Mask Layout: RGB or BGR (check LCD panel) " 0.0 0.0 1.0 1.0
|
||||||
|
#define mask_layout params.mask_layout // mask layout: RGB or BGR
|
||||||
|
|
||||||
|
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05
|
||||||
|
#define mask_gamma global.mask_gamma // Mask application gamma
|
||||||
|
|
||||||
|
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
||||||
|
#define slotmask params.slotmask
|
||||||
|
|
||||||
|
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
||||||
|
#define slotmask1 params.slotmask1
|
||||||
|
|
||||||
|
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0
|
||||||
|
#define slotwidth params.slotwidth // Slot Mask Width
|
||||||
|
|
||||||
|
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0
|
||||||
|
#define double_slot params.double_slot // Slot Mask Height
|
||||||
|
|
||||||
|
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
||||||
|
#define slotms global.slotms // Slot Mask Size
|
||||||
|
|
||||||
|
#pragma parameter mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05
|
||||||
|
#define mclip global.mclip //
|
||||||
|
|
||||||
|
#pragma parameter gamma_out "Gamma out" 2.4 1.0 5.0 0.05
|
||||||
|
#define gamma_out global.gamma_out // output gamma
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter bogus_deconvergence11 "[ HORIZONTAL/VERTICAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_deconvergence11 "[ HORIZONTAL/VERTICAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter dctypex " Deconvergence type X : 0.0 - static, other - dynamic" 0.0 0.0 1.0 0.05
|
#pragma parameter dctypex " Deconvergence type X : 0.0 - static, other - dynamic" 0.0 0.0 0.75 0.05
|
||||||
|
|
||||||
#pragma parameter dctypey " Deconvergence type Y : 0.0 - static, other - dynamic" 0.0 0.0 1.0 0.05
|
#pragma parameter dctypey " Deconvergence type Y : 0.0 - static, other - dynamic" 0.0 0.0 0.75 0.05
|
||||||
|
|
||||||
#pragma parameter deconrr " Horizontal Deconvergence Red Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrr " Horizontal Deconvergence Red Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrg " Horizontal Deconvergence Green Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrg " Horizontal Deconvergence Green Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrb " Horizontal Deconvergence Blue Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrb " Horizontal Deconvergence Blue Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrry " Vertical Deconvergence Red Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrry " Vertical Deconvergence Red Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrgy " Vertical Deconvergence Green Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrgy " Vertical Deconvergence Green Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter deconrby " Vertical Deconvergence Blue Range" 0.0 -12.0 12.0 0.25
|
#pragma parameter deconrby " Vertical Deconvergence Blue Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
#pragma parameter decons " Deconvergence Strength (and Type)" 0.5 -4.0 4.0 0.10
|
#pragma parameter decons " Deconvergence Strength" 1.0 0.0 3.0 0.10
|
||||||
#define decons params.decons // Horizontal deconvergence colors strength
|
|
||||||
|
|
||||||
#pragma parameter addnoised " Add Noise" 0.0 -1.0 1.0 0.02
|
#pragma parameter addnoised " Add Noise" 0.0 -1.0 1.0 0.02
|
||||||
#define addnoised params.addnoised // add noise
|
|
||||||
|
|
||||||
#pragma parameter noiseresd " Noise Resolution" 2.0 0.0 10.0 1.0
|
#pragma parameter noiseresd " Noise Resolution" 2.0 1.0 10.0 1.0
|
||||||
#define noiseresd params.noiseresd // add noise
|
|
||||||
|
#pragma parameter noisetype " Noise Type: Colored, Luma" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter post_br " Post Brightness" 1.0 0.25 5.0 0.01
|
||||||
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
{
|
#define TEX0 vTexCoord
|
||||||
mat4 MVP;
|
|
||||||
} global;
|
#define OutputSize global.OutputSize
|
||||||
|
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
||||||
|
|
||||||
#pragma stage vertex
|
#pragma stage vertex
|
||||||
layout(location = 0) in vec4 Position;
|
layout(location = 0) in vec4 Position;
|
||||||
|
@ -79,15 +222,254 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
layout(set = 0, binding = 2) uniform sampler2D PrePass;
|
||||||
|
layout(set = 0, binding = 3) uniform sampler2D LinearizePass;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D BloomPass;
|
||||||
|
layout(set = 0, binding = 5) uniform sampler2D Source;
|
||||||
|
|
||||||
|
#define eps 1e-10
|
||||||
|
|
||||||
|
// Shadow mask (1-4 from PD CRT Lottes shader).
|
||||||
|
|
||||||
|
vec3 Mask(vec2 pos, float mx)
|
||||||
|
{
|
||||||
|
vec2 pos0 = pos;
|
||||||
|
pos.y = floor(pos.y/masksize);
|
||||||
|
float next_line = float(fract(pos.y*0.5) > 0.25);
|
||||||
|
pos0.x = (mshift > -0.25) ? (pos0.x + next_line * mshift) : (pos0.x + pos.y * mshift);
|
||||||
|
pos = floor(pos0/masksize);
|
||||||
|
|
||||||
|
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.4, 0.0) + 1.0, 1.0, mx);
|
||||||
|
float mc = 1.0 - max(maskstr, 0.0);
|
||||||
|
|
||||||
|
// No mask
|
||||||
|
if (shadowMask == -1.0)
|
||||||
|
{
|
||||||
|
mask = vec3(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phosphor.
|
||||||
|
else if (shadowMask == 0.0)
|
||||||
|
{
|
||||||
|
pos.x = fract(pos.x*0.5);
|
||||||
|
if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
||||||
|
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Very compressed TV style shadow mask.
|
||||||
|
else if (shadowMask == 1.0)
|
||||||
|
{
|
||||||
|
float line = maskLight;
|
||||||
|
float odd = 0.0;
|
||||||
|
|
||||||
|
if (fract(pos.x/6.0) < 0.49)
|
||||||
|
odd = 1.0;
|
||||||
|
if (fract((pos.y + odd)/2.0) < 0.49)
|
||||||
|
line = maskDark;
|
||||||
|
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
|
||||||
|
mask*=line;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aperture-grille.
|
||||||
|
else if (shadowMask == 2.0)
|
||||||
|
{
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stretched VGA style shadow mask (same as prior shaders).
|
||||||
|
else if (shadowMask == 3.0)
|
||||||
|
{
|
||||||
|
pos.x += pos.y*3.0;
|
||||||
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VGA style shadow mask.
|
||||||
|
else if (shadowMask == 4.0)
|
||||||
|
{
|
||||||
|
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
||||||
|
pos.x += pos.y*3.0;
|
||||||
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trinitron mask 5
|
||||||
|
else if (shadowMask == 5.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/2.0);
|
||||||
|
if (pos.x < 0.49)
|
||||||
|
{ mask.r = 1.0;
|
||||||
|
mask.b = 1.0;
|
||||||
|
}
|
||||||
|
else mask.g = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trinitron mask 6
|
||||||
|
else if (shadowMask == 6.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.6) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BW Trinitron mask 7
|
||||||
|
else if (shadowMask == 7.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/2.0);
|
||||||
|
if (pos.x < 0.49)
|
||||||
|
{ mask = 0.0.xxx;
|
||||||
|
}
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BW Trinitron mask 8
|
||||||
|
else if (shadowMask == 8.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask = 1.0.xxx;
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magenta - Green - Black mask
|
||||||
|
else if (shadowMask == 9.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask.rb = 1.0.xx;
|
||||||
|
else mask.g = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RGBX
|
||||||
|
else if (shadowMask == 10.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.4) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.7) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4k mask
|
||||||
|
else if (shadowMask == 11.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
||||||
|
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RRGGBBX mask
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = floor(mod(pos.x,7.0));
|
||||||
|
if (pos.x < 1.0) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 3.0) mask.r = 1.0;
|
||||||
|
else if (pos.x < 5.0) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SlotMask(vec2 pos, float m)
|
||||||
|
{
|
||||||
|
if ((slotmask + slotmask1) == 0.0) return 1.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos = floor(pos/slotms);
|
||||||
|
float mlen = slotwidth*2.0;
|
||||||
|
float px = fract(pos.x/mlen);
|
||||||
|
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
||||||
|
float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m);
|
||||||
|
float slot = 1.0;
|
||||||
|
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
||||||
|
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Warp(vec2 pos)
|
||||||
|
{
|
||||||
|
pos = pos*2.0-1.0;
|
||||||
|
pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape);
|
||||||
|
return pos*0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Overscan(vec2 pos, float dx, float dy){
|
||||||
|
pos=pos*2.0-1.0;
|
||||||
|
pos*=vec2(dx,dy);
|
||||||
|
return pos*0.5+0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
float humbar(float pos)
|
||||||
|
{
|
||||||
|
if (params.barintensity == 0.0) return 1.0; else
|
||||||
|
{
|
||||||
|
pos = (params.barintensity >= 0.0) ? pos : (1.0-pos);
|
||||||
|
pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0));
|
||||||
|
pos = (params.barintensity < 0.0) ? pos : (1.0-pos);
|
||||||
|
return (1.0-params.barintensity) + params.barintensity*pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float corner(vec2 pos) {
|
||||||
|
vec2 b = vec2(bsize1, bsize1) * vec2(1.0, OutputSize.x/OutputSize.y) * 0.05;
|
||||||
|
pos = clamp(pos, 0.0, 1.0);
|
||||||
|
pos = abs(2.0*(pos - 0.5));
|
||||||
|
float csize1 = mix(400.0, 7.0, pow(4.0*csize, 0.10));
|
||||||
|
float crn = dot(pow(pos, csize1.xx), vec2(1.0, OutputSize.y/OutputSize.x));
|
||||||
|
crn = (csize == 0.0) ? max(pos.x, pos.y) : pow(crn, 1.0/csize1);
|
||||||
|
pos = max(pos, crn);
|
||||||
|
vec2 res = (bsize1 == 0.0) ? 1.0.xx : mix(0.0.xx, 1.0.xx, smoothstep(1.0.xx, 1.0.xx-b, sqrt(pos)));
|
||||||
|
res = pow(res, sborder.xx);
|
||||||
|
return sqrt(res.x*res.y);
|
||||||
|
}
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
vec3 plant (vec3 tar, float r)
|
vec3 plant (vec3 tar, float r)
|
||||||
{
|
{
|
||||||
|
@ -95,82 +477,202 @@ vec3 plant (vec3 tar, float r)
|
||||||
return tar * r / t;
|
return tar * r / t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 declip(vec3 c, float b)
|
||||||
|
{
|
||||||
|
float m = max(max(c.r,c.g),c.b);
|
||||||
|
if (m > b) c = c*b/m;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
// noise function:
|
// noise function:
|
||||||
// Dedicated to the public domain.
|
// Dedicated to the public domain.
|
||||||
// If you want a real license, you may consider this MIT/BSD/CC0/WTFPL-licensed (take your pick).
|
// If you want a real license, you may consider this MIT/BSD/CC0/WTFPL-licensed (take your pick).
|
||||||
// Adapted from ChuckNorris - shadertoy: https://www.shadertoy.com/view/XtK3Dz
|
// Adapted from ChuckNorris - shadertoy: https://www.shadertoy.com/view/XtK3Dz
|
||||||
|
|
||||||
vec3 noise(vec3 v){
|
vec3 noise(vec3 v){
|
||||||
if (addnoised < 0.0) v.z = -addnoised; else v.z = v.z/6000.0;
|
if (params.addnoised < 0.0) v.z = -params.addnoised; else v.z = mod(v.z,6001.0)/1753.0;
|
||||||
// ensure reasonable range
|
// ensure reasonable range
|
||||||
v = fract(v) + fract(v*1e4) + fract(v*1e-4);
|
v = fract(v) + fract(v*1e4) + fract(v*1e-4);
|
||||||
// seed
|
// seed
|
||||||
v += vec3(0.12345, 0.6789, 0.314159);
|
v += vec3(0.12345, 0.6789, 0.314159);
|
||||||
// more iterations => more random
|
// more iterations => more random
|
||||||
v = fract(v*dot(v, v)*123.456);
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
v = fract(v*dot(v, v)*123.456);
|
v = fract(v*dot(v, v)*123.456);
|
||||||
v = fract(v*dot(v, v)*123.456);
|
v = fract(v*dot(v, v)*123.456);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void fetch_pixel (inout vec3 c, inout vec3 b, vec2 coord, vec2 bcoord)
|
||||||
{
|
{
|
||||||
|
float stepx = OutputSize.z;
|
||||||
|
float stepy = OutputSize.w;
|
||||||
|
|
||||||
vec3 color = COMPAT_TEXTURE(Source, vTexCoord).rgb;
|
float ds = global.decons;
|
||||||
vec3 result = color;
|
|
||||||
|
|
||||||
if ((abs(params.deconrr) + abs(params.deconrg) + abs(params.deconrb) + abs(params.deconrry) + abs(params.deconrgy) + abs(params.deconrby)) > 0.20)
|
|
||||||
{
|
|
||||||
float stepx = params.OutputSize.z;
|
|
||||||
float stepy = params.OutputSize.w;
|
|
||||||
|
|
||||||
vec2 dx = vec2(stepx, 0.0);
|
vec2 dx = vec2(stepx, 0.0);
|
||||||
vec2 dy = vec2(0.0, stepy);
|
vec2 dy = vec2(0.0, stepy);
|
||||||
|
|
||||||
float ds = decons;
|
float posx = 2.0*coord.x - 1.0;
|
||||||
|
float posy = 2.0*coord.y - 1.0;
|
||||||
|
|
||||||
float posx = 2.0*vTexCoord.x - 1.0;
|
if (global.dctypex > 0.025)
|
||||||
float posy = 2.0*vTexCoord.y - 1.0;
|
|
||||||
|
|
||||||
if (params.dctypex > 0.025)
|
|
||||||
{
|
{
|
||||||
posx = sign(posx)*pow(abs(posx), 1.05-params.dctypex);
|
posx = sign(posx)*pow(abs(posx), 1.05-global.dctypex);
|
||||||
dx = posx * dx;
|
dx = posx * dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.dctypey > 0.025)
|
if (global.dctypey > 0.025)
|
||||||
{
|
{
|
||||||
|
|
||||||
posy = sign(posy)*pow(abs(posy), 1.05-params.dctypey);
|
posy = sign(posy)*pow(abs(posy), 1.05-global.dctypey);
|
||||||
dy = posy * dy;
|
dy = posy * dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.dctypex > 0.025 || params.dctypey > 0.025) ds *= sqrt(posx*posx*sign(params.dctypex) + posy*posy*sign(params.dctypey));
|
// if (global.dctypex > 0.025 || global.dctypey > 0.025) ds *= sqrt(posx*posx*sign(global.dctypex) + posy*posy*sign(global.dctypey));
|
||||||
|
|
||||||
vec2 rc = params.deconrr * dx + params.deconrry*dy;
|
vec2 rc = global.deconrr * dx + global.deconrry*dy;
|
||||||
vec2 gc = params.deconrg * dx + params.deconrgy*dy;
|
vec2 gc = global.deconrg * dx + global.deconrgy*dy;
|
||||||
vec2 bc = params.deconrb * dx + params.deconrby*dy;
|
vec2 bc = global.deconrb * dx + global.deconrby*dy;
|
||||||
|
|
||||||
float r = COMPAT_TEXTURE(Source, vTexCoord + rc ).r;
|
float r1 = COMPAT_TEXTURE(Source, coord + rc).r;
|
||||||
float g = COMPAT_TEXTURE(Source, vTexCoord + gc ).g;
|
float g1 = COMPAT_TEXTURE(Source, coord + gc).g;
|
||||||
float b = COMPAT_TEXTURE(Source, vTexCoord + bc ).b;
|
float b1 = COMPAT_TEXTURE(Source, coord + bc).b;
|
||||||
|
|
||||||
result = vec3(r,g,b);
|
vec3 d = vec3(r1, g1, b1);
|
||||||
|
c = clamp(mix(c, d, ds), 0.0, 1.0);
|
||||||
|
|
||||||
vec3 dcolor = max(max(COMPAT_TEXTURE(Source, vTexCoord + dx).rgb, COMPAT_TEXTURE(Source, vTexCoord - dx).rgb), color);
|
r1 = COMPAT_TEXTURE(BloomPass, bcoord + rc).r;
|
||||||
|
g1 = COMPAT_TEXTURE(BloomPass, bcoord + gc).g;
|
||||||
|
b1 = COMPAT_TEXTURE(BloomPass, bcoord + bc).b;
|
||||||
|
|
||||||
float mc = max(max(dcolor.r, dcolor.g), dcolor.b);
|
d = vec3(r1, g1, b1);
|
||||||
if (decons < 0.0) mc = 0.9;
|
b = clamp(mix(b, d, ds), 0.0, 1.0);
|
||||||
float dclamp = min(2.0-0.40*abs(ds),1.0);
|
|
||||||
|
|
||||||
result = clamp(mix(color, sqrt(mix(result*result, color*result, sqrt(mc))), abs(ds)), dclamp*min(result,color), min(1.0/dclamp*max(result, color),1.0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float rc = 0.6*sqrt(max(max(result.r, result.g), result.b))+0.4;
|
void main()
|
||||||
|
{
|
||||||
|
vec4 SourceSize = global.OriginalSize;
|
||||||
|
|
||||||
if (abs(addnoised) > 0.01) result = mix(result, noise(vec3(floor(params.OutputSize.xy * vTexCoord / noiseresd), float(params.FrameCount))), 0.25*abs(addnoised) * rc);
|
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
||||||
|
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
||||||
|
bool interb = (intera < 0.5);
|
||||||
|
|
||||||
float corner = COMPAT_TEXTURE(Source, vTexCoord).a;
|
// Calculating texel coordinates
|
||||||
|
|
||||||
FragColor = vec4(result*corner, 1.0);
|
vec2 texcoord = TEX0.xy;
|
||||||
|
|
||||||
|
if (IOS > 0.0 && !interb){
|
||||||
|
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
||||||
|
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
||||||
|
vec2 diff = ofactor/intfactor;
|
||||||
|
float scan = diff.y;
|
||||||
|
texcoord = Overscan(texcoord, scan, scan);
|
||||||
|
if (IOS == 1.0 || IOS == 3.0) texcoord = vec2(TEX0.x, texcoord.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
texcoord = Overscan(texcoord, (global.OriginalSize.x - overscanX)/global.OriginalSize.x, (global.OriginalSize.y - overscanY)/global.OriginalSize.y);
|
||||||
|
|
||||||
|
vec2 pos1 = TEX0.xy;
|
||||||
|
vec2 pos = Warp(texcoord);
|
||||||
|
vec2 pos0 = Warp(TEX0.xy);
|
||||||
|
vec3 color0 = COMPAT_TEXTURE(Source,pos1).rgb;
|
||||||
|
float c0 = max(max(color0.r, color0.g),color0.b);
|
||||||
|
|
||||||
|
// color and bloom fetching
|
||||||
|
vec3 color = COMPAT_TEXTURE(Source,pos1).rgb;
|
||||||
|
vec3 Bloom = COMPAT_TEXTURE(BloomPass, pos).rgb;
|
||||||
|
fetch_pixel(color, Bloom, pos1, pos);
|
||||||
|
|
||||||
|
float cm = max(max(color.r,color.g),color.b);
|
||||||
|
float mx1 = COMPAT_TEXTURE(Source, pos1 ).a;
|
||||||
|
float colmx = max(mx1, cm);
|
||||||
|
float w3 = min((c0 + 0.0005) / (pow(colmx, gamma_in/1.4) + 0.0005), 1.0);
|
||||||
|
|
||||||
|
vec2 dx = vec2(0.001, 0.0);
|
||||||
|
float mx0 = COMPAT_TEXTURE(Source, pos1 - dx).a;
|
||||||
|
float mx2 = COMPAT_TEXTURE(Source, pos1 + dx).a;
|
||||||
|
float mx = max(max(mx0,mx1),max(mx2,cm));
|
||||||
|
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
|
||||||
|
// Apply Mask
|
||||||
|
|
||||||
|
vec3 orig1 = color;
|
||||||
|
vec3 cmask = one;
|
||||||
|
|
||||||
|
vec2 maskcoord = gl_FragCoord.xy * 1.000001;
|
||||||
|
|
||||||
|
float smask = SlotMask(maskcoord, mx);
|
||||||
|
cmask*= Mask(maskcoord, mx);
|
||||||
|
|
||||||
|
if (mask_layout > 0.5) cmask = cmask.rbg;
|
||||||
|
|
||||||
|
vec3 cmask1 = cmask;
|
||||||
|
float smask1 = smask;
|
||||||
|
|
||||||
|
if (mask_bloom > 0.025)
|
||||||
|
{
|
||||||
|
float maxb = max(max(Bloom.r,Bloom.g),Bloom.b);
|
||||||
|
maxb = pow(sqrt(maxb*mix(maxb, colmx, 0.75)),0.275);
|
||||||
|
vec3 mBloom = 0.5*(1.5*Bloom+0.5*maxb) * mix(1.0, 2.0-colmx, (bloom_dist + 0.5));
|
||||||
|
float maskmx = 1.0; if (shadowMask > 0.5 || shadowMask < 4.5) maskmx = maskLight; else if (shadowMask > 6.5 && shadowMask < 10.5) maskmx = 1.0; else maskmx = max(max(cmask.r,cmask.g),cmask.b);
|
||||||
|
cmask = min(cmask + maxb*mBloom*mask_bloom, maskmx);
|
||||||
|
smask = min(smask + 0.9*maxb*max(max(mBloom.r,mBloom.g),mBloom.b)*mask_bloom, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
color = pow(color, vec3(mask_gamma/gamma_in));
|
||||||
|
color = color*cmask;
|
||||||
|
color = min(color,1.0);
|
||||||
|
color = color*smask;
|
||||||
|
color = pow(color, vec3(gamma_in/mask_gamma));
|
||||||
|
|
||||||
|
cmask = min(cmask*smask, 1.0);
|
||||||
|
cmask1 = min(cmask1*smask1, 1.0);
|
||||||
|
|
||||||
|
float bb = mix(brightboost, brightboost1, colmx);
|
||||||
|
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
||||||
|
color*=bb;
|
||||||
|
|
||||||
|
vec3 Glow = COMPAT_TEXTURE(BloomPass, pos).rgb;
|
||||||
|
vec3 Ref = COMPAT_TEXTURE(LinearizePass, pos).rgb;
|
||||||
|
float maxb = COMPAT_TEXTURE(BloomPass, pos).a;
|
||||||
|
float vig = COMPAT_TEXTURE(PrePass, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a;
|
||||||
|
|
||||||
|
vec3 Bloom1 = Bloom;
|
||||||
|
|
||||||
|
if (bloom < -0.01) Bloom1 = plant(Bloom, maxb);
|
||||||
|
|
||||||
|
Bloom1 = min(Bloom1*(orig1+color), max(0.5*(colmx + orig1 - color),0.001*Bloom1));
|
||||||
|
Bloom1 = 0.5*(Bloom1 + mix(Bloom1, mix(colmx*orig1, Bloom1, 0.5), 1.0-color));
|
||||||
|
|
||||||
|
Bloom1 = Bloom1 * mix(1.0, 2.0-colmx, bloom_dist);
|
||||||
|
|
||||||
|
color = color + abs(bloom) * Bloom1;
|
||||||
|
|
||||||
|
color = min(color, mix(one, cmask1, mclip));
|
||||||
|
|
||||||
|
if (!interb) color = declip(color, mix(1.0, w3, 0.6)); else w3 = 1.0;
|
||||||
|
|
||||||
|
if (halation > 0.01) {
|
||||||
|
Bloom = mix(0.5*(Bloom + Bloom*Bloom), 0.75*Bloom*Bloom, colmx);
|
||||||
|
color = color + 2.0*max((2.0*mix(maxb*maxb, maxb, colmx)-0.5*max(max(Ref.r,Ref.g),Ref.b)),0.25)*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.6)*Bloom*halation; }
|
||||||
|
|
||||||
|
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
||||||
|
if (glow >= 0.0) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + (-glow)*cmask*Glow; }
|
||||||
|
|
||||||
|
color = min(color, 1.0);
|
||||||
|
|
||||||
|
color = pow(color, vec3(1.0/gamma_out));
|
||||||
|
|
||||||
|
float rc = 0.6*sqrt(max(max(color.r, color.g), color.b))+0.4;
|
||||||
|
|
||||||
|
if (abs(params.addnoised) > 0.01)
|
||||||
|
{
|
||||||
|
vec3 noise0 = noise(vec3(floor(OutputSize.xy * vTexCoord / params.noiseresd), float(global.FrameCount)));
|
||||||
|
if (global.noisetype < 0.5) color = mix(color, noise0, 0.25*abs(params.addnoised) * rc);
|
||||||
|
else color = min(color * mix(1.0, 1.5*noise0.x, 0.5*abs(params.addnoised)),1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir))*global.post_br*corner(pos0), 1.0);
|
||||||
}
|
}
|
|
@ -72,7 +72,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader)" 1.0 1.0 4.0 1.0 // Joint parameter with main pass, values must match
|
||||||
#define prescalex params.prescalex // prescale-x factor
|
#define prescalex params.prescalex // prescale-x factor
|
||||||
|
|
||||||
#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.40 0.0 1.0 0.05
|
#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.25 0.0 1.0 0.05
|
||||||
#define iscans params.iscans // interlace saturation
|
#define iscans params.iscans // interlace saturation
|
||||||
|
|
||||||
#pragma stage vertex
|
#pragma stage vertex
|
||||||
|
@ -83,7 +83,7 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord * 1.000001;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
|
@ -152,7 +152,7 @@ void main()
|
||||||
|
|
||||||
if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5)
|
if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5)
|
||||||
{
|
{
|
||||||
intera = 0.5;
|
intera = 0.25;
|
||||||
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
||||||
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
||||||
float ii = abs(line_no-frame_no);
|
float ii = abs(line_no-frame_no);
|
||||||
|
@ -163,10 +163,9 @@ void main()
|
||||||
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
||||||
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
||||||
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
||||||
intera = 0.0;
|
|
||||||
}
|
}
|
||||||
if (interm == 4.0) c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b));
|
if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; }
|
||||||
if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b));}
|
if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; }
|
||||||
}
|
}
|
||||||
c = pow(c, vec3(gamma_in));
|
c = pow(c, vec3(gamma_in));
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord * 1.000001;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
|
@ -107,7 +107,7 @@ void main()
|
||||||
|
|
||||||
if (inter <= params.OriginalSize.y && interm > 0.5)
|
if (inter <= params.OriginalSize.y && interm > 0.5)
|
||||||
{
|
{
|
||||||
intera = 0.5;
|
intera = 0.25;
|
||||||
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
||||||
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
||||||
float ii = abs(line_no-frame_no);
|
float ii = abs(line_no-frame_no);
|
||||||
|
@ -117,9 +117,8 @@ void main()
|
||||||
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
||||||
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
||||||
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
||||||
intera = 0.0;
|
|
||||||
}
|
}
|
||||||
if (interm == 5.0) { c = mix(c2, c1, 0.5); }
|
if (interm == 5.0) { c = mix(c2, c1, 0.5); intera = 0.45; }
|
||||||
}
|
}
|
||||||
c = pow(c, vec3(gamma_in));
|
c = pow(c, vec3(gamma_in));
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
CRT Advanced color altering
|
CRT Advanced color altering
|
||||||
|
|
||||||
Copyright (C) 2019-2021 guest(r) and Dr. Venom
|
Copyright (C) 2019-2022 guest(r) and Dr. Venom
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -38,6 +38,7 @@ layout(push_constant) uniform Push
|
||||||
float vigdef;
|
float vigdef;
|
||||||
float sega_fix;
|
float sega_fix;
|
||||||
float pre_bb;
|
float pre_bb;
|
||||||
|
float contr;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
@ -49,7 +50,7 @@ layout(push_constant) uniform Push
|
||||||
#define CP params.CP
|
#define CP params.CP
|
||||||
#define CS params.CS
|
#define CS params.CS
|
||||||
|
|
||||||
#pragma parameter TNTC " LUT Colors: Trin. | invTrin. | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0
|
#pragma parameter TNTC " LUT Colors: Trin.1 | Trin.2 | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0
|
||||||
#define TNTC params.TNTC
|
#define TNTC params.TNTC
|
||||||
|
|
||||||
#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0
|
#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0
|
||||||
|
@ -65,17 +66,19 @@ layout(push_constant) uniform Push
|
||||||
|
|
||||||
#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01
|
#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter contr " Contrast Adjustment" 0.0 -1.0 1.0 0.05
|
||||||
|
|
||||||
#define WP params.WP
|
#define WP params.WP
|
||||||
#define wp_saturation params.wp_saturation
|
#define wp_saturation params.wp_saturation
|
||||||
|
|
||||||
#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0
|
#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter BP " Raise Black Level" 0.0 0.0 25.0 1.0
|
#pragma parameter BP " Raise Black Level" 0.0 -100.0 25.0 1.0
|
||||||
#define BP params.BP
|
#define BP params.BP
|
||||||
|
|
||||||
#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.025
|
#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.05
|
||||||
|
|
||||||
#pragma parameter vigdef " Vignette Definition" 7.0 0.4 15.0 0.2
|
#pragma parameter vigdef " Vignette Size" 1.0 0.5 3.0 0.10
|
||||||
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
@ -194,9 +197,9 @@ const mat3 D65_to_D55 = mat3 (
|
||||||
|
|
||||||
|
|
||||||
const mat3 D65_to_D93 = mat3 (
|
const mat3 D65_to_D93 = mat3 (
|
||||||
0.3683017655, 0.1899055978, 0.0172641453,
|
0.3412754080, 0.1759701322, 0.0159972847,
|
||||||
0.3555467892, 0.7110935785, 0.1185155964,
|
0.3646170520, 0.7292341040, 0.1215390173,
|
||||||
0.2475020592, 0.0990008237, 1.3035108450);
|
0.2369894093, 0.0947957637, 1.2481442225);
|
||||||
|
|
||||||
|
|
||||||
vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
||||||
|
@ -208,18 +211,26 @@ vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
||||||
return mix(lutcolor, ref, LUTBR);
|
return mix(lutcolor, ref, LUTBR);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ctransform (vec2 inputc)
|
float vignette(vec2 pos) {
|
||||||
{
|
vec2 b = vec2(params.vigdef, params.vigdef) * vec2(1.0, params.OriginalSize.x/params.OriginalSize.y) * 0.125;
|
||||||
return vec2( inputc.x * sqrt(1.0 - 0.5*inputc.y*inputc.y), inputc.y * sqrt(1.0 - 0.5*inputc.x*inputc.x));
|
pos = clamp(pos, 0.0, 1.0);
|
||||||
|
pos = abs(2.0*(pos - 0.5));
|
||||||
|
vec2 res = mix(0.0.xx, 1.0.xx, smoothstep(1.0.xx, 1.0.xx-b, sqrt(pos)));
|
||||||
|
res = pow(res, 0.70.xx);
|
||||||
|
return max(mix(1.0, sqrt(res.x*res.y), params.vigstr), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float vignette (vec2 coords)
|
vec3 plant (vec3 tar, float r)
|
||||||
{
|
{
|
||||||
vec2 ccoords = ctransform(2.0*(coords-0.5));
|
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
||||||
ccoords = ccoords * ccoords;
|
return tar * r / t;
|
||||||
float vstr = sqrt(ccoords.x+ccoords.y);
|
}
|
||||||
vstr = pow(vstr, params.vigdef);
|
|
||||||
return max(mix(1.0, 1.0-vstr, params.vigstr), 0.0);
|
float contrast(float x)
|
||||||
|
{
|
||||||
|
float y = 2.0*x-1.0;
|
||||||
|
y = (sin(y*1.57079632679)+1.0)*0.5;
|
||||||
|
return mix(x, y, params.contr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
@ -229,8 +240,6 @@ void main()
|
||||||
float w = float ((imgColor.r + imgColor.g + imgColor.b) < 1.5/255.0);
|
float w = float ((imgColor.r + imgColor.g + imgColor.b) < 1.5/255.0);
|
||||||
float bp = w * BP/255.0;
|
float bp = w * BP/255.0;
|
||||||
|
|
||||||
imgColor.rgb = imgColor.rgb * params.pre_bb;
|
|
||||||
|
|
||||||
if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0);
|
if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0);
|
||||||
|
|
||||||
imgColor.rgb = min(imgColor.rgb, 1.0);
|
imgColor.rgb = min(imgColor.rgb, 1.0);
|
||||||
|
@ -279,10 +288,6 @@ void main()
|
||||||
res = mix(color1, color2, f);
|
res = mix(color1, color2, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imgColor.r == 0.0) res.r = 0.0;
|
|
||||||
if (imgColor.g == 0.0) res.g = 0.0;
|
|
||||||
if (imgColor.b == 0.0) res.b = 0.0;
|
|
||||||
|
|
||||||
res.rgb = fix_lut (res.rgb, imgColor.rgb);
|
res.rgb = fix_lut (res.rgb, imgColor.rgb);
|
||||||
|
|
||||||
color = mix(imgColor.rgb, res.rgb, min(TNTC,1.0));
|
color = mix(imgColor.rgb, res.rgb, min(TNTC,1.0));
|
||||||
|
@ -319,11 +324,13 @@ void main()
|
||||||
|
|
||||||
if (CP == -1.0) color = c;
|
if (CP == -1.0) color = c;
|
||||||
|
|
||||||
vec3 scolor1 = normalize(pow(color + 0.000000001, vec3(wp_saturation)))*length(color);
|
vec3 scolor1 = plant(pow(color, vec3(wp_saturation)), max(max(color.r,color.g),color.b));
|
||||||
float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
float luma = dot(color, vec3(0.299, 0.587, 0.114));
|
||||||
vec3 scolor2 = mix(vec3(luma), color, wp_saturation);
|
vec3 scolor2 = mix(vec3(luma), color, wp_saturation);
|
||||||
color = (wp_saturation > 1.0) ? scolor1 : scolor2;
|
color = (wp_saturation > 1.0) ? scolor1 : scolor2;
|
||||||
|
|
||||||
|
color = plant(color, contrast(max(max(color.r,color.g),color.b)));
|
||||||
|
|
||||||
p = 2.2;
|
p = 2.2;
|
||||||
|
|
||||||
color = pow(color, vec3(p));
|
color = pow(color, vec3(p));
|
||||||
|
@ -343,7 +350,12 @@ void main()
|
||||||
color = mix(color, comp, m);
|
color = mix(color, comp, m);
|
||||||
color = pow(max(color, 0.0), vec3(1.0/p));
|
color = pow(max(color, 0.0), vec3(1.0/p));
|
||||||
|
|
||||||
color = color + bp;
|
if (BP > -0.5) color = color + bp; else
|
||||||
|
{
|
||||||
|
color = max(color + BP/255.0, 0.0) / (1.0 + BP/255.0*step(- BP/255.0, max(max(color.r,color.g),color.b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
color = min(color * params.pre_bb, 1.0);
|
||||||
|
|
||||||
FragColor = vec4(color, vignette(vTexCoord.xy));
|
FragColor = vec4(color, vignette(vTexCoord.xy));
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
CRT Advanced color altering
|
CRT Advanced color altering
|
||||||
|
|
||||||
Copyright (C) 2019-2021 guest(r) and Dr. Venom
|
Copyright (C) 2019-2022 guest(r) and Dr. Venom
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -37,11 +37,12 @@ layout(push_constant) uniform Push
|
||||||
float vigdef;
|
float vigdef;
|
||||||
float sega_fix;
|
float sega_fix;
|
||||||
float pre_bb;
|
float pre_bb;
|
||||||
|
float contr;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter TNTC " LUT Colors: Trin. | invTrin. | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0
|
#pragma parameter TNTC " LUT Colors: Trin.1 | Trin.2 | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0
|
||||||
#define TNTC params.TNTC
|
#define TNTC params.TNTC
|
||||||
|
|
||||||
#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0
|
#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0
|
||||||
|
@ -52,16 +53,20 @@ layout(push_constant) uniform Push
|
||||||
#define LUTBR 1.0 // "Fix LUT Brightness" from 0.0 to 1.0
|
#define LUTBR 1.0 // "Fix LUT Brightness" from 0.0 to 1.0
|
||||||
|
|
||||||
#pragma parameter WP " Color Temperature %" 0.0 -100.0 100.0 5.0
|
#pragma parameter WP " Color Temperature %" 0.0 -100.0 100.0 5.0
|
||||||
|
|
||||||
#pragma parameter wp_saturation " Saturation Adjustment" 1.0 0.0 2.0 0.05
|
#pragma parameter wp_saturation " Saturation Adjustment" 1.0 0.0 2.0 0.05
|
||||||
|
|
||||||
#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01
|
#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter contr " Contrast Adjustment" 0.0 -1.0 1.0 0.05
|
||||||
|
|
||||||
#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0
|
#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter BP " Raise Black Level" 0.0 0.0 25.0 1.0
|
#pragma parameter BP " Raise Black Level" 0.0 -100.0 25.0 1.0
|
||||||
|
|
||||||
#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.025
|
#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.05
|
||||||
|
|
||||||
#pragma parameter vigdef " Vignette Definition" 7.0 0.4 15.0 0.2
|
#pragma parameter vigdef " Vignette Size" 1.0 0.5 3.0 0.10
|
||||||
|
|
||||||
|
|
||||||
#define WP params.WP
|
#define WP params.WP
|
||||||
|
@ -120,9 +125,9 @@ const mat3 D65_to_D55 = mat3 (
|
||||||
|
|
||||||
|
|
||||||
const mat3 D65_to_D93 = mat3 (
|
const mat3 D65_to_D93 = mat3 (
|
||||||
0.3683017655, 0.1899055978, 0.0172641453,
|
0.3412754080, 0.1759701322, 0.0159972847,
|
||||||
0.3555467892, 0.7110935785, 0.1185155964,
|
0.3646170520, 0.7292341040, 0.1215390173,
|
||||||
0.2475020592, 0.0990008237, 1.3035108450);
|
0.2369894093, 0.0947957637, 1.2481442225);
|
||||||
|
|
||||||
|
|
||||||
vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
||||||
|
@ -134,20 +139,27 @@ vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
||||||
return mix(lutcolor, ref, LUTBR);
|
return mix(lutcolor, ref, LUTBR);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ctransform (vec2 inputc)
|
float vignette(vec2 pos) {
|
||||||
{
|
vec2 b = vec2(params.vigdef, params.vigdef) * vec2(1.0, params.OriginalSize.x/params.OriginalSize.y) * 0.125;
|
||||||
return vec2( inputc.x * sqrt(1.0 - 0.5*inputc.y*inputc.y), inputc.y * sqrt(1.0 - 0.5*inputc.x*inputc.x));
|
pos = clamp(pos, 0.0, 1.0);
|
||||||
|
pos = abs(2.0*(pos - 0.5));
|
||||||
|
vec2 res = mix(0.0.xx, 1.0.xx, smoothstep(1.0.xx, 1.0.xx-b, sqrt(pos)));
|
||||||
|
res = pow(res, 0.70.xx);
|
||||||
|
return max(mix(1.0, sqrt(res.x*res.y), params.vigstr), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float vignette (vec2 coords)
|
vec3 plant (vec3 tar, float r)
|
||||||
{
|
{
|
||||||
vec2 ccoords = ctransform(2.0*(coords-0.5));
|
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
||||||
ccoords = ccoords * ccoords;
|
return tar * r / t;
|
||||||
float vstr = sqrt(ccoords.x+ccoords.y);
|
|
||||||
vstr = pow(vstr, params.vigdef);
|
|
||||||
return max(mix(1.0, 1.0-vstr, params.vigstr), 0.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float contrast(float x)
|
||||||
|
{
|
||||||
|
float y = 2.0*x-1.0;
|
||||||
|
y = (sin(y*1.57079632679)+1.0)*0.5;
|
||||||
|
return mix(x, y, params.contr);
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
@ -157,8 +169,6 @@ void main()
|
||||||
|
|
||||||
float bp = w * BP/255.0;
|
float bp = w * BP/255.0;
|
||||||
|
|
||||||
imgColor.rgb = imgColor.rgb * params.pre_bb;
|
|
||||||
|
|
||||||
if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0);
|
if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0);
|
||||||
|
|
||||||
imgColor.rgb = min(imgColor.rgb, 1.0);
|
imgColor.rgb = min(imgColor.rgb, 1.0);
|
||||||
|
@ -214,11 +224,13 @@ void main()
|
||||||
|
|
||||||
vec3 c = clamp(color, 0.0, 1.0);
|
vec3 c = clamp(color, 0.0, 1.0);
|
||||||
|
|
||||||
vec3 scolor1 = normalize(pow(color + 0.000000001, vec3(wp_saturation)))*length(color);
|
vec3 scolor1 = plant(pow(color, vec3(wp_saturation)), max(max(color.r,color.g),color.b));
|
||||||
float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
float luma = dot(color, vec3(0.299, 0.587, 0.114));
|
||||||
vec3 scolor2 = mix(vec3(luma), color, wp_saturation);
|
vec3 scolor2 = mix(vec3(luma), color, wp_saturation);
|
||||||
color = (wp_saturation > 1.0) ? scolor1 : scolor2;
|
color = (wp_saturation > 1.0) ? scolor1 : scolor2;
|
||||||
|
|
||||||
|
color = plant(color, contrast(max(max(color.r,color.g),color.b)));
|
||||||
|
|
||||||
float p = 2.2;
|
float p = 2.2;
|
||||||
|
|
||||||
color = pow(color, vec3(p));
|
color = pow(color, vec3(p));
|
||||||
|
@ -238,21 +250,24 @@ void main()
|
||||||
color = mix(color, comp, m);
|
color = mix(color, comp, m);
|
||||||
color = pow(max(color, 0.0), vec3(1.0/p));
|
color = pow(max(color, 0.0), vec3(1.0/p));
|
||||||
|
|
||||||
color = color + bp;
|
if (BP > -0.5) color = color + bp; else
|
||||||
|
{
|
||||||
|
color = max(color + BP/255.0, 0.0) / (1.0 + BP/255.0*step(- BP/255.0, max(max(color.r,color.g),color.b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
color = min(color * params.pre_bb, 1.0);
|
||||||
|
|
||||||
vec2 dx = vec2(params.SourceSize.z, 0.0);
|
vec2 dx = vec2(params.SourceSize.z, 0.0);
|
||||||
vec2 x2 = 2.5 *dx;
|
|
||||||
vec2 xx = dx + dx;
|
vec2 xx = dx + dx;
|
||||||
vec2 x3 = x2 + dx;
|
|
||||||
vec2 pC4 = vTexCoord;
|
vec2 pC4 = vTexCoord;
|
||||||
|
|
||||||
vec3 ol3 = COMPAT_TEXTURE(OriginalHistory1, pC4 -x2).rgb;
|
vec3 ol3 = COMPAT_TEXTURE(OriginalHistory1, pC4 -xx).rgb;
|
||||||
vec3 ol2 = COMPAT_TEXTURE(OriginalHistory1, pC4 -dx).rgb;
|
vec3 ol2 = COMPAT_TEXTURE(OriginalHistory1, pC4 -dx).rgb;
|
||||||
vec3 ol1 = COMPAT_TEXTURE(OriginalHistory1, pC4 ).rgb;
|
vec3 ol1 = COMPAT_TEXTURE(OriginalHistory1, pC4 ).rgb;
|
||||||
vec3 or1 = COMPAT_TEXTURE(OriginalHistory1, pC4 +dx).rgb;
|
vec3 or1 = COMPAT_TEXTURE(OriginalHistory1, pC4 +dx).rgb;
|
||||||
vec3 or2 = COMPAT_TEXTURE(OriginalHistory1, pC4 +xx).rgb;
|
vec3 or2 = COMPAT_TEXTURE(OriginalHistory1, pC4 +xx).rgb;
|
||||||
|
|
||||||
vec3 cl3 = COMPAT_TEXTURE(OriginalHistory0, pC4 -x2).rgb;
|
vec3 cl3 = COMPAT_TEXTURE(OriginalHistory0, pC4 -xx).rgb;
|
||||||
vec3 cl2 = COMPAT_TEXTURE(OriginalHistory0, pC4 -dx).rgb;
|
vec3 cl2 = COMPAT_TEXTURE(OriginalHistory0, pC4 -dx).rgb;
|
||||||
vec3 cl1 = COMPAT_TEXTURE(OriginalHistory0, pC4 ).rgb;
|
vec3 cl1 = COMPAT_TEXTURE(OriginalHistory0, pC4 ).rgb;
|
||||||
vec3 cr1 = COMPAT_TEXTURE(OriginalHistory0, pC4 +dx).rgb;
|
vec3 cr1 = COMPAT_TEXTURE(OriginalHistory0, pC4 +dx).rgb;
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
/*
|
|
||||||
Smart Smoothing Difference Shader
|
|
||||||
|
|
||||||
Copyright (C) 2019 guest(r) - guest.r@gmail.com
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma name SmoothPass
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float STH;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter STH "Smart Smoothing Threshold" 0.7 0.4 1.2 0.05
|
|
||||||
#define STH params.STH
|
|
||||||
#define SourceSize params.SourceSize
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
float df (vec3 A, vec3 B)
|
|
||||||
{
|
|
||||||
float diff = length(A-B);
|
|
||||||
float luma = clamp(length(0.5*min(A,B) + 0.25*(A+B) + 1e-8), 0.0001, 1.0);
|
|
||||||
float diff1 = diff/luma;
|
|
||||||
return 1.0 - clamp(7.0*(max(1.5*diff,diff1)-STH), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 dx = vec2(SourceSize.z, 0.0);
|
|
||||||
vec2 dy = vec2(0.0, SourceSize.w);
|
|
||||||
|
|
||||||
vec3 l1 = COMPAT_TEXTURE(Source, vTexCoord.xy -dx).xyz;
|
|
||||||
vec3 ct = COMPAT_TEXTURE(Source, vTexCoord.xy ).xyz;
|
|
||||||
vec3 r1 = COMPAT_TEXTURE(Source, vTexCoord.xy +dx).xyz;
|
|
||||||
|
|
||||||
float dl = df(ct, l1);
|
|
||||||
float dr = df(ct, r1);
|
|
||||||
|
|
||||||
float resx = dl; float resy = dr;
|
|
||||||
|
|
||||||
FragColor = vec4(resx,resy,1.0,1.0);
|
|
||||||
}
|
|
|
@ -6,12 +6,8 @@ layout(push_constant) uniform Push
|
||||||
vec4 OriginalSize;
|
vec4 OriginalSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
float GAMMA_INPUT;
|
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 0.1 5.0 0.05
|
|
||||||
#define GAMMA_INPUT params.GAMMA_INPUT
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
{
|
{
|
||||||
mat4 MVP;
|
mat4 MVP;
|
||||||
|
@ -31,9 +27,9 @@ void main()
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Original;
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
FragColor = pow(texture(Original, vTexCoord), vec4(GAMMA_INPUT));
|
FragColor = vec4(texture(Source, vTexCoord).rgb, 1.0);
|
||||||
}
|
}
|
|
@ -26,10 +26,15 @@ layout(push_constant) uniform Push
|
||||||
float PR, PG, PB;
|
float PR, PG, PB;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
|
#pragma parameter bogus_resolution "[ INTERNAL RESOLUTION (Quick setup) ]:" 0.0 0.0 1.0 1.0
|
||||||
|
#pragma parameter internal_res " Internal Resolution" 1.0 1.0 8.0 0.10
|
||||||
|
|
||||||
#pragma parameter bogus_afterglow "[ AFTERGLOW SETTINGS ]:" 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_afterglow "[ AFTERGLOW SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
#pragma parameter PR " Persistence Red" 0.14 0.0 0.25 0.01
|
#pragma parameter PR " Persistence Red" 0.32 0.0 0.50 0.01
|
||||||
#pragma parameter PG " Persistence Green" 0.14 0.0 0.25 0.01
|
#pragma parameter PG " Persistence Green" 0.32 0.0 0.50 0.01
|
||||||
#pragma parameter PB " Persistence Blue" 0.14 0.0 0.25 0.01
|
#pragma parameter PB " Persistence Blue" 0.32 0.0 0.50 0.01
|
||||||
|
#pragma parameter AS " Afterglow Strength" 0.20 0.0 0.60 0.01
|
||||||
|
#pragma parameter sat " Afterglow saturation" 0.50 0.0 1.0 0.01
|
||||||
|
|
||||||
#define PR params.PR
|
#define PR params.PR
|
||||||
#define PG params.PG
|
#define PG params.PG
|
||||||
|
@ -68,9 +73,9 @@ void main()
|
||||||
vec3 accumulate = COMPAT_TEXTURE(AfterglowPassFeedback, TEX0.xy).rgb;
|
vec3 accumulate = COMPAT_TEXTURE(AfterglowPassFeedback, TEX0.xy).rgb;
|
||||||
|
|
||||||
float w = 1.0;
|
float w = 1.0;
|
||||||
if ((color.r + color.g + color.b < 3.0/255.0)) { w = 0.0; }
|
if ((color.r + color.g + color.b < 5.0/255.0)) { w = 0.0; }
|
||||||
|
|
||||||
vec3 result = mix( max(mix(color, accumulate, 0.74 + vec3(PR, PG, PB))- 2.0/255.0, 0.0)*(255.0/255.0), color, w);
|
vec3 result = mix( max(mix(color, accumulate, 0.49 + vec3(PR, PG, PB))- 2.0/255.0, 0.0), color, w);
|
||||||
|
|
||||||
FragColor = vec4(result, w);
|
FragColor = vec4(result, w);
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
Gaussian blur - horizontal pass, dynamic range, resizable
|
Gaussian blur - horizontal pass, dynamic range, resizable
|
||||||
|
|
||||||
Copyright (C) 2020 guest(r) - guest.r@gmail.com
|
Copyright (C) 2021 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -21,11 +21,9 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma format R16G16B16A16_SFLOAT
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
vec4 LinearizePassSize;
|
vec4 SourceSize;
|
||||||
vec4 OriginalSize;
|
vec4 OriginalSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
|
@ -33,10 +31,12 @@ layout(push_constant) uniform Push
|
||||||
float SIGMA_HB;
|
float SIGMA_HB;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
#pragma parameter SIZEHB " H. Bloom/Halation Radius" 3.0 1.0 30.0 1.0
|
#pragma parameter bogus_glow "[ GLOW/BLOOM PASS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter SIZEHB " H. Bloom/Halation/Glow Radius" 4.0 1.0 30.0 1.0
|
||||||
#define SIZEHB params.SIZEHB
|
#define SIZEHB params.SIZEHB
|
||||||
|
|
||||||
#pragma parameter SIGMA_HB " Horizontal Bloom/Halation Sigma" 0.70 0.5 15.0 0.10
|
#pragma parameter SIGMA_HB " Horizontal Bloom/Halation/Glow Sigma" 1.0 0.25 15.0 0.05
|
||||||
#define SIGMA_HB params.SIGMA_HB
|
#define SIGMA_HB params.SIGMA_HB
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
@ -75,18 +75,20 @@ void main()
|
||||||
float f = fract(SourceSize1.x * vTexCoord.x);
|
float f = fract(SourceSize1.x * vTexCoord.x);
|
||||||
f = 0.5 - f;
|
f = 0.5 - f;
|
||||||
vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw;
|
vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw;
|
||||||
vec3 color = vec3(0.0);
|
vec4 color = vec4(0.0);
|
||||||
vec2 dx = vec2(SourceSize1.z, 0.0);
|
vec2 dx = vec2(SourceSize1.z, 0.0);
|
||||||
|
|
||||||
float w;
|
float w;
|
||||||
float wsum = 0.0;
|
float wsum = 0.0;
|
||||||
vec3 pixel;
|
vec4 pixel;
|
||||||
float n = -SIZEHB;
|
float n = -SIZEHB;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx).rgb;
|
pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx);
|
||||||
w = gaussian(n+f);
|
w = gaussian(n+f);
|
||||||
|
pixel.a = max(max(pixel.r, pixel.g),pixel.b);
|
||||||
|
pixel.a*=pixel.a*pixel.a;
|
||||||
color = color + w * pixel;
|
color = color + w * pixel;
|
||||||
wsum = wsum + w;
|
wsum = wsum + w;
|
||||||
n = n + 1.0;
|
n = n + 1.0;
|
||||||
|
@ -95,5 +97,5 @@ void main()
|
||||||
|
|
||||||
color = color / wsum;
|
color = color / wsum;
|
||||||
|
|
||||||
FragColor = vec4(color, 1.0);
|
FragColor = vec4(color.rgb, pow(color.a, 0.333333));
|
||||||
}
|
}
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma format R16G16B16A16_SFLOAT
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
|
@ -34,10 +33,10 @@ layout(push_constant) uniform Push
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter SIZEVB " V. Bloom/Halation Radius" 3.0 1.0 30.0 1.0
|
#pragma parameter SIZEVB " V. Bloom/Halation/Glow Radius" 4.0 1.0 30.0 1.0
|
||||||
#define SIZEVB params.SIZEVB
|
#define SIZEVB params.SIZEVB
|
||||||
|
|
||||||
#pragma parameter SIGMA_VB " Vertical Bloom/Halation Sigma" 0.70 0.5 15.0 0.10
|
#pragma parameter SIGMA_VB " Vertical Bloom/Halation/Glow Sigma" 1.0 0.25 15.0 0.05
|
||||||
#define SIGMA_VB params.SIGMA_VB
|
#define SIGMA_VB params.SIGMA_VB
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
@ -72,24 +71,24 @@ float gaussian(float x)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 SourceSize1 = params.SourceSize;
|
vec4 SourceSize1 = vec4(params.SourceSize.x, params.OriginalSize.y, params.SourceSize.z, params.OriginalSize.w);
|
||||||
SourceSize1.yw = params.OriginalSize.yw;
|
|
||||||
|
|
||||||
float f = fract(SourceSize1.y * vTexCoord.y);
|
float f = fract(SourceSize1.y * vTexCoord.y);
|
||||||
f = 0.5 - f;
|
f = 0.5 - f;
|
||||||
vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw;
|
vec2 tex = floor(SourceSize1.xy * vTexCoord)*SourceSize1.zw + 0.5*SourceSize1.zw;
|
||||||
vec3 color = vec3(0.0);
|
vec4 color = vec4(0.0);
|
||||||
vec2 dy = vec2(0.0, SourceSize1.w);
|
vec2 dy = vec2(0.0, SourceSize1.w);
|
||||||
|
|
||||||
float w;
|
float w;
|
||||||
float wsum = 0.0;
|
float wsum = 0.0;
|
||||||
vec3 pixel;
|
vec4 pixel;
|
||||||
float n = -SIZEVB;
|
float n = -SIZEVB;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
pixel = COMPAT_TEXTURE(Source, tex + n*dy).rgb;
|
pixel = COMPAT_TEXTURE(Source, tex + n*dy);
|
||||||
w = gaussian(n+f);
|
w = gaussian(n+f);
|
||||||
|
pixel.a*=pixel.a*pixel.a;
|
||||||
color = color + w * pixel;
|
color = color + w * pixel;
|
||||||
wsum = wsum + w;
|
wsum = wsum + w;
|
||||||
n = n + 1.0;
|
n = n + 1.0;
|
||||||
|
@ -98,5 +97,5 @@ void main()
|
||||||
|
|
||||||
color = color / wsum;
|
color = color / wsum;
|
||||||
|
|
||||||
FragColor = vec4(color, 1.0);
|
FragColor = vec4(color.rgb, pow(color.a, 0.175));
|
||||||
}
|
}
|
193
crt/shaders/guest/hd/crt-guest-advanced-hd-pass1.slang
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
/*
|
||||||
|
CRT - Guest - Advanced - HD - Pass1
|
||||||
|
|
||||||
|
Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
float SIGMA_HOR;
|
||||||
|
float HSHARPNESS;
|
||||||
|
float S_SHARP;
|
||||||
|
float HARNG;
|
||||||
|
float HSHARP;
|
||||||
|
float prescalex;
|
||||||
|
float prescaley;
|
||||||
|
float spike;
|
||||||
|
float SIGMA_VER;
|
||||||
|
float VSHARPNESS;
|
||||||
|
float S_SHARPV;
|
||||||
|
float VARNG;
|
||||||
|
float VSHARP;
|
||||||
|
float internal_res;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter bogus_filtering "[ FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter internal_res " Internal Resolution" 1.0 1.0 8.0 0.10
|
||||||
|
#define internal_res params.internal_res
|
||||||
|
|
||||||
|
#pragma parameter HSHARPNESS " Horizontal Filter Range" 1.0 1.0 8.0 0.25
|
||||||
|
#define HSHARPNESS params.HSHARPNESS
|
||||||
|
|
||||||
|
#pragma parameter SIGMA_HOR " Horizontal Blur Sigma" 0.50 0.1 7.0 0.025
|
||||||
|
#define SIGMA_HOR params.SIGMA_HOR
|
||||||
|
|
||||||
|
#pragma parameter S_SHARP " Substractive Sharpness" 1.0 0.0 2.0 0.10
|
||||||
|
#define S_SHARP params.S_SHARP
|
||||||
|
|
||||||
|
#pragma parameter HSHARP " Sharpness Definition" 1.25 0.0 2.0 0.10
|
||||||
|
#define HSHARP params.HSHARP
|
||||||
|
|
||||||
|
#pragma parameter HARNG " Substractive Sharpness Ringing" 0.2 0.0 4.0 0.10
|
||||||
|
#define HARNG params.HARNG
|
||||||
|
|
||||||
|
#pragma parameter bogus_vfiltering "[ VERTICAL/INTERLACING FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter VSHARPNESS " Vertical Filter Range" 1.0 1.0 8.0 0.25
|
||||||
|
#define VSHARPNESS global.VSHARPNESS
|
||||||
|
|
||||||
|
#pragma parameter SIGMA_VER " Vertical Blur Sigma" 0.50 0.1 7.0 0.025
|
||||||
|
#define SIGMA_VER global.SIGMA_VER
|
||||||
|
|
||||||
|
#pragma parameter S_SHARPV " Vert. Substractive Sharpness" 1.0 0.0 2.0 0.10
|
||||||
|
#define S_SHARPV global.S_SHARPV
|
||||||
|
|
||||||
|
#pragma parameter VSHARP " Vert. Sharpness Definition" 1.25 0.0 2.0 0.10
|
||||||
|
#define VSHARP global.VSHARP
|
||||||
|
|
||||||
|
#pragma parameter VARNG " Substractive Sharpness Ringing" 0.2 0.0 4.0 0.10
|
||||||
|
#define VARNG params.VARNG
|
||||||
|
|
||||||
|
#pragma parameter spike " Scanline Spike Removal" 1.0 0.0 2.0 0.10
|
||||||
|
#define spike params.spike
|
||||||
|
|
||||||
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader...)" 1.0 1.0 5.0 0.25 // Joint parameter with main pass, values must match
|
||||||
|
#define prescalex params.prescalex // prescale-x factor
|
||||||
|
|
||||||
|
#pragma parameter prescaley " Prescale-Y Factor (for xBR...pre-shader...)" 1.0 1.0 5.0 0.25 // Joint parameter with Linearize Pass pass, values must match
|
||||||
|
#define prescaley params.prescaley // prescale-y factor
|
||||||
|
|
||||||
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
|
#define TEX0 vTexCoord
|
||||||
|
|
||||||
|
#define OutputSize params.OutputSize
|
||||||
|
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
||||||
|
|
||||||
|
#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 LinearizePass;
|
||||||
|
|
||||||
|
float invsqrsigma = 1.0/(2.0*SIGMA_HOR*SIGMA_HOR*internal_res*internal_res);
|
||||||
|
|
||||||
|
float gaussian(float x)
|
||||||
|
{
|
||||||
|
return exp(-x*x*invsqrsigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 SourceSize = params.OriginalSize * vec4(prescalex, prescaley, 1.0/prescalex, 1.0/prescaley);
|
||||||
|
|
||||||
|
float f = fract(SourceSize.x * vTexCoord.x);
|
||||||
|
f = 0.5 - f;
|
||||||
|
vec2 tex = floor(SourceSize.xy * vTexCoord)*SourceSize.zw + 0.5*SourceSize.zw;
|
||||||
|
vec3 color = 0.0.xxx;
|
||||||
|
float scolor = 0.0;
|
||||||
|
vec2 dx = vec2(SourceSize.z, 0.0);
|
||||||
|
|
||||||
|
float w = 0.0;
|
||||||
|
float swsum = 0.0;
|
||||||
|
float wsum = 0.0;
|
||||||
|
vec3 pixel;
|
||||||
|
|
||||||
|
float hsharpness = HSHARPNESS * internal_res;
|
||||||
|
vec3 cmax = 0.0.xxx;
|
||||||
|
vec3 cmin = 1.0.xxx;
|
||||||
|
float sharp = gaussian(hsharpness) * S_SHARP;
|
||||||
|
float maxsharp = 0.20;
|
||||||
|
float FPR = hsharpness;
|
||||||
|
float fpx = 0.0;
|
||||||
|
float sp = 0.0;
|
||||||
|
float sw = 0.0;
|
||||||
|
|
||||||
|
float ts = 0.025;
|
||||||
|
vec3 luma = vec3(0.2126, 0.7152, 0.0722);
|
||||||
|
|
||||||
|
float LOOPSIZE = ceil(2.0*FPR);
|
||||||
|
float CLAMPSIZE = round(2.0*LOOPSIZE/3.0);
|
||||||
|
|
||||||
|
float n = -LOOPSIZE;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pixel = COMPAT_TEXTURE(LinearizePass, tex + n*dx).rgb;
|
||||||
|
sp = max(max(pixel.r,pixel.g),pixel.b);
|
||||||
|
|
||||||
|
w = gaussian(n+f) - sharp;
|
||||||
|
fpx = abs(n+f-sign(n)*FPR)/FPR;
|
||||||
|
if (abs(n) <= CLAMPSIZE) { cmax = max(cmax, pixel); cmin = min(cmin, pixel); }
|
||||||
|
if (w < 0.0) w = clamp(w, mix(-maxsharp, 0.0, pow(fpx, HSHARP)), 0.0);
|
||||||
|
|
||||||
|
color = color + w * pixel;
|
||||||
|
wsum = wsum + w;
|
||||||
|
|
||||||
|
sw = max(w, 0.0) * (dot(pixel,luma) + ts);
|
||||||
|
scolor = scolor + sw * sp;
|
||||||
|
swsum = swsum + sw;
|
||||||
|
|
||||||
|
n = n + 1.0;
|
||||||
|
|
||||||
|
} while (n <= LOOPSIZE);
|
||||||
|
|
||||||
|
color = color / wsum;
|
||||||
|
scolor = scolor / swsum;
|
||||||
|
|
||||||
|
color = clamp(mix(clamp(color, cmin, cmax), color, HARNG), 0.0, 1.0);
|
||||||
|
|
||||||
|
scolor = clamp(mix(max(max(color.r, color.g),color.b), scolor, spike), 0.0, 1.0);
|
||||||
|
|
||||||
|
FragColor = vec4(color, scolor);
|
||||||
|
}
|
461
crt/shaders/guest/hd/crt-guest-advanced-hd-pass2.slang
Normal file
|
@ -0,0 +1,461 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
/*
|
||||||
|
CRT - Guest - Advanced - HD - Pass2
|
||||||
|
|
||||||
|
Copyright (C) 2018-2021 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
float IOS, brightboost, brightboost1, gsl, scanline1, scanline2, beam_min, beam_max, beam_size,
|
||||||
|
glow, vertmask, inters, bloom, halation, scans, gamma_c;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
float warpX;
|
||||||
|
float warpY;
|
||||||
|
float csize;
|
||||||
|
float bsize1;
|
||||||
|
float intres;
|
||||||
|
float c_shape;
|
||||||
|
float barspeed;
|
||||||
|
float barintensity;
|
||||||
|
float bardir;
|
||||||
|
float SIGMA_VER;
|
||||||
|
float VSHARPNESS;
|
||||||
|
float S_SHARPV;
|
||||||
|
float VARNG;
|
||||||
|
float VSHARP;
|
||||||
|
float prescaley;
|
||||||
|
float internal_res;
|
||||||
|
float scangamma;
|
||||||
|
float sborder;
|
||||||
|
float scan_falloff;
|
||||||
|
float overscanX;
|
||||||
|
float overscanY;
|
||||||
|
float bloom_dist;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
#pragma parameter bogus_vfiltering "[ VERTICAL/INTERLACING FILTERING OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter VSHARPNESS " Vertical Filter Range" 1.0 1.0 8.0 0.25
|
||||||
|
#define VSHARPNESS global.VSHARPNESS
|
||||||
|
|
||||||
|
#pragma parameter SIGMA_VER " Vertical Blur Sigma" 0.50 0.1 7.0 0.025
|
||||||
|
#define SIGMA_VER global.SIGMA_VER
|
||||||
|
|
||||||
|
#pragma parameter S_SHARPV " Vert. Substractive Sharpness" 1.0 0.0 2.0 0.10
|
||||||
|
#define S_SHARPV global.S_SHARPV
|
||||||
|
|
||||||
|
#pragma parameter VSHARP " Vert. Sharpness Definition" 1.25 0.0 2.0 0.10
|
||||||
|
#define VSHARP global.VSHARP
|
||||||
|
|
||||||
|
#pragma parameter VARNG " Substractive Sharpness Ringing" 0.2 0.0 4.0 0.10
|
||||||
|
#define VARNG global.VARNG
|
||||||
|
|
||||||
|
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with linearize pass, values must match
|
||||||
|
|
||||||
|
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
||||||
|
#define IOS params.IOS // Smart Integer Scaling
|
||||||
|
|
||||||
|
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpX global.warpX // Curvature X
|
||||||
|
|
||||||
|
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpY global.warpY // Curvature Y
|
||||||
|
|
||||||
|
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
||||||
|
#define c_shape global.c_shape // curvature shape
|
||||||
|
|
||||||
|
#pragma parameter overscanX " Overscan X original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanX global.overscanX // OverscanX pixels
|
||||||
|
|
||||||
|
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanY global.overscanY // OverscanY pixels
|
||||||
|
|
||||||
|
#pragma parameter csize " Corner Size" 0.0 0.0 0.25 0.005
|
||||||
|
#define csize global.csize // corner size
|
||||||
|
|
||||||
|
#pragma parameter bsize1 " Border Size" 0.01 0.0 3.0 0.01
|
||||||
|
#define bsize1 global.bsize1 // border size
|
||||||
|
|
||||||
|
#pragma parameter sborder " Border Intensity" 0.75 0.25 2.0 0.05
|
||||||
|
#define sborder global.sborder // border intensity
|
||||||
|
|
||||||
|
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
||||||
|
#define glow params.glow // Glow Strength
|
||||||
|
|
||||||
|
#pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05
|
||||||
|
#define bloom params.bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter mask_bloom " Mask Bloom" 0.0 0.0 2.0 0.05
|
||||||
|
#define mask_bloom params.mask_bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter bloom_dist " Bloom Distribution" 0.0 0.0 3.0 0.05
|
||||||
|
#define bloom_dist global.bloom_dist // bloom effect distribution
|
||||||
|
|
||||||
|
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
||||||
|
#define halation params.halation // halation effect
|
||||||
|
|
||||||
|
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
||||||
|
#define gamma_c params.gamma_c // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05
|
||||||
|
#define brightboost params.brightboost // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025
|
||||||
|
#define brightboost1 params.brightboost1 // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter bogus_scanline "[ SCANLINE OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter gsl " Scanline Type" 0.0 -1.0 2.0 1.0
|
||||||
|
#define gsl params.gsl // Alternate scanlines
|
||||||
|
|
||||||
|
#pragma parameter scanline1 " Scanline Beam Shape Center" 6.0 -20.0 20.0 0.5
|
||||||
|
#define scanline1 params.scanline1 // scanline param, vertical sharpness
|
||||||
|
|
||||||
|
#pragma parameter scanline2 " Scanline Beam Shape Edges" 8.0 3.0 70.0 1.0
|
||||||
|
#define scanline2 params.scanline2 // scanline param, vertical sharpness
|
||||||
|
|
||||||
|
#pragma parameter beam_min " Scanline Shape Dark Pixels" 1.20 0.25 5.0 0.05
|
||||||
|
#define beam_min params.beam_min // dark area beam min - narrow
|
||||||
|
|
||||||
|
#pragma parameter beam_max " Scanline Shape Bright Pixels" 1.00 0.4 3.5 0.025
|
||||||
|
#define beam_max params.beam_max // bright area beam max - wide
|
||||||
|
|
||||||
|
#pragma parameter beam_size " Increased Bright Scanline Beam" 0.60 0.0 1.0 0.05
|
||||||
|
#define beam_size params.beam_size // increased max. beam size
|
||||||
|
|
||||||
|
#pragma parameter vertmask " Scanline Color Deconvergence" 0.0 -1.0 1.0 0.1
|
||||||
|
#define vertmask params.vertmask // Scanline deconvergence colors
|
||||||
|
|
||||||
|
#pragma parameter scans " Scanline Saturation / Mask Falloff" 0.60 0.0 2.5 0.05
|
||||||
|
#define scans params.scans // scanline saturation
|
||||||
|
|
||||||
|
#pragma parameter scan_falloff " Scanline Falloff" 1.0 0.25 2.0 0.05
|
||||||
|
#define scan_falloff global.scan_falloff // scanline falloff
|
||||||
|
|
||||||
|
#pragma parameter scangamma " Scanline Gamma" 2.40 0.5 5.0 0.05
|
||||||
|
#define scangamma global.scangamma
|
||||||
|
|
||||||
|
#pragma parameter prescaley " Prescale-Y Factor (for xBR...pre-shader...)" 1.0 1.0 5.0 0.25 // Joint parameter with Linearize Pass pass, values must match
|
||||||
|
#define prescaley global.prescaley // prescale-y factor
|
||||||
|
|
||||||
|
#pragma parameter internal_res " Internal Resolution" 1.0 1.0 8.0 0.10
|
||||||
|
#define internal_res global.internal_res
|
||||||
|
|
||||||
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
|
#define TEX0 vTexCoord
|
||||||
|
|
||||||
|
#define OutputSize global.OutputSize
|
||||||
|
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
||||||
|
|
||||||
|
#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 Pass1;
|
||||||
|
layout(set = 0, binding = 3) uniform sampler2D LinearizePass;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D BloomPass;
|
||||||
|
layout(set = 0, binding = 5) uniform sampler2D PrePass;
|
||||||
|
|
||||||
|
#define eps 1e-10
|
||||||
|
|
||||||
|
float st(float x)
|
||||||
|
{
|
||||||
|
return exp2(-10.0*x*x);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sw0(float x, float color, float scanline)
|
||||||
|
{
|
||||||
|
float tmp = mix(beam_min, beam_max, color);
|
||||||
|
float ex = x*tmp;
|
||||||
|
ex = (gsl > -0.5) ? ex*ex : mix(ex*ex, ex*ex*ex, 0.4);
|
||||||
|
return exp2(-scanline*ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sw1(float x, float color, float scanline)
|
||||||
|
{
|
||||||
|
x = mix (x, beam_min*x, max(x-0.4*color,0.0));
|
||||||
|
float tmp = mix(1.2*beam_min, beam_max, color);
|
||||||
|
float ex = x*tmp;
|
||||||
|
return exp2(-scanline*ex*ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sw2(float x, float color, float scanline)
|
||||||
|
{
|
||||||
|
float tmp = mix((2.5-0.5*color)*beam_min, beam_max, color);
|
||||||
|
tmp = mix(beam_max, tmp, pow(x, color+0.3));
|
||||||
|
float ex = x*tmp;
|
||||||
|
return exp2(-scanline*ex*ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 gc(vec3 c)
|
||||||
|
{
|
||||||
|
float mc = max(max(c.r,c.g),c.b);
|
||||||
|
float mg = pow(mc, 1.0/gamma_c);
|
||||||
|
return c * mg/(mc + eps);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Overscan(vec2 pos, float dx, float dy){
|
||||||
|
pos=pos*2.0-1.0;
|
||||||
|
pos*=vec2(dx,dy);
|
||||||
|
return pos*0.5+0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Warp(vec2 pos)
|
||||||
|
{
|
||||||
|
pos = pos*2.0-1.0;
|
||||||
|
pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape);
|
||||||
|
return pos*0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float invsqrsigma = 1.0/(2.0*SIGMA_VER*SIGMA_VER*internal_res*internal_res);
|
||||||
|
|
||||||
|
float gaussian(float x)
|
||||||
|
{
|
||||||
|
return exp(-x*x*invsqrsigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 v_resample (vec2 tex0, vec4 Size) {
|
||||||
|
|
||||||
|
float f = fract(Size.y * tex0.y);
|
||||||
|
f = 0.5 - f;
|
||||||
|
vec2 tex = tex0;
|
||||||
|
tex.y = floor(Size.y *tex.y)*Size.w + 0.5*Size.w;
|
||||||
|
vec3 color = 0.0.xxx;
|
||||||
|
vec2 dy = vec2(0.0, Size.w);
|
||||||
|
|
||||||
|
float w = 0.0;
|
||||||
|
float wsum = 0.0;
|
||||||
|
vec3 pixel;
|
||||||
|
|
||||||
|
vec3 cmax = 0.0.xxx;
|
||||||
|
vec3 cmin = 1.0.xxx;
|
||||||
|
float vsharpness = VSHARPNESS*internal_res;
|
||||||
|
float sharp = gaussian(vsharpness) * S_SHARPV;
|
||||||
|
float maxsharp = 0.20;
|
||||||
|
float FPR = vsharpness;
|
||||||
|
float fpx = 0.0;
|
||||||
|
|
||||||
|
float LOOPSIZE = ceil(2.0*FPR);
|
||||||
|
float CLAMPSIZE = round(2.0*LOOPSIZE/3.0);
|
||||||
|
|
||||||
|
float n = -LOOPSIZE;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pixel = COMPAT_TEXTURE(Pass1, tex + n*dy).rgb;
|
||||||
|
|
||||||
|
w = gaussian(n+f) - sharp;
|
||||||
|
fpx = abs(n+f-sign(n)*FPR)/FPR;
|
||||||
|
if (abs(n) <= CLAMPSIZE) { cmax = max(cmax, pixel); cmin = min(cmin, pixel); }
|
||||||
|
if (w < 0.0) w = clamp(w, mix(-maxsharp, 0.0, pow(fpx, VSHARP)), 0.0);
|
||||||
|
|
||||||
|
color = color + w * pixel;
|
||||||
|
wsum = wsum + w;
|
||||||
|
|
||||||
|
n = n + 1.0;
|
||||||
|
|
||||||
|
} while (n <= LOOPSIZE);
|
||||||
|
|
||||||
|
color = color / wsum;
|
||||||
|
|
||||||
|
color = clamp(mix(clamp(color, cmin, cmax), color, VARNG), 0.0, 1.0);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 SourceSize = vec4(global.SourceSize.x, global.OriginalSize.y, global.SourceSize.z, global.OriginalSize.w);
|
||||||
|
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
||||||
|
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
||||||
|
bool interb = (intera < 0.5);
|
||||||
|
|
||||||
|
float SourceY = SourceSize.y;
|
||||||
|
float sy = 1.0;
|
||||||
|
if (global.intres == 0.5) sy = SourceY/224.0; else
|
||||||
|
if (global.intres == 1.0) sy = SourceY/240.0; else
|
||||||
|
if (global.intres > 1.25) sy = global.intres;
|
||||||
|
SourceSize*=vec4(1.0, 1.0/sy, 1.0, sy);
|
||||||
|
|
||||||
|
// Calculating texel coordinates
|
||||||
|
|
||||||
|
vec2 texcoord = TEX0.xy;
|
||||||
|
|
||||||
|
if (IOS > 0.0 && !interb){
|
||||||
|
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
||||||
|
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
||||||
|
vec2 diff = ofactor/intfactor;
|
||||||
|
float scan = diff.y;
|
||||||
|
texcoord = Overscan(texcoord, scan, scan);
|
||||||
|
if (IOS == 1.0 || IOS == 3.0) texcoord = vec2(TEX0.x, texcoord.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
texcoord = Overscan(texcoord, (global.OriginalSize.x - overscanX)/global.OriginalSize.x, (global.OriginalSize.y - overscanY)/global.OriginalSize.y);
|
||||||
|
|
||||||
|
vec2 pos = Warp(texcoord);
|
||||||
|
|
||||||
|
float coffset = 0.5;
|
||||||
|
|
||||||
|
vec2 ps = SourceSize.zw;
|
||||||
|
float OGL2Pos = pos.y * SourceSize.y - coffset;
|
||||||
|
float f = fract(OGL2Pos);
|
||||||
|
|
||||||
|
vec2 dx = vec2(ps.x,0.0);
|
||||||
|
vec2 dy = vec2(0.0, ps.y);
|
||||||
|
|
||||||
|
// Reading the texels
|
||||||
|
|
||||||
|
vec2 pC4;
|
||||||
|
|
||||||
|
pC4.y = floor(OGL2Pos) * ps.y + 0.5*ps.y;
|
||||||
|
pC4.x = pos.x;
|
||||||
|
|
||||||
|
vec3 color1 = COMPAT_TEXTURE(Pass1, pC4 ).rgb;
|
||||||
|
vec3 scolor1 = COMPAT_TEXTURE(Pass1, pC4 ).aaa;
|
||||||
|
|
||||||
|
color1 = pow(color1, vec3(scangamma/gamma_in));
|
||||||
|
|
||||||
|
if (interb) color1 = v_resample(pos, SourceSize * vec4(1.0, prescaley, 1.0, 1.0/prescaley));
|
||||||
|
|
||||||
|
pC4+=dy;
|
||||||
|
|
||||||
|
vec3 color2 = COMPAT_TEXTURE(Pass1, pC4 ).rgb;
|
||||||
|
vec3 scolor2 = COMPAT_TEXTURE(Pass1, pC4 ).aaa;
|
||||||
|
|
||||||
|
color2 = pow(color2, vec3(scangamma/gamma_in));
|
||||||
|
|
||||||
|
// calculating scanlines
|
||||||
|
|
||||||
|
vec3 ctmp = color1; vec3 mcolor = scolor1; float w3 = 1.0; vec3 color = color1;
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
|
||||||
|
if (!interb)
|
||||||
|
{
|
||||||
|
float shape1 = mix(scanline1, scanline2, f);
|
||||||
|
float shape2 = mix(scanline1, scanline2, 1.0-f);
|
||||||
|
|
||||||
|
float wt1 = st(f);
|
||||||
|
float wt2 = st(1.0-f);
|
||||||
|
|
||||||
|
vec3 color00 = color1*wt1 + color2*wt2;
|
||||||
|
vec3 scolor0 = scolor1*wt1 + scolor2*wt2;
|
||||||
|
|
||||||
|
ctmp = color00/(wt1+wt2);
|
||||||
|
vec3 sctmp = max(scolor0/(wt1+wt2), ctmp);
|
||||||
|
|
||||||
|
float wf1, wf2;
|
||||||
|
|
||||||
|
vec3 cref1 = mix(sctmp, scolor1, beam_size); float creff1 = pow(max(max(cref1.r,cref1.g),cref1.b), scan_falloff);
|
||||||
|
vec3 cref2 = mix(sctmp, scolor2, beam_size); float creff2 = pow(max(max(cref2.r,cref2.g),cref2.b), scan_falloff);
|
||||||
|
|
||||||
|
float f1 = f;
|
||||||
|
float f2 = 1.0-f;
|
||||||
|
|
||||||
|
if (gsl < 0.5) { wf1 = sw0(f1,creff1,shape1); wf2 = sw0(f2,creff2,shape2);} else
|
||||||
|
if (gsl == 1.0) { wf1 = sw1(f1,creff1,shape1); wf2 = sw1(f2,creff2,shape2);} else
|
||||||
|
{ wf1 = sw2(f1,creff1,shape1); wf2 = sw2(f2,creff2,shape2);}
|
||||||
|
|
||||||
|
if ((wf1 + wf2) > 1.0) { float wtmp = 1.0/(wf1+wf2); wf1*=wtmp; wf2*=wtmp; }
|
||||||
|
|
||||||
|
// Scanline saturation application
|
||||||
|
|
||||||
|
vec3 w1 = vec3(wf1); vec3 w2 = vec3(wf2);
|
||||||
|
w3 = wf1+wf2;
|
||||||
|
|
||||||
|
float mc1 = max(max(color1.r,color1.g),color1.b) + eps;
|
||||||
|
float mc2 = max(max(color2.r,color2.g),color2.b) + eps;
|
||||||
|
|
||||||
|
cref1 = color1 / mc1; cref1=cref1*cref1; cref1*=cref1;
|
||||||
|
cref2 = color2 / mc2; cref2=cref2*cref2; cref2*=cref2;
|
||||||
|
|
||||||
|
w1 = max( mix(w1*mix(one, cref1, scans), w1, wf1*min((1.0+0.15*scans), 1.2)), 0.0); w1 = min(w1*color1, mc1)/(color1 + eps);
|
||||||
|
w2 = max( mix(w2*mix(one, cref2, scans), w2, wf2*min((1.0+0.15*scans), 1.2)), 0.0); w2 = min(w2*color2, mc2)/(color2 + eps);
|
||||||
|
|
||||||
|
// Scanline Deconvergence
|
||||||
|
|
||||||
|
vec3 cd1 = one; vec3 cd2 = one; float vm = sqrt(abs(vertmask));
|
||||||
|
|
||||||
|
float v_high1 = 1.0 + 0.3*vm;
|
||||||
|
float v_high2 = 1.0 + 0.6*vm;
|
||||||
|
float v_low = 1.0 - vm;
|
||||||
|
|
||||||
|
float ds1 = min(max(1.0-w3*w3, 2.5*f1), 1.0);
|
||||||
|
float ds2 = min(max(1.0-w3*w3, 2.5*f2), 1.0);
|
||||||
|
|
||||||
|
if (vertmask < 0.0)
|
||||||
|
{
|
||||||
|
cd1 = mix(one, vec3(v_high2, v_low, v_low), ds1);
|
||||||
|
cd2 = mix(one, vec3(v_low, v_high1, v_high1), ds2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd1 = mix(one, vec3(v_high1, v_low, v_high1), ds1);
|
||||||
|
cd2 = mix(one, vec3(v_low, v_high2, v_low), ds2);
|
||||||
|
}
|
||||||
|
|
||||||
|
color = gc(color1)*w1*cd1 + gc(color2)*w2*cd2;
|
||||||
|
color = min(color, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interb)
|
||||||
|
{
|
||||||
|
color = gc(color1);
|
||||||
|
}
|
||||||
|
|
||||||
|
float colmx = pow(max(max(ctmp.r,ctmp.g),ctmp.b), 1.40/gamma_in);
|
||||||
|
|
||||||
|
if (!interb) color = pow( color, vec3(gamma_in/scangamma) );
|
||||||
|
|
||||||
|
FragColor = vec4(color, colmx);
|
||||||
|
}
|
682
crt/shaders/guest/hd/deconvergence-hd.slang
Normal file
|
@ -0,0 +1,682 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
/*
|
||||||
|
CRT - Guest - Advanced
|
||||||
|
|
||||||
|
Copyright (C) 2018-2022 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
|
Incorporates many good ideas and suggestions from Dr. Venom.
|
||||||
|
I would also like give thanks to many Libretro forums members for continuous feedback, suggestions and caring about the shader.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
float IOS, brightboost, brightboost1, csize, bsize1, warpX, warpY, glow, shadowMask, masksize,
|
||||||
|
slotmask, slotmask1, slotwidth, double_slot, mcut, maskDark, maskLight, maskstr, mshift, mask_layout, mask_bloom;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
float bloom;
|
||||||
|
float halation;
|
||||||
|
float slotms;
|
||||||
|
float mclip;
|
||||||
|
float mask_gamma;
|
||||||
|
float gamma_out;
|
||||||
|
float overscanX;
|
||||||
|
float overscanY;
|
||||||
|
float intres;
|
||||||
|
float prescalex;
|
||||||
|
float c_shape;
|
||||||
|
float barspeed;
|
||||||
|
float barintensity;
|
||||||
|
float bardir;
|
||||||
|
float sborder;
|
||||||
|
float bloom_dist;
|
||||||
|
float deconr;
|
||||||
|
float decons;
|
||||||
|
float addnoised;
|
||||||
|
float noiseresd;
|
||||||
|
float noisetype;
|
||||||
|
float deconrr;
|
||||||
|
float deconrg;
|
||||||
|
float deconrb;
|
||||||
|
float deconrry;
|
||||||
|
float deconrgy;
|
||||||
|
float deconrby;
|
||||||
|
float dctypex;
|
||||||
|
float dctypey;
|
||||||
|
float post_br;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter bogus_brightness "[ BRIGHTNESS SETTINGS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter glow " Glow Strength" 0.08 -2.0 2.0 0.01
|
||||||
|
#define glow params.glow // Glow Strength
|
||||||
|
|
||||||
|
#pragma parameter bloom " Bloom Strength" 0.0 -2.0 2.0 0.05
|
||||||
|
#define bloom global.bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter mask_bloom " Mask Bloom" 0.0 0.0 2.0 0.05
|
||||||
|
#define mask_bloom params.mask_bloom // bloom effect
|
||||||
|
|
||||||
|
#pragma parameter bloom_dist " Bloom Distribution" 0.0 0.0 3.0 0.05
|
||||||
|
#define bloom_dist global.bloom_dist // bloom effect distribution
|
||||||
|
|
||||||
|
#pragma parameter halation " Halation Strength" 0.0 0.0 2.0 0.025
|
||||||
|
#define halation global.halation // halation effect
|
||||||
|
|
||||||
|
#pragma parameter gamma_c " Gamma correct" 1.0 0.50 2.0 0.02
|
||||||
|
#define gamma_c global.gamma_c // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost " Bright Boost Dark Pixels" 1.40 0.25 10.0 0.05
|
||||||
|
#define brightboost params.brightboost // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter brightboost1 " Bright Boost Bright Pixels" 1.10 0.25 3.00 0.025
|
||||||
|
#define brightboost1 params.brightboost1 // adjust brightness
|
||||||
|
|
||||||
|
#pragma parameter bogus_screen "[ SCREEN OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter IOS " Integer Scaling: Odd:Y, Even:'X'+Y" 0.0 0.0 4.0 1.0
|
||||||
|
#define IOS params.IOS // Smart Integer Scaling
|
||||||
|
|
||||||
|
#pragma parameter csize " Corner Size" 0.0 0.0 0.25 0.005
|
||||||
|
#define csize params.csize // corner size
|
||||||
|
|
||||||
|
#pragma parameter bsize1 " Border Size" 0.01 0.0 3.0 0.01
|
||||||
|
#define bsize1 params.bsize1 // border Size
|
||||||
|
|
||||||
|
#pragma parameter sborder " Border Intensity" 0.75 0.25 2.0 0.05
|
||||||
|
#define sborder global.sborder // border intensity
|
||||||
|
|
||||||
|
#pragma parameter barspeed " Hum Bar Speed" 50.0 5.0 200.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter barintensity " Hum Bar Intensity" 0.0 -1.0 1.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter bardir " Hum Bar Direction" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter warpX " CurvatureX (default 0.03)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpX params.warpX // Curvature X
|
||||||
|
|
||||||
|
#pragma parameter warpY " CurvatureY (default 0.04)" 0.0 0.0 0.25 0.01
|
||||||
|
#define warpY params.warpY // Curvature Y
|
||||||
|
|
||||||
|
#pragma parameter c_shape " Curvature Shape" 0.25 0.05 0.60 0.05
|
||||||
|
#define c_shape global.c_shape // curvature shape
|
||||||
|
|
||||||
|
#pragma parameter overscanX " Overscan X original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanX global.overscanX // OverscanX pixels
|
||||||
|
|
||||||
|
#pragma parameter overscanY " Overscan Y original pixels" 0.0 -200.0 200.0 1.0
|
||||||
|
#define overscanY global.overscanY // OverscanY pixels
|
||||||
|
|
||||||
|
#pragma parameter bogus_masks "[ CRT MASK OPTIONS ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter shadowMask " CRT Mask: 0:CGWG, 1-4:Lottes, 5-12:'Trinitron'" 0.0 -1.0 12.0 1.0
|
||||||
|
#define shadowMask params.shadowMask // Mask Style
|
||||||
|
|
||||||
|
#pragma parameter maskstr " Mask Strength (0, 5-12)" 0.3 -0.5 1.0 0.025
|
||||||
|
#define maskstr params.maskstr // Mask Strength
|
||||||
|
|
||||||
|
#pragma parameter mcut " Mask 5-12 Low Strength" 1.10 0.0 2.0 0.05
|
||||||
|
#define mcut params.mcut // Mask 5-12 dark color strength
|
||||||
|
|
||||||
|
#pragma parameter masksize " CRT Mask Size" 1.0 1.0 4.0 1.0
|
||||||
|
#define masksize params.masksize // Mask Size
|
||||||
|
|
||||||
|
#pragma parameter maskDark " Lottes maskDark" 0.5 0.0 2.0 0.05
|
||||||
|
#define maskDark params.maskDark // Dark "Phosphor"
|
||||||
|
|
||||||
|
#pragma parameter maskLight " Lottes maskLight" 1.5 0.0 2.0 0.05
|
||||||
|
#define maskLight params.maskLight // Light "Phosphor"
|
||||||
|
|
||||||
|
#pragma parameter mshift " Mask Shift/Stagger" 0.0 -8.0 8.0 1.0
|
||||||
|
#define mshift params.mshift // mask 'line' shift/stagger
|
||||||
|
|
||||||
|
#pragma parameter mask_layout " Mask Layout: RGB or BGR (check LCD panel) " 0.0 0.0 1.0 1.0
|
||||||
|
#define mask_layout params.mask_layout // mask layout: RGB or BGR
|
||||||
|
|
||||||
|
#pragma parameter mask_gamma " Mask gamma" 2.40 1.0 5.0 0.05
|
||||||
|
#define mask_gamma global.mask_gamma // Mask application gamma
|
||||||
|
|
||||||
|
#pragma parameter slotmask " Slot Mask Strength Bright Pixels" 0.0 0.0 1.0 0.05
|
||||||
|
#define slotmask params.slotmask
|
||||||
|
|
||||||
|
#pragma parameter slotmask1 " Slot Mask Strength Dark Pixels" 0.0 0.0 1.0 0.05
|
||||||
|
#define slotmask1 params.slotmask1
|
||||||
|
|
||||||
|
#pragma parameter slotwidth " Slot Mask Width" 2.0 1.0 8.0 1.0
|
||||||
|
#define slotwidth params.slotwidth // Slot Mask Width
|
||||||
|
|
||||||
|
#pragma parameter double_slot " Slot Mask Height: 2x1 or 4x1..." 1.0 1.0 4.0 1.0
|
||||||
|
#define double_slot params.double_slot // Slot Mask Height
|
||||||
|
|
||||||
|
#pragma parameter slotms " Slot Mask Size" 1.0 1.0 4.0 1.0
|
||||||
|
#define slotms global.slotms // Slot Mask Size
|
||||||
|
|
||||||
|
#pragma parameter mclip " Keep Mask effect with clipping" 0.50 0.0 1.0 0.05
|
||||||
|
#define mclip global.mclip //
|
||||||
|
|
||||||
|
#pragma parameter gamma_out "Gamma out" 1.75 1.0 5.0 0.05
|
||||||
|
#define gamma_out global.gamma_out // output gamma
|
||||||
|
|
||||||
|
|
||||||
|
#pragma parameter bogus_deconvergence11 "[ HORIZONTAL/VERTICAL DECONVERGENCE ]: " 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter dctypex " Deconvergence type X : 0.0 - static, other - dynamic" 0.0 0.0 0.75 0.05
|
||||||
|
|
||||||
|
#pragma parameter dctypey " Deconvergence type Y : 0.0 - static, other - dynamic" 0.0 0.0 0.75 0.05
|
||||||
|
|
||||||
|
#pragma parameter deconrr " Horizontal Deconvergence Red Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrg " Horizontal Deconvergence Green Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrb " Horizontal Deconvergence Blue Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrry " Vertical Deconvergence Red Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrgy " Vertical Deconvergence Green Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter deconrby " Vertical Deconvergence Blue Range" 0.0 -15.0 15.0 0.25
|
||||||
|
|
||||||
|
#pragma parameter decons " Deconvergence Strength" 1.0 0.0 3.0 0.10
|
||||||
|
|
||||||
|
#pragma parameter addnoised " Add Noise" 0.0 -1.0 1.0 0.02
|
||||||
|
|
||||||
|
#pragma parameter noiseresd " Noise Resolution" 2.0 1.0 10.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter noisetype " Noise Type: Colored, Luma" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter post_br " Post Brightness" 1.0 0.25 5.0 0.01
|
||||||
|
|
||||||
|
|
||||||
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
|
#define TEX0 vTexCoord
|
||||||
|
|
||||||
|
#define OutputSize global.OutputSize
|
||||||
|
#define gl_FragCoord (vTexCoord * OutputSize.xy)
|
||||||
|
|
||||||
|
#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 LinearizePass;
|
||||||
|
layout(set = 0, binding = 3) uniform sampler2D BloomPass;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D PrePass;
|
||||||
|
layout(set = 0, binding = 5) uniform sampler2D Source;
|
||||||
|
|
||||||
|
#define eps 1e-10
|
||||||
|
|
||||||
|
// Shadow mask (1-4 from PD CRT Lottes shader).
|
||||||
|
|
||||||
|
vec3 Mask(vec2 pos, float mx)
|
||||||
|
{
|
||||||
|
vec2 pos0 = pos;
|
||||||
|
pos.y = floor(pos.y/masksize);
|
||||||
|
float next_line = float(fract(pos.y*0.5) > 0.25);
|
||||||
|
pos0.x = (mshift > -0.25) ? (pos0.x + next_line * mshift) : (pos0.x + pos.y * mshift);
|
||||||
|
pos = floor(pos0/masksize);
|
||||||
|
|
||||||
|
vec3 mask = vec3(maskDark, maskDark, maskDark);
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
float dark_compensate = mix(max( clamp( mix (mcut, maskstr, mx),0.0, 1.0) - 0.4, 0.0) + 1.0, 1.0, mx);
|
||||||
|
float mc = 1.0 - max(maskstr, 0.0);
|
||||||
|
|
||||||
|
// No mask
|
||||||
|
if (shadowMask == -1.0)
|
||||||
|
{
|
||||||
|
mask = vec3(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phosphor.
|
||||||
|
else if (shadowMask == 0.0)
|
||||||
|
{
|
||||||
|
pos.x = fract(pos.x*0.5);
|
||||||
|
if (pos.x < 0.49) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
|
||||||
|
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Very compressed TV style shadow mask.
|
||||||
|
else if (shadowMask == 1.0)
|
||||||
|
{
|
||||||
|
float line = maskLight;
|
||||||
|
float odd = 0.0;
|
||||||
|
|
||||||
|
if (fract(pos.x/6.0) < 0.49)
|
||||||
|
odd = 1.0;
|
||||||
|
if (fract((pos.y + odd)/2.0) < 0.49)
|
||||||
|
line = maskDark;
|
||||||
|
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
|
||||||
|
mask*=line;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aperture-grille.
|
||||||
|
else if (shadowMask == 2.0)
|
||||||
|
{
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stretched VGA style shadow mask (same as prior shaders).
|
||||||
|
else if (shadowMask == 3.0)
|
||||||
|
{
|
||||||
|
pos.x += pos.y*3.0;
|
||||||
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VGA style shadow mask.
|
||||||
|
else if (shadowMask == 4.0)
|
||||||
|
{
|
||||||
|
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
|
||||||
|
pos.x += pos.y*3.0;
|
||||||
|
pos.x = fract(pos.x/6.0);
|
||||||
|
|
||||||
|
if (pos.x < 0.3) mask.r = maskLight;
|
||||||
|
else if (pos.x < 0.6) mask.g = maskLight;
|
||||||
|
else mask.b = maskLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trinitron mask 5
|
||||||
|
else if (shadowMask == 5.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/2.0);
|
||||||
|
if (pos.x < 0.49)
|
||||||
|
{ mask.r = 1.0;
|
||||||
|
mask.b = 1.0;
|
||||||
|
}
|
||||||
|
else mask.g = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trinitron mask 6
|
||||||
|
else if (shadowMask == 6.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.6) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BW Trinitron mask 7
|
||||||
|
else if (shadowMask == 7.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/2.0);
|
||||||
|
if (pos.x < 0.49)
|
||||||
|
{ mask = 0.0.xxx;
|
||||||
|
}
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BW Trinitron mask 8
|
||||||
|
else if (shadowMask == 8.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask = 1.0.xxx;
|
||||||
|
else mask = 1.0.xxx;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magenta - Green - Black mask
|
||||||
|
else if (shadowMask == 9.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x/3.0);
|
||||||
|
if (pos.x < 0.3) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.6) mask.rb = 1.0.xx;
|
||||||
|
else mask.g = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RGBX
|
||||||
|
else if (shadowMask == 10.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 0.4) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.7) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4k mask
|
||||||
|
else if (shadowMask == 11.0)
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = fract(pos.x * 0.25);
|
||||||
|
if (pos.x < 0.2) mask.r = 1.0;
|
||||||
|
else if (pos.x < 0.4) mask.rg = 1.0.xx;
|
||||||
|
else if (pos.x < 0.7) mask.gb = 1.0.xx;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RRGGBBX mask
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = vec3(0.0);
|
||||||
|
pos.x = floor(mod(pos.x,7.0));
|
||||||
|
if (pos.x < 1.0) mask = 0.0.xxx;
|
||||||
|
else if (pos.x < 3.0) mask.r = 1.0;
|
||||||
|
else if (pos.x < 5.0) mask.g = 1.0;
|
||||||
|
else mask.b = 1.0;
|
||||||
|
mask = clamp(mix( mix(one, mask, mcut), mix(one, mask, maskstr), mx), 0.0, 1.0) * dark_compensate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SlotMask(vec2 pos, float m)
|
||||||
|
{
|
||||||
|
if ((slotmask + slotmask1) == 0.0) return 1.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos = floor(pos/slotms);
|
||||||
|
float mlen = slotwidth*2.0;
|
||||||
|
float px = fract(pos.x/mlen);
|
||||||
|
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
|
||||||
|
float slot_dark = mix(1.0-slotmask1, 1.0-slotmask, m);
|
||||||
|
float slot = 1.0;
|
||||||
|
if (py == 0.0 && px < 0.5) slot = slot_dark; else
|
||||||
|
if (py == double_slot && px >= 0.5) slot = slot_dark;
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Warp(vec2 pos)
|
||||||
|
{
|
||||||
|
pos = pos*2.0-1.0;
|
||||||
|
pos = mix(pos, vec2(pos.x*inversesqrt(1.0-c_shape*pos.y*pos.y), pos.y*inversesqrt(1.0-c_shape*pos.x*pos.x)), vec2(warpX, warpY)/c_shape);
|
||||||
|
return pos*0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Overscan(vec2 pos, float dx, float dy){
|
||||||
|
pos=pos*2.0-1.0;
|
||||||
|
pos*=vec2(dx,dy);
|
||||||
|
return pos*0.5+0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
float humbar(float pos)
|
||||||
|
{
|
||||||
|
if (global.barintensity == 0.0) return 1.0; else
|
||||||
|
{
|
||||||
|
pos = (global.barintensity >= 0.0) ? pos : (1.0-pos);
|
||||||
|
pos = fract(pos + mod(float(global.FrameCount),global.barspeed)/(global.barspeed-1.0));
|
||||||
|
pos = (global.barintensity < 0.0) ? pos : (1.0-pos);
|
||||||
|
return (1.0-global.barintensity) + global.barintensity*pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float corner(vec2 pos) {
|
||||||
|
vec2 b = vec2(bsize1, bsize1) * vec2(1.0, OutputSize.x/OutputSize.y) * 0.05;
|
||||||
|
pos = clamp(pos, 0.0, 1.0);
|
||||||
|
pos = abs(2.0*(pos - 0.5));
|
||||||
|
float csize1 = mix(400.0, 7.0, pow(4.0*csize, 0.10));
|
||||||
|
float crn = dot(pow(pos, csize1.xx), vec2(1.0, OutputSize.y/OutputSize.x));
|
||||||
|
crn = (csize == 0.0) ? max(pos.x, pos.y) : pow(crn, 1.0/csize1);
|
||||||
|
pos = max(pos, crn);
|
||||||
|
vec2 res = (bsize1 == 0.0) ? 1.0.xx : mix(0.0.xx, 1.0.xx, smoothstep(1.0.xx, 1.0.xx-b, sqrt(pos)));
|
||||||
|
res = pow(res, sborder.xx);
|
||||||
|
return sqrt(res.x*res.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 plant (vec3 tar, float r)
|
||||||
|
{
|
||||||
|
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
||||||
|
return tar * r / t;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 declip(vec3 c, float b)
|
||||||
|
{
|
||||||
|
float m = max(max(c.r,c.g),c.b);
|
||||||
|
if (m > b) c = c*b/m;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// noise function:
|
||||||
|
// Dedicated to the public domain.
|
||||||
|
// If you want a real license, you may consider this MIT/BSD/CC0/WTFPL-licensed (take your pick).
|
||||||
|
// Adapted from ChuckNorris - shadertoy: https://www.shadertoy.com/view/XtK3Dz
|
||||||
|
|
||||||
|
vec3 noise(vec3 v){
|
||||||
|
if (global.addnoised < 0.0) v.z = -global.addnoised; else v.z = mod(v.z,6001.0)/1753.0;
|
||||||
|
// ensure reasonable range
|
||||||
|
v = fract(v) + fract(v*1e4) + fract(v*1e-4);
|
||||||
|
// seed
|
||||||
|
v += vec3(0.12345, 0.6789, 0.314159);
|
||||||
|
// more iterations => more random
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
v = fract(v*dot(v, v)*123.456);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fetch_pixel (inout vec3 c, inout vec3 b, vec2 coord, vec2 bcoord)
|
||||||
|
{
|
||||||
|
float stepx = OutputSize.z;
|
||||||
|
float stepy = OutputSize.w;
|
||||||
|
|
||||||
|
float ds = global.decons;
|
||||||
|
|
||||||
|
vec2 dx = vec2(stepx, 0.0);
|
||||||
|
vec2 dy = vec2(0.0, stepy);
|
||||||
|
|
||||||
|
float posx = 2.0*coord.x - 1.0;
|
||||||
|
float posy = 2.0*coord.y - 1.0;
|
||||||
|
|
||||||
|
if (global.dctypex > 0.025)
|
||||||
|
{
|
||||||
|
posx = sign(posx)*pow(abs(posx), 1.05-global.dctypex);
|
||||||
|
dx = posx * dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global.dctypey > 0.025)
|
||||||
|
{
|
||||||
|
|
||||||
|
posy = sign(posy)*pow(abs(posy), 1.05-global.dctypey);
|
||||||
|
dy = posy * dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (global.dctypex > 0.025 || global.dctypey > 0.025) ds *= sqrt(posx*posx*sign(global.dctypex) + posy*posy*sign(global.dctypey));
|
||||||
|
|
||||||
|
vec2 rc = global.deconrr * dx + global.deconrry*dy;
|
||||||
|
vec2 gc = global.deconrg * dx + global.deconrgy*dy;
|
||||||
|
vec2 bc = global.deconrb * dx + global.deconrby*dy;
|
||||||
|
|
||||||
|
float r1 = COMPAT_TEXTURE(Source, coord + rc).r;
|
||||||
|
float g1 = COMPAT_TEXTURE(Source, coord + gc).g;
|
||||||
|
float b1 = COMPAT_TEXTURE(Source, coord + bc).b;
|
||||||
|
|
||||||
|
vec3 d = vec3(r1, g1, b1);
|
||||||
|
c = clamp(mix(c, d, ds), 0.0, 1.0);
|
||||||
|
|
||||||
|
r1 = COMPAT_TEXTURE(BloomPass, bcoord + rc).r;
|
||||||
|
g1 = COMPAT_TEXTURE(BloomPass, bcoord + gc).g;
|
||||||
|
b1 = COMPAT_TEXTURE(BloomPass, bcoord + bc).b;
|
||||||
|
|
||||||
|
d = vec3(r1, g1, b1);
|
||||||
|
b = clamp(mix(b, d, ds), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 SourceSize = global.OriginalSize;
|
||||||
|
|
||||||
|
float gamma_in = 1.0/COMPAT_TEXTURE(LinearizePass, vec2(0.25,0.25)).a;
|
||||||
|
float intera = COMPAT_TEXTURE(LinearizePass, vec2(0.75,0.25)).a;
|
||||||
|
bool interb = (intera < 0.5);
|
||||||
|
|
||||||
|
// Calculating texel coordinates
|
||||||
|
|
||||||
|
vec2 texcoord = TEX0.xy;
|
||||||
|
|
||||||
|
if (IOS > 0.0 && !interb){
|
||||||
|
vec2 ofactor = OutputSize.xy/SourceSize.xy;
|
||||||
|
vec2 intfactor = (IOS < 2.5) ? floor(ofactor) : ceil(ofactor);
|
||||||
|
vec2 diff = ofactor/intfactor;
|
||||||
|
float scan = diff.y;
|
||||||
|
texcoord = Overscan(texcoord, scan, scan);
|
||||||
|
if (IOS == 1.0 || IOS == 3.0) texcoord = vec2(TEX0.x, texcoord.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
texcoord = Overscan(texcoord, (global.OriginalSize.x - overscanX)/global.OriginalSize.x, (global.OriginalSize.y - overscanY)/global.OriginalSize.y);
|
||||||
|
|
||||||
|
vec2 pos1 = TEX0.xy;
|
||||||
|
vec2 pos = Warp(texcoord);
|
||||||
|
vec2 pos0 = Warp(TEX0.xy);
|
||||||
|
vec3 color0 = COMPAT_TEXTURE(Source,pos1).rgb;
|
||||||
|
float c0 = max(max(color0.r, color0.g),color0.b);
|
||||||
|
|
||||||
|
// color and bloom fetching
|
||||||
|
vec3 color = COMPAT_TEXTURE(Source,pos1).rgb;
|
||||||
|
vec3 Bloom = COMPAT_TEXTURE(BloomPass, pos).rgb;
|
||||||
|
fetch_pixel(color, Bloom, pos1, pos);
|
||||||
|
|
||||||
|
float cm = max(max(color.r,color.g),color.b);
|
||||||
|
float mx1 = COMPAT_TEXTURE(Source, pos1 ).a;
|
||||||
|
float colmx = max(mx1, cm);
|
||||||
|
float w3 = min((c0 + 0.0005) / (pow(colmx, gamma_in/1.4) + 0.0005), 1.0);
|
||||||
|
|
||||||
|
vec2 dx = vec2(0.001, 0.0);
|
||||||
|
float mx0 = COMPAT_TEXTURE(Source, pos1 - dx).a;
|
||||||
|
float mx2 = COMPAT_TEXTURE(Source, pos1 + dx).a;
|
||||||
|
float mx = max(max(mx0,mx1),max(mx2,cm));
|
||||||
|
|
||||||
|
vec3 one = vec3(1.0);
|
||||||
|
|
||||||
|
// Apply Mask
|
||||||
|
|
||||||
|
vec3 orig1 = color;
|
||||||
|
vec3 cmask = one;
|
||||||
|
|
||||||
|
vec2 maskcoord = gl_FragCoord.xy * 1.000001;
|
||||||
|
|
||||||
|
float smask = SlotMask(maskcoord, mx);
|
||||||
|
cmask*= Mask(maskcoord, mx);
|
||||||
|
|
||||||
|
if (mask_layout > 0.5) cmask = cmask.rbg;
|
||||||
|
|
||||||
|
vec3 cmask1 = cmask;
|
||||||
|
float smask1 = smask;
|
||||||
|
|
||||||
|
if (mask_bloom > 0.025)
|
||||||
|
{
|
||||||
|
float maxb = max(max(Bloom.r,Bloom.g),Bloom.b);
|
||||||
|
maxb = pow(sqrt(maxb*mix(maxb, colmx, 0.75)),0.275);
|
||||||
|
vec3 mBloom = 0.5*(1.5*Bloom+0.5*maxb) * mix(1.0, 2.0-colmx, (bloom_dist + 0.5));
|
||||||
|
float maskmx = 1.0; if (shadowMask > 0.5 || shadowMask < 4.5) maskmx = maskLight; else if (shadowMask > 6.5 && shadowMask < 10.5) maskmx = 1.0; else maskmx = max(max(cmask.r,cmask.g),cmask.b);
|
||||||
|
cmask = min(cmask + maxb*mBloom*mask_bloom, maskmx);
|
||||||
|
smask = min(smask + 0.9*maxb*max(max(mBloom.r,mBloom.g),mBloom.b)*mask_bloom, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
color = pow(color, vec3(mask_gamma/gamma_in));
|
||||||
|
color = color*cmask;
|
||||||
|
color = min(color,1.0);
|
||||||
|
color = color*smask;
|
||||||
|
color = pow(color, vec3(gamma_in/mask_gamma));
|
||||||
|
|
||||||
|
cmask = min(cmask*smask, 1.0);
|
||||||
|
cmask1 = min(cmask1*smask1, 1.0);
|
||||||
|
|
||||||
|
float bb = mix(brightboost, brightboost1, colmx);
|
||||||
|
if (interb) bb = (abs(intera-0.5)<0.1) ? pow(0.80*bb, 0.65) : pow(bb, 0.70);
|
||||||
|
color*=bb;
|
||||||
|
|
||||||
|
vec3 Glow = COMPAT_TEXTURE(BloomPass, pos).rgb;
|
||||||
|
vec3 Ref = COMPAT_TEXTURE(LinearizePass, pos).rgb;
|
||||||
|
float maxb = COMPAT_TEXTURE(BloomPass, pos).a;
|
||||||
|
float vig = COMPAT_TEXTURE(PrePass, clamp(pos, 0.0+0.5*global.OriginalSize.zw, 1.0-0.5*global.OriginalSize.zw)).a;
|
||||||
|
|
||||||
|
vec3 Bloom1 = Bloom;
|
||||||
|
|
||||||
|
if (bloom < -0.01) Bloom1 = plant(Bloom, maxb);
|
||||||
|
|
||||||
|
Bloom1 = min(Bloom1*(orig1+color), max(0.5*(colmx + orig1 - color),0.001*Bloom1));
|
||||||
|
Bloom1 = 0.5*(Bloom1 + mix(Bloom1, mix(colmx*orig1, Bloom1, 0.5), 1.0-color));
|
||||||
|
|
||||||
|
Bloom1 = Bloom1 * mix(1.0, 2.0-colmx, bloom_dist);
|
||||||
|
|
||||||
|
color = color + abs(bloom) * Bloom1;
|
||||||
|
|
||||||
|
color = min(color, mix(one, cmask1, mclip));
|
||||||
|
|
||||||
|
if (!interb) color = declip(color, mix(1.0, w3, 0.6)); else w3 = 1.0;
|
||||||
|
|
||||||
|
if (halation > 0.01) {
|
||||||
|
Bloom = mix(0.5*(Bloom + Bloom*Bloom), 0.75*Bloom*Bloom, colmx);
|
||||||
|
color = color + 2.0*max((2.0*mix(maxb*maxb, maxb, colmx)-0.5*max(max(Ref.r,Ref.g),Ref.b)),0.25)*mix(1.0,w3,0.5*colmx)*mix(one,cmask,0.6)*Bloom*halation; }
|
||||||
|
|
||||||
|
Glow = mix(Glow, 0.25*color, 0.7*colmx);
|
||||||
|
if (glow >= 0.0) color = color + 0.5*Glow*glow; else { cmask*=cmask; cmask*=cmask; color = color + (-glow)*cmask*Glow; }
|
||||||
|
|
||||||
|
color = min(color, 1.0);
|
||||||
|
|
||||||
|
color = pow(color, vec3(1.0/gamma_out));
|
||||||
|
|
||||||
|
float rc = 0.6*sqrt(max(max(color.r, color.g), color.b))+0.4;
|
||||||
|
|
||||||
|
if (abs(global.addnoised) > 0.01)
|
||||||
|
{
|
||||||
|
vec3 noise0 = noise(vec3(floor(OutputSize.xy * vTexCoord / global.noiseresd), float(global.FrameCount)));
|
||||||
|
if (global.noisetype < 0.5) color = mix(color, noise0, 0.25*abs(global.addnoised) * rc);
|
||||||
|
else color = min(color * mix(1.0, 1.5*noise0.x, 0.5*abs(global.addnoised)), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor = vec4(color*vig*humbar(mix(pos.y, pos.x, global.bardir))*global.post_br*corner(pos0), 1.0);
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
Interlacing
|
Interlacing
|
||||||
|
|
||||||
Copyright (C) 2020 guest(r) - guest.r@gmail.com
|
Copyright (C) 2020-2021 guest(r) - guest.r@gmail.com
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
vec4 OriginalSize;
|
vec4 OriginalSize;
|
||||||
|
vec4 SourceSize;
|
||||||
vec4 OutputSize;
|
vec4 OutputSize;
|
||||||
uint FrameCount;
|
uint FrameCount;
|
||||||
float GAMMA_INPUT;
|
float GAMMA_INPUT;
|
||||||
|
@ -32,9 +33,8 @@ layout(push_constant) uniform Push
|
||||||
float iscan;
|
float iscan;
|
||||||
float intres;
|
float intres;
|
||||||
float iscans;
|
float iscans;
|
||||||
float downsample_levelx;
|
|
||||||
float downsample_levely;
|
|
||||||
float prescalex;
|
float prescalex;
|
||||||
|
float prescaley;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
} global;
|
} global;
|
||||||
|
|
||||||
|
|
||||||
#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05
|
#pragma parameter GAMMA_INPUT "Gamma Input" 1.80 1.0 5.0 0.05
|
||||||
#define GAMMA_INPUT params.GAMMA_INPUT
|
#define GAMMA_INPUT params.GAMMA_INPUT
|
||||||
|
|
||||||
#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0
|
#pragma parameter bogus_interlacing "[ INTERLACING OPTIONS ]: " 0.0 0.0 0.0 1.0
|
||||||
|
@ -53,7 +53,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter inter " Interlace Trigger Resolution :" 400.0 0.0 800.0 25.0
|
#pragma parameter inter " Interlace Trigger Resolution :" 400.0 0.0 800.0 25.0
|
||||||
#define inter params.inter // interlace resolution
|
#define inter params.inter // interlace resolution
|
||||||
|
|
||||||
#pragma parameter interm " Interlace Mode: OFF, Normal 1-3, Interpolation 4-5" 1.0 0.0 5.0 1.0
|
#pragma parameter interm " Interlace Mode: OFF, Normal 1-3, Interpolation 4" 4.0 0.0 4.0 1.0
|
||||||
#define interm params.interm // interlace mode
|
#define interm params.interm // interlace mode
|
||||||
|
|
||||||
#pragma parameter iscan " Interlacing Scanline Effect" 0.20 0.0 1.0 0.05
|
#pragma parameter iscan " Interlacing Scanline Effect" 0.20 0.0 1.0 0.05
|
||||||
|
@ -62,13 +62,13 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match
|
#pragma parameter intres " Internal Resolution Y: 224p/240p, 1.5...y-dowsample" 0.0 0.0 6.0 0.5 // Joint parameter with main pass, values must match
|
||||||
#define intres params.intres // interlace resolution
|
#define intres params.intres // interlace resolution
|
||||||
|
|
||||||
#pragma parameter downsample_levelx " Downsampling-X (High-res content, pre-scalers)" 0.0 0.0 3.0 0.05
|
#pragma parameter prescalex " Prescale-X Factor (for xBR...pre-shader...)" 1.0 1.0 5.0 0.25 // Joint parameter with main pass, values must match
|
||||||
#define downsample_levelx params.downsample_levelx // downsample level
|
#define prescalex params.prescalex // prescale-x factor
|
||||||
|
|
||||||
#pragma parameter downsample_levely " Downsampling-Y (High-res content, pre-scalers)" 0.0 0.0 3.0 0.05
|
#pragma parameter prescaley " Prescale-Y Factor (for xBR...pre-shader...)" 1.0 1.0 5.0 0.25 // Joint parameter with main pass, values must match
|
||||||
#define downsample_levely params.downsample_levely // downsample level
|
#define prescaley params.prescaley // prescale-y factor
|
||||||
|
|
||||||
#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.40 0.0 1.0 0.05
|
#pragma parameter iscans " Interlacing (Scanline) Saturation" 0.25 0.0 1.0 0.05
|
||||||
#define iscans params.iscans // interlace saturation
|
#define iscans params.iscans // interlace saturation
|
||||||
|
|
||||||
#pragma stage vertex
|
#pragma stage vertex
|
||||||
|
@ -79,13 +79,13 @@ layout(location = 0) out vec2 vTexCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord * 1.000001;
|
vTexCoord = TexCoord * 1.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D PrePass;
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
||||||
|
|
||||||
|
@ -97,38 +97,10 @@ vec3 plant (vec3 tar, float r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 fetch_pixel(vec2 coord)
|
|
||||||
{
|
|
||||||
vec2 dx = vec2(global.SourceSize.z, 0.0) * downsample_levelx;
|
|
||||||
vec2 dy = vec2(0.0, global.SourceSize.w) * downsample_levely;
|
|
||||||
vec2 d1 = dx + dy;
|
|
||||||
vec2 d2 = dx - dy;
|
|
||||||
|
|
||||||
float sum = 15.0;
|
|
||||||
vec3 result = 3.0*COMPAT_TEXTURE(PrePass, coord ).rgb +
|
|
||||||
2.0*COMPAT_TEXTURE(PrePass, coord + dx).rgb +
|
|
||||||
2.0*COMPAT_TEXTURE(PrePass, coord - dx).rgb +
|
|
||||||
2.0*COMPAT_TEXTURE(PrePass, coord + dy).rgb +
|
|
||||||
2.0*COMPAT_TEXTURE(PrePass, coord - dy).rgb +
|
|
||||||
COMPAT_TEXTURE(PrePass, coord + d1).rgb +
|
|
||||||
COMPAT_TEXTURE(PrePass, coord - d1).rgb +
|
|
||||||
COMPAT_TEXTURE(PrePass, coord + d2).rgb +
|
|
||||||
COMPAT_TEXTURE(PrePass, coord - d2).rgb;
|
|
||||||
|
|
||||||
return result/sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 c1 = COMPAT_TEXTURE(PrePass, vTexCoord).rgb;
|
vec3 c1 = COMPAT_TEXTURE(Source, vTexCoord).rgb;
|
||||||
vec3 c2 = COMPAT_TEXTURE(PrePass, vTexCoord + vec2(0.0, params.OriginalSize.w)).rgb;
|
vec3 c2 = COMPAT_TEXTURE(Source, vTexCoord + vec2(0.0, params.SourceSize.w)).rgb;
|
||||||
|
|
||||||
if ((downsample_levelx + downsample_levely) > 0.025)
|
|
||||||
{
|
|
||||||
c1 = fetch_pixel(vTexCoord);
|
|
||||||
c2 = fetch_pixel(vTexCoord + vec2(0.0, params.OriginalSize.w));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 c = c1;
|
vec3 c = c1;
|
||||||
|
|
||||||
|
@ -148,7 +120,7 @@ void main()
|
||||||
|
|
||||||
if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5)
|
if (inter <= params.OriginalSize.y/yres_div && interm > 0.5 && intres != 1.0 && intres != 0.5)
|
||||||
{
|
{
|
||||||
intera = 0.5;
|
intera = 0.25;
|
||||||
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
float line_no = clamp(floor(mod(params.OriginalSize.y*vTexCoord.y, 2.0)), 0.0, 1.0);
|
||||||
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
float frame_no = clamp(floor(mod(float(params.FrameCount),2.0)), 0.0, 1.0);
|
||||||
float ii = abs(line_no-frame_no);
|
float ii = abs(line_no-frame_no);
|
||||||
|
@ -159,10 +131,8 @@ void main()
|
||||||
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
r = clamp(max(m1*ii, (1.0-iscan)*min(m1,m2)), 0.0, 1.0);
|
||||||
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
c = plant( mix(mix(c1,c2, min(mix(m1, 1.0-m2, min(m1,1.0-m1))/(d+0.00001),1.0)), c1, ii), r);
|
||||||
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
if (interm == 3.0) c = (1.0-0.5*iscan)*mix(c2, c1, ii);
|
||||||
intera = 0.0;
|
|
||||||
}
|
}
|
||||||
if (interm == 4.0) c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b));
|
if (interm == 4.0) { c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b)); intera = 0.45; }
|
||||||
if (interm == 5.0) { c = mix(c2, c1, 0.5); c = plant(mix(c, c*c, 0.5*iscans), max(max(c.r,c.g),c.b));}
|
|
||||||
}
|
}
|
||||||
c = pow(c, vec3(gamma_in));
|
c = pow(c, vec3(gamma_in));
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CRT GDV Afterglow, color altering
|
CRT Advanced Afterglow, color altering
|
||||||
|
|
||||||
Copyright (C) 2019-2021 guest(r) and Dr. Venom
|
Copyright (C) 2019-2022 guest(r) and Dr. Venom
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -34,39 +34,58 @@ layout(push_constant) uniform Push
|
||||||
float WP;
|
float WP;
|
||||||
float wp_saturation;
|
float wp_saturation;
|
||||||
float AS, sat;
|
float AS, sat;
|
||||||
|
float BP;
|
||||||
|
float vigstr;
|
||||||
|
float vigdef;
|
||||||
|
float sega_fix;
|
||||||
|
float pre_bb;
|
||||||
|
float contr;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
#pragma parameter AS " Afterglow Strength" 0.07 0.0 0.50 0.01
|
#pragma parameter AS " Afterglow Strength" 0.20 0.0 0.60 0.01
|
||||||
#define AS params.AS
|
#define AS params.AS
|
||||||
|
|
||||||
#pragma parameter sat " Afterglow saturation" 0.10 0.0 1.0 0.01
|
#pragma parameter sat " Afterglow saturation" 0.50 0.0 1.0 0.01
|
||||||
#define sat params.sat
|
#define sat params.sat
|
||||||
|
|
||||||
#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0
|
#pragma parameter bogus_color "[ COLOR TWEAKS ]:" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
#pragma parameter TNTC " LUT Number/Colors (1.0-4.0)" 0.0 0.0 4.0 1.0
|
#pragma parameter CS " Display Gamut: sRGB, Modern, DCI, Adobe, Rec.2020" 0.0 0.0 4.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter CP " CRT Profile: EBU | P22 | SMPTE-C | Philips | Trin." 0.0 -1.0 5.0 1.0
|
||||||
|
|
||||||
|
#define CP params.CP
|
||||||
|
#define CS params.CS
|
||||||
|
|
||||||
|
#pragma parameter TNTC " LUT Colors: Trin.1 | Trin.2 | Nec Mult. | NTSC" 0.0 0.0 4.0 1.0
|
||||||
#define TNTC params.TNTC
|
#define TNTC params.TNTC
|
||||||
|
|
||||||
#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0
|
#pragma parameter LS " LUT Size" 32.0 32.0 64.0 32.0
|
||||||
#define LS params.LS
|
#define LS params.LS
|
||||||
|
|
||||||
#pragma parameter LUTLOW " Fix LUT Dark - Range" 5.0 0.0 50.0 1.0
|
#define LUTLOW 5.0 // "Fix LUT Dark - Range" from 0.0 to 50.0 - RGB singletons
|
||||||
#define LUTLOW params.LUTLOW
|
|
||||||
|
|
||||||
#pragma parameter LUTBR " Fix LUT Brightness" 1.0 0.0 1.0 0.10
|
#define LUTBR 1.0 // "Fix LUT Brightness" from 0.0 to 1.0
|
||||||
#define LUTBR params.LUTBR
|
|
||||||
|
|
||||||
#pragma parameter CP " CRT Color Profile" 0.0 -1.0 5.0 1.0
|
|
||||||
#pragma parameter CS " Color Space: sRGB, DCI, Adobe, Rec.2020" 0.0 0.0 3.0 1.0
|
|
||||||
|
|
||||||
#define CP params.CP
|
|
||||||
#define CS params.CS
|
|
||||||
|
|
||||||
#pragma parameter WP " Color Temperature %" 0.0 -100.0 100.0 5.0
|
#pragma parameter WP " Color Temperature %" 0.0 -100.0 100.0 5.0
|
||||||
|
|
||||||
#pragma parameter wp_saturation " Saturation Adjustment" 1.0 0.0 2.0 0.05
|
#pragma parameter wp_saturation " Saturation Adjustment" 1.0 0.0 2.0 0.05
|
||||||
|
|
||||||
|
#pragma parameter pre_bb " Brightness Adjustment" 1.0 0.0 2.0 0.01
|
||||||
|
|
||||||
|
#pragma parameter contr " Contrast Adjustment" 0.0 -1.0 1.0 0.05
|
||||||
|
|
||||||
|
#pragma parameter sega_fix " Sega Brightness Fix" 0.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter BP " Raise Black Level" 0.0 -100.0 25.0 1.0
|
||||||
|
|
||||||
|
#pragma parameter vigstr " Vignette Strength" 0.0 0.0 2.0 0.05
|
||||||
|
|
||||||
|
#pragma parameter vigdef " Vignette Size" 1.0 0.5 3.0 0.10
|
||||||
|
|
||||||
#define WP params.WP
|
#define WP params.WP
|
||||||
#define wp_saturation params.wp_saturation
|
#define wp_saturation params.wp_saturation
|
||||||
|
#define BP params.BP
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
{
|
{
|
||||||
|
@ -148,11 +167,18 @@ mat3(
|
||||||
-0.498611, 0.041555, 1.056972
|
-0.498611, 0.041555, 1.056972
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const mat3 ToModern =
|
||||||
|
mat3(
|
||||||
|
2.791723, -0.894766, 0.041678,
|
||||||
|
-1.173165, 1.815586, -0.130886,
|
||||||
|
-0.440973, 0.032000, 1.002034
|
||||||
|
);
|
||||||
|
|
||||||
const mat3 ToDCI =
|
const mat3 ToDCI =
|
||||||
mat3(
|
mat3(
|
||||||
2.725394, -0.795168, 0.041242,
|
2.493497, -0.829489, 0.035846,
|
||||||
-1.018003, 1.689732, -0.087639,
|
-0.931384, 1.762664, -0.076172,
|
||||||
-0.440163, 0.022647, 1.100929
|
-0.402711, 0.023625, 0.956885
|
||||||
);
|
);
|
||||||
|
|
||||||
const mat3 ToAdobe =
|
const mat3 ToAdobe =
|
||||||
|
@ -178,9 +204,9 @@ const mat3 D65_to_D55 = mat3 (
|
||||||
|
|
||||||
|
|
||||||
const mat3 D65_to_D93 = mat3 (
|
const mat3 D65_to_D93 = mat3 (
|
||||||
0.3683017655, 0.1899055978, 0.0172641453,
|
0.3412754080, 0.1759701322, 0.0159972847,
|
||||||
0.3555467892, 0.7110935785, 0.1185155964,
|
0.3646170520, 0.7292341040, 0.1215390173,
|
||||||
0.2475020592, 0.0990008237, 1.3035108450);
|
0.2369894093, 0.0947957637, 1.2481442225);
|
||||||
|
|
||||||
|
|
||||||
vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
||||||
|
@ -193,6 +219,29 @@ vec3 fix_lut(vec3 lutcolor, vec3 ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float vignette(vec2 pos) {
|
||||||
|
vec2 b = vec2(params.vigdef, params.vigdef) * vec2(1.0, params.OriginalSize.x/params.OriginalSize.y) * 0.125;
|
||||||
|
pos = clamp(pos, 0.0, 1.0);
|
||||||
|
pos = abs(2.0*(pos - 0.5));
|
||||||
|
vec2 res = mix(0.0.xx, 1.0.xx, smoothstep(1.0.xx, 1.0.xx-b, sqrt(pos)));
|
||||||
|
res = pow(res, 0.70.xx);
|
||||||
|
return max(mix(1.0, sqrt(res.x*res.y), params.vigstr), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 plant (vec3 tar, float r)
|
||||||
|
{
|
||||||
|
float t = max(max(tar.r,tar.g),tar.b) + 0.00001;
|
||||||
|
return tar * r / t;
|
||||||
|
}
|
||||||
|
|
||||||
|
float contrast(float x)
|
||||||
|
{
|
||||||
|
float y = 2.0*x-1.0;
|
||||||
|
y = (sin(y*1.57079632679)+1.0)*0.5;
|
||||||
|
return mix(x, y, params.contr);
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 imgColor = COMPAT_TEXTURE(StockPass, vTexCoord.xy);
|
vec4 imgColor = COMPAT_TEXTURE(StockPass, vTexCoord.xy);
|
||||||
|
@ -202,6 +251,11 @@ void main()
|
||||||
|
|
||||||
float l = length(aftglow.rgb);
|
float l = length(aftglow.rgb);
|
||||||
aftglow.rgb = AS*w*normalize(pow(aftglow.rgb + 0.01, vec3(sat)))*l;
|
aftglow.rgb = AS*w*normalize(pow(aftglow.rgb + 0.01, vec3(sat)))*l;
|
||||||
|
float bp = w * BP/255.0;
|
||||||
|
|
||||||
|
if (params.sega_fix > 0.5) imgColor.rgb = imgColor.rgb * (255.0 / 239.0);
|
||||||
|
|
||||||
|
imgColor.rgb = min(imgColor.rgb, 1.0);
|
||||||
|
|
||||||
vec3 color = imgColor.rgb;
|
vec3 color = imgColor.rgb;
|
||||||
|
|
||||||
|
@ -247,10 +301,6 @@ void main()
|
||||||
res = mix(color1, color2, f);
|
res = mix(color1, color2, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imgColor.r == 0.0) res.r = 0.0;
|
|
||||||
if (imgColor.g == 0.0) res.g = 0.0;
|
|
||||||
if (imgColor.b == 0.0) res.b = 0.0;
|
|
||||||
|
|
||||||
res.rgb = fix_lut (res.rgb, imgColor.rgb);
|
res.rgb = fix_lut (res.rgb, imgColor.rgb);
|
||||||
|
|
||||||
color = mix(imgColor.rgb, res.rgb, min(TNTC,1.0));
|
color = mix(imgColor.rgb, res.rgb, min(TNTC,1.0));
|
||||||
|
@ -261,10 +311,11 @@ void main()
|
||||||
float p;
|
float p;
|
||||||
mat3 m_out;
|
mat3 m_out;
|
||||||
|
|
||||||
if (CS == 0.0) { p = 2.4; m_out = ToSRGB; } else
|
if (CS == 0.0) { p = 2.2; m_out = ToSRGB; } else
|
||||||
if (CS == 1.0) { p = 2.6; m_out = ToDCI; } else
|
if (CS == 1.0) { p = 2.2; m_out = ToModern; } else
|
||||||
if (CS == 2.0) { p = 2.2; m_out = ToAdobe;} else
|
if (CS == 2.0) { p = 2.6; m_out = ToDCI; } else
|
||||||
if (CS == 3.0) { p = 2.4; m_out = ToREC; }
|
if (CS == 3.0) { p = 2.2; m_out = ToAdobe; } else
|
||||||
|
if (CS == 4.0) { p = 2.4; m_out = ToREC; }
|
||||||
|
|
||||||
color = pow(c, vec3(p));
|
color = pow(c, vec3(p));
|
||||||
|
|
||||||
|
@ -286,11 +337,13 @@ void main()
|
||||||
|
|
||||||
if (CP == -1.0) color = c;
|
if (CP == -1.0) color = c;
|
||||||
|
|
||||||
vec3 scolor1 = normalize(pow(color + 0.000000001, vec3(wp_saturation)))*length(color);
|
vec3 scolor1 = plant(pow(color, vec3(wp_saturation)), max(max(color.r,color.g),color.b));
|
||||||
float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
float luma = dot(color, vec3(0.299, 0.587, 0.114));
|
||||||
vec3 scolor2 = mix(vec3(luma), color, wp_saturation);
|
vec3 scolor2 = mix(vec3(luma), color, wp_saturation);
|
||||||
color = (wp_saturation > 1.0) ? scolor1 : scolor2;
|
color = (wp_saturation > 1.0) ? scolor1 : scolor2;
|
||||||
|
|
||||||
|
color = plant(color, contrast(max(max(color.r,color.g),color.b)));
|
||||||
|
|
||||||
p = 2.2;
|
p = 2.2;
|
||||||
|
|
||||||
color = pow(color, vec3(p));
|
color = pow(color, vec3(p));
|
||||||
|
@ -310,7 +363,12 @@ void main()
|
||||||
color = mix(color, comp, m);
|
color = mix(color, comp, m);
|
||||||
color = pow(max(color, 0.0), vec3(1.0/p));
|
color = pow(max(color, 0.0), vec3(1.0/p));
|
||||||
|
|
||||||
color = color + aftglow.rgb;
|
if (BP > -0.5) color = color + aftglow.rgb + bp; else
|
||||||
|
{
|
||||||
FragColor = vec4(color, 1.0);
|
color = max(color + BP/255.0, 0.0) / (1.0 + BP/255.0*step(- BP/255.0, max(max(color.r,color.g),color.b))) + aftglow.rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = min(color * params.pre_bb, 1.0);
|
||||||
|
|
||||||
|
FragColor = vec4(color, vignette(vTexCoord.xy));
|
||||||
}
|
}
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
layout(push_constant) uniform Push
|
||||||
{
|
{
|
||||||
float GAMMA_INPUT;
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.05
|
|
||||||
#define GAMMA_INPUT params.GAMMA_INPUT
|
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 0) uniform UBO
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
{
|
{
|
||||||
mat4 MVP;
|
mat4 MVP;
|
||||||
|
@ -27,13 +27,9 @@ void main()
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D AfterglowPass;
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float gamma_in = 1.0/GAMMA_INPUT;
|
FragColor = vec4(texture(Source, vTexCoord).rgb, 1.0);
|
||||||
FragColor = vec4(pow(vec3(COMPAT_TEXTURE(AfterglowPass, vTexCoord)), vec3(GAMMA_INPUT)), gamma_in);
|
|
||||||
}
|
}
|
|
@ -1 +0,0 @@
|
||||||
LUT's kindly provided by torridgristle.
|
|
Before Width: | Height: | Size: 14 KiB |
|
@ -1,112 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(push_constant) uniform Push
|
|
||||||
{
|
|
||||||
vec4 SourceSize;
|
|
||||||
vec4 OriginalSize;
|
|
||||||
vec4 OutputSize;
|
|
||||||
uint FrameCount;
|
|
||||||
float TNTC;
|
|
||||||
} params;
|
|
||||||
|
|
||||||
#pragma parameter TNTC "LUT Colors" 0.0 0.0 3.0 1.0
|
|
||||||
#define TNTC params.TNTC
|
|
||||||
|
|
||||||
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 SamplerLUT1;
|
|
||||||
layout(set = 0, binding = 4) uniform sampler2D SamplerLUT2;
|
|
||||||
layout(set = 0, binding = 5) uniform sampler2D SamplerLUT3;
|
|
||||||
|
|
||||||
#define LUT_Size 32.0
|
|
||||||
#define COMPAT_TEXTURE(c,d) texture(c,d)
|
|
||||||
|
|
||||||
const mat3 D65_to_XYZ = mat3 (
|
|
||||||
0.4306190, 0.2220379, 0.0201853,
|
|
||||||
0.3415419, 0.7066384, 0.1295504,
|
|
||||||
0.1783091, 0.0713236, 0.9390944);
|
|
||||||
|
|
||||||
const mat3 XYZ_to_D50 = mat3 (
|
|
||||||
2.9603944, -0.9787684, 0.0844874,
|
|
||||||
-1.4678519, 1.9161415, -0.2545973,
|
|
||||||
-0.4685105, 0.0334540, 1.4216174);
|
|
||||||
|
|
||||||
|
|
||||||
// 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 = COMPAT_TEXTURE(Source, vTexCoord.xy);
|
|
||||||
if (int(TNTC) == 0)
|
|
||||||
{
|
|
||||||
FragColor = imgColor;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float red = ( imgColor.r * (LUT_Size - 1.0) + 0.499999 ) / (LUT_Size * LUT_Size);
|
|
||||||
float green = ( imgColor.g * (LUT_Size - 1.0) + 0.499999 ) / LUT_Size;
|
|
||||||
float blue1 = (floor( imgColor.b * (LUT_Size - 1.0) ) / LUT_Size) + red;
|
|
||||||
float blue2 = (ceil( imgColor.b * (LUT_Size - 1.0) ) / LUT_Size) + red;
|
|
||||||
float mixer = clamp(max((imgColor.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0);
|
|
||||||
vec4 color1, color2, res;
|
|
||||||
if (int(TNTC) == 1)
|
|
||||||
{
|
|
||||||
color1 = COMPAT_TEXTURE( SamplerLUT1, vec2( blue1, green ));
|
|
||||||
color2 = COMPAT_TEXTURE( SamplerLUT1, vec2( blue2, green ));
|
|
||||||
res = mixfix(color1, color2, mixer);
|
|
||||||
float mx = max(res.r,max(res.g,res.b));
|
|
||||||
float l = mix(length(imgColor.rgb), length(res.rgb), max(mx-0.5,0.0));
|
|
||||||
res.rgb = mix(imgColor.rgb, res.rgb, clamp(25.0*(mx-0.02),0.0,1.0));
|
|
||||||
res.rgb = normalize(res.rgb+1e-10)*l;
|
|
||||||
vec3 cooler = D65_to_XYZ*res.rgb;
|
|
||||||
cooler = XYZ_to_D50*cooler;
|
|
||||||
res.rgb = mix(res.rgb, cooler, 0.25);
|
|
||||||
}
|
|
||||||
else if (int(TNTC) == 2)
|
|
||||||
{
|
|
||||||
color1 = COMPAT_TEXTURE( SamplerLUT2, vec2( blue1, green ));
|
|
||||||
color2 = COMPAT_TEXTURE( SamplerLUT2, vec2( blue2, green ));
|
|
||||||
res = mixfix(color1, color2, mixer);
|
|
||||||
float l = mix(length(imgColor.rgb), length(res.rgb), 0.4);
|
|
||||||
res.rgb = normalize(res.rgb + 1e-10)*l;
|
|
||||||
}
|
|
||||||
else if (int(TNTC) == 3)
|
|
||||||
{
|
|
||||||
color1 = COMPAT_TEXTURE( SamplerLUT3, vec2( blue1, green ));
|
|
||||||
color2 = COMPAT_TEXTURE( SamplerLUT3, vec2( blue2, green ));
|
|
||||||
res = mixfix(color1, color2, mixer);
|
|
||||||
res.rgb = pow(res.rgb, vec3(1.0/1.20));
|
|
||||||
float mx = max(res.r,max(res.g,res.b));
|
|
||||||
res.rgb = mix(imgColor.rgb, res.rgb, clamp(25.0*(mx-0.05),0.0,1.0));
|
|
||||||
float l = length(imgColor.rgb);
|
|
||||||
res.rgb = normalize(res.rgb + 1e-10)*l;
|
|
||||||
}
|
|
||||||
|
|
||||||
FragColor = vec4(mix(imgColor.rgb, res.rgb, min(TNTC,1.0)),1.0);
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 17 KiB |
|
@ -1,134 +0,0 @@
|
||||||
shaders = 17
|
|
||||||
|
|
||||||
shader0 = ../stock.slang
|
|
||||||
filter_linear0 = false
|
|
||||||
scale_type0 = source
|
|
||||||
scale0 = 1.0
|
|
||||||
|
|
||||||
shader1 = ../stock.slang
|
|
||||||
filter_linear1 = false
|
|
||||||
scale_type1 = source
|
|
||||||
scale1 = 1.0
|
|
||||||
alias1 = StockPass
|
|
||||||
|
|
||||||
shader2 = ../crt/shaders/guest/advanced/afterglow0.slang
|
|
||||||
filter_linear2 = true
|
|
||||||
scale_type2 = source
|
|
||||||
scale2 = 1.0
|
|
||||||
alias2 = AfterglowPass
|
|
||||||
|
|
||||||
shader3 = ../crt/shaders/guest/advanced/pre-shaders-afterglow.slang
|
|
||||||
filter_linear3 = true
|
|
||||||
scale_type3 = source
|
|
||||||
scale3 = 1.0
|
|
||||||
alias3 = PrePass0
|
|
||||||
|
|
||||||
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3;SamplerLUT4"
|
|
||||||
SamplerLUT1 = ../crt/shaders/guest/advanced/lut/trinitron-lut.png
|
|
||||||
SamplerLUT1_linear = true
|
|
||||||
SamplerLUT2 = ../crt/shaders/guest/advanced/lut/inv-trinitron-lut.png
|
|
||||||
SamplerLUT2_linear = true
|
|
||||||
SamplerLUT3 = ../crt/shaders/guest/advanced/lut/nec-lut.png
|
|
||||||
SamplerLUT3_linear = true
|
|
||||||
SamplerLUT4 = ../crt/shaders/guest/advanced/lut/ntsc-lut.png
|
|
||||||
SamplerLUT4_linear = true
|
|
||||||
|
|
||||||
# custom ntsc shaders
|
|
||||||
|
|
||||||
shader4 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass1.slang
|
|
||||||
shader5 = ../ntsc/shaders/ntsc-adaptive/ntsc-pass2.slang
|
|
||||||
|
|
||||||
filter_linear4 = false
|
|
||||||
filter_linear5 = true
|
|
||||||
|
|
||||||
scale_type_x4 = source
|
|
||||||
scale_type_y4 = source
|
|
||||||
scale_x4 = 4.0
|
|
||||||
scale_y4 = 1.0
|
|
||||||
frame_count_mod4 = 2
|
|
||||||
float_framebuffer4 = true
|
|
||||||
|
|
||||||
scale_type5 = source
|
|
||||||
scale_x5 = 0.5
|
|
||||||
scale_y5 = 1.0
|
|
||||||
|
|
||||||
shader6 = ../crt/shaders/guest/advanced/custom-fast-sharpen.slang
|
|
||||||
filter_linear6 = true
|
|
||||||
scale_type6 = source
|
|
||||||
scale_x6 = 1.0
|
|
||||||
scale_y6 = 1.0
|
|
||||||
alias6 = NtscPass
|
|
||||||
|
|
||||||
shader7 = ../crt/shaders/guest/advanced/convert-ntsc.slang
|
|
||||||
filter_linear7 = true
|
|
||||||
scale_type7 = source
|
|
||||||
scale_x7 = 0.5
|
|
||||||
scale_y7 = 1.0
|
|
||||||
|
|
||||||
shader8 = ../stock.slang
|
|
||||||
filter_linear8 = true
|
|
||||||
scale_type8 = source
|
|
||||||
scale_x8 = 1.0
|
|
||||||
scale_y8 = 1.0
|
|
||||||
alias8 = PrePass
|
|
||||||
mipmap_input8 = true
|
|
||||||
|
|
||||||
shader9 = ../crt/shaders/guest/advanced/avg-lum-ntsc.slang
|
|
||||||
filter_linear9 = true
|
|
||||||
scale_type9 = source
|
|
||||||
scale9 = 1.0
|
|
||||||
mipmap_input9 = true
|
|
||||||
alias9 = AvgLumPass
|
|
||||||
|
|
||||||
shader10 = ../crt/shaders/guest/advanced/linearize-ntsc.slang
|
|
||||||
filter_linear10 = true
|
|
||||||
scale_type10 = source
|
|
||||||
scale10 = 1.0
|
|
||||||
alias10 = LinearizePass
|
|
||||||
float_framebuffer10 = true
|
|
||||||
|
|
||||||
shader11 = ../crt/shaders/guest/advanced/gaussian_horizontal.slang
|
|
||||||
filter_linear11 = true
|
|
||||||
scale_type_x11 = absolute
|
|
||||||
scale_x11 = 640.0
|
|
||||||
scale_type_y11 = source
|
|
||||||
scale_y11 = 1.0
|
|
||||||
float_framebuffer11 = true
|
|
||||||
|
|
||||||
shader12 = ../crt/shaders/guest/advanced/gaussian_vertical.slang
|
|
||||||
filter_linear12 = true
|
|
||||||
scale_type_x12 = absolute
|
|
||||||
scale_x12 = 640.0
|
|
||||||
scale_type_y12 = absolute
|
|
||||||
scale_y12 = 480.0
|
|
||||||
float_framebuffer12 = true
|
|
||||||
alias12 = GlowPass
|
|
||||||
|
|
||||||
shader13 = ../crt/shaders/guest/advanced/bloom_horizontal.slang
|
|
||||||
filter_linear13 = true
|
|
||||||
scale_type_x13 = absolute
|
|
||||||
scale_x13 = 640.0
|
|
||||||
scale_type_y13 = absolute
|
|
||||||
scale_y13 = 480.0
|
|
||||||
float_framebuffer13 = true
|
|
||||||
|
|
||||||
shader14 = ../crt/shaders/guest/advanced/bloom_vertical.slang
|
|
||||||
filter_linear14 = true
|
|
||||||
scale_type_x14 = absolute
|
|
||||||
scale_x14 = 640.0
|
|
||||||
scale_type_y14 = absolute
|
|
||||||
scale_y14 = 480.0
|
|
||||||
float_framebuffer14 = true
|
|
||||||
alias14 = BloomPass
|
|
||||||
|
|
||||||
shader15 = ../crt/shaders/guest/advanced/crt-guest-advanced-ntsc.slang
|
|
||||||
filter_linear15 = true
|
|
||||||
scale_type15 = viewport
|
|
||||||
scale_x15 = 1.0
|
|
||||||
scale_y15 = 1.0
|
|
||||||
|
|
||||||
shader16 = ../crt/shaders/guest/advanced/deconvergence.slang
|
|
||||||
filter_linear16 = true
|
|
||||||
scale_type16 = viewport
|
|
||||||
scale_x16 = 1.0
|
|
||||||
scale_y16 = 1.0
|
|