From 92b292175429c88a0c993636575e662f5844855d Mon Sep 17 00:00:00 2001 From: cgwg Date: Sun, 21 Feb 2021 04:47:28 +0100 Subject: bgfx: crt-geom and crt-geom-deluxe enhancements (#7766) Added a "brightness boost" feature for the shadow mask that works by making the brightness ratio between bright and dark mask pixels closer to 1 for the brighter parts of the image. Added clamping to zero so that underscanning produces a black border. Added a "raster bloom" effect to crt-geom-deluxe that makes the image grow slightly when the average brightness of the screen is high, mimicking a common defect in CRTs. --- artwork/bgfx/chains/crt-geom/add_alpha.py | 33 +++ artwork/bgfx/chains/crt-geom/aperture_1_2_bgr.png | Bin 153 -> 74 bytes artwork/bgfx/chains/crt-geom/aperture_1_4_rgb.png | Bin 152 -> 78 bytes artwork/bgfx/chains/crt-geom/aperture_2_4_rgb.png | Bin 159 -> 78 bytes artwork/bgfx/chains/crt-geom/aperture_2_5_bgr.png | Bin 156 -> 82 bytes artwork/bgfx/chains/crt-geom/aperture_3_6_rgb.png | Bin 159 -> 82 bytes artwork/bgfx/chains/crt-geom/delta_1_2x1_bgr.png | Bin 159 -> 83 bytes artwork/bgfx/chains/crt-geom/delta_1_4x1_rgb.png | Bin 156 -> 87 bytes artwork/bgfx/chains/crt-geom/delta_2_4x1_rgb.png | Bin 164 -> 86 bytes artwork/bgfx/chains/crt-geom/delta_2_4x2_rgb.png | Bin 168 -> 91 bytes artwork/bgfx/chains/crt-geom/none.png | Bin 150 -> 70 bytes artwork/bgfx/chains/crt-geom/slot_2_4x4_rgb.png | Bin 171 -> 99 bytes artwork/bgfx/chains/crt-geom/slot_2_5x4_bgr.png | Bin 176 -> 107 bytes artwork/bgfx/chains/crt-geom/slot_3_7x6_rgb.png | Bin 180 -> 109 bytes bgfx/chains/crt-geom-deluxe.json | 293 ++++++++++++--------- bgfx/chains/crt-geom.json | 121 +++++---- bgfx/effects/crt-geom/crt-geom-deluxe.json | 62 +++-- bgfx/effects/crt-geom/crt-geom.json | 55 ++-- bgfx/effects/crt-geom/gaussx.json | 30 +-- bgfx/effects/crt-geom/gaussy.json | 30 +-- bgfx/effects/crt-geom/mipmap8.json | 29 ++ bgfx/effects/crt-geom/phosphor_apply.json | 30 +-- bgfx/effects/crt-geom/phosphor_update.json | 30 +-- .../glsl/chains/crt-geom/fs_crt-geom-deluxe.bin | Bin 7142 -> 10255 bytes bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.bin | Bin 6832 -> 9221 bytes bgfx/shaders/glsl/chains/crt-geom/fs_mipmap8.bin | Bin 0 -> 19483 bytes bgfx/shaders/glsl/chains/crt-geom/vs_mipmap8.bin | Bin 0 -> 308 bytes .../shaders/chains/crt-geom/fs_crt-geom-deluxe.sc | 74 ++++-- .../bgfx/shaders/chains/crt-geom/fs_crt-geom.sc | 48 ++-- .../bgfx/shaders/chains/crt-geom/fs_mipmap8.sc | 148 +++++++++++ .../bgfx/shaders/chains/crt-geom/vs_mipmap8.sc | 11 + 31 files changed, 663 insertions(+), 331 deletions(-) create mode 100644 artwork/bgfx/chains/crt-geom/add_alpha.py create mode 100644 bgfx/effects/crt-geom/mipmap8.json create mode 100644 bgfx/shaders/glsl/chains/crt-geom/fs_mipmap8.bin create mode 100644 bgfx/shaders/glsl/chains/crt-geom/vs_mipmap8.bin create mode 100644 src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc create mode 100644 src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc diff --git a/artwork/bgfx/chains/crt-geom/add_alpha.py b/artwork/bgfx/chains/crt-geom/add_alpha.py new file mode 100644 index 00000000000..69fff62f3a6 --- /dev/null +++ b/artwork/bgfx/chains/crt-geom/add_alpha.py @@ -0,0 +1,33 @@ +""" +Assumes the input RGB image subpixels are all either 0 or 255. +Counts the bright subpixels in the whole image. This should be divisible by 3. +Creates a uniform alpha channel containing 255 minus 1/3 of +the number of bright subpixels. +Writes the RGBA image to the output file. +""" +import sys +import numpy +import PIL +import PIL.Image + +if len(sys.argv) != 3: + print("usage: add_alpha.py in.png out.png") + sys.exit(1) + +img = PIL.Image.open(sys.argv[1]) + +arr = numpy.asarray(img) +count = (arr==255).sum() +assert count%3 == 0 +count //= 3 + +alpha = arr[:,:,0,None]*0 + (255-count) + +arr = numpy.concatenate((arr,alpha),axis=2) + +# DEBUG +#print(arr) + +out = PIL.Image.fromarray(arr) +out.save(sys.argv[2]) + diff --git a/artwork/bgfx/chains/crt-geom/aperture_1_2_bgr.png b/artwork/bgfx/chains/crt-geom/aperture_1_2_bgr.png index 26c49ba1c81..55e9c59e189 100644 Binary files a/artwork/bgfx/chains/crt-geom/aperture_1_2_bgr.png and b/artwork/bgfx/chains/crt-geom/aperture_1_2_bgr.png differ diff --git a/artwork/bgfx/chains/crt-geom/aperture_1_4_rgb.png b/artwork/bgfx/chains/crt-geom/aperture_1_4_rgb.png index 1667e2abfac..0a7a5a71ccf 100644 Binary files a/artwork/bgfx/chains/crt-geom/aperture_1_4_rgb.png and b/artwork/bgfx/chains/crt-geom/aperture_1_4_rgb.png differ diff --git a/artwork/bgfx/chains/crt-geom/aperture_2_4_rgb.png b/artwork/bgfx/chains/crt-geom/aperture_2_4_rgb.png index a4fce0e92ec..1d2688b1d56 100644 Binary files a/artwork/bgfx/chains/crt-geom/aperture_2_4_rgb.png and b/artwork/bgfx/chains/crt-geom/aperture_2_4_rgb.png differ diff --git a/artwork/bgfx/chains/crt-geom/aperture_2_5_bgr.png b/artwork/bgfx/chains/crt-geom/aperture_2_5_bgr.png index 0efddb5bcee..76958863152 100644 Binary files a/artwork/bgfx/chains/crt-geom/aperture_2_5_bgr.png and b/artwork/bgfx/chains/crt-geom/aperture_2_5_bgr.png differ diff --git a/artwork/bgfx/chains/crt-geom/aperture_3_6_rgb.png b/artwork/bgfx/chains/crt-geom/aperture_3_6_rgb.png index 8ebbb448786..422db658ca6 100644 Binary files a/artwork/bgfx/chains/crt-geom/aperture_3_6_rgb.png and b/artwork/bgfx/chains/crt-geom/aperture_3_6_rgb.png differ diff --git a/artwork/bgfx/chains/crt-geom/delta_1_2x1_bgr.png b/artwork/bgfx/chains/crt-geom/delta_1_2x1_bgr.png index 497ca426474..cead16fd19e 100644 Binary files a/artwork/bgfx/chains/crt-geom/delta_1_2x1_bgr.png and b/artwork/bgfx/chains/crt-geom/delta_1_2x1_bgr.png differ diff --git a/artwork/bgfx/chains/crt-geom/delta_1_4x1_rgb.png b/artwork/bgfx/chains/crt-geom/delta_1_4x1_rgb.png index 21144c3b183..0b4f7dc2082 100644 Binary files a/artwork/bgfx/chains/crt-geom/delta_1_4x1_rgb.png and b/artwork/bgfx/chains/crt-geom/delta_1_4x1_rgb.png differ diff --git a/artwork/bgfx/chains/crt-geom/delta_2_4x1_rgb.png b/artwork/bgfx/chains/crt-geom/delta_2_4x1_rgb.png index 4a652631940..1d9a174400c 100644 Binary files a/artwork/bgfx/chains/crt-geom/delta_2_4x1_rgb.png and b/artwork/bgfx/chains/crt-geom/delta_2_4x1_rgb.png differ diff --git a/artwork/bgfx/chains/crt-geom/delta_2_4x2_rgb.png b/artwork/bgfx/chains/crt-geom/delta_2_4x2_rgb.png index 9cba74f077d..1fa7de380fb 100644 Binary files a/artwork/bgfx/chains/crt-geom/delta_2_4x2_rgb.png and b/artwork/bgfx/chains/crt-geom/delta_2_4x2_rgb.png differ diff --git a/artwork/bgfx/chains/crt-geom/none.png b/artwork/bgfx/chains/crt-geom/none.png index 31419a54ac9..dd4c34390ea 100644 Binary files a/artwork/bgfx/chains/crt-geom/none.png and b/artwork/bgfx/chains/crt-geom/none.png differ diff --git a/artwork/bgfx/chains/crt-geom/slot_2_4x4_rgb.png b/artwork/bgfx/chains/crt-geom/slot_2_4x4_rgb.png index 695957eab7d..d16ea109d8b 100644 Binary files a/artwork/bgfx/chains/crt-geom/slot_2_4x4_rgb.png and b/artwork/bgfx/chains/crt-geom/slot_2_4x4_rgb.png differ diff --git a/artwork/bgfx/chains/crt-geom/slot_2_5x4_bgr.png b/artwork/bgfx/chains/crt-geom/slot_2_5x4_bgr.png index 58d1651bc38..86771a210f9 100644 Binary files a/artwork/bgfx/chains/crt-geom/slot_2_5x4_bgr.png and b/artwork/bgfx/chains/crt-geom/slot_2_5x4_bgr.png differ diff --git a/artwork/bgfx/chains/crt-geom/slot_3_7x6_rgb.png b/artwork/bgfx/chains/crt-geom/slot_3_7x6_rgb.png index 86f72a7297a..db8c5f241e6 100644 Binary files a/artwork/bgfx/chains/crt-geom/slot_3_7x6_rgb.png and b/artwork/bgfx/chains/crt-geom/slot_3_7x6_rgb.png differ diff --git a/bgfx/chains/crt-geom-deluxe.json b/bgfx/chains/crt-geom-deluxe.json index d71df646d7b..0eabc4ac399 100644 --- a/bgfx/chains/crt-geom-deluxe.json +++ b/bgfx/chains/crt-geom-deluxe.json @@ -11,6 +11,15 @@ "step" : 0.05, "format": "%1.2f", "screen": "raster" }, + { "type": "float", + "name": "aperture_brightboost", + "text": "Shadow mask brightness boost", + "default": 0.4, + "max" : 1.0, + "min" : 0.0, + "step" : 0.05, + "format": "%1.2f", + "screen": "raster" }, { "type": "float", "name": "phosphor_power", "text": "Phosphor decay power", @@ -29,6 +38,24 @@ "step" : 0.01, "format": "%1.2f", "screen": "raster" }, + { "type": "float", + "name": "rasterbloom_smooth", + "text": "Raster bloom temporal smoothing", + "default": 0.5, + "max" : 0.99, + "min" : 0.0, + "step" : 0.01, + "format": "%1.2f", + "screen": "raster" }, + { "type": "float", + "name": "rasterbloom", + "text": "Raster bloom amplitude", + "default": 0.01, + "max" : 0.1, + "min" : 0.0, + "step" : 0.001, + "format": "%1.3f", + "screen": "raster" }, { "type": "float", "name": "halation", "text": "Halation amplitude", @@ -74,15 +101,15 @@ "step" : 0.1, "format": "%1.1f", "screen": "raster" }, - { "type": "vec2", - "name": "angle", - "text": "Tilt ", - "default": [ 0.0, 0.0 ], - "max" : [ 1.0, 1.0 ], - "min" : [-1.0,-1.0 ], - "step" : 0.01, - "format": "%1.2f", - "screen": "raster" }, + { "type": "vec2", + "name": "angle", + "text": "Tilt ", + "default": [ 0.0, 0.0 ], + "max" : [ 1.0, 1.0 ], + "min" : [-1.0,-1.0 ], + "step" : 0.01, + "format": "%1.2f", + "screen": "raster" }, { "type": "float", "name": "cornersize", "text": "Rounded corner size", @@ -101,15 +128,15 @@ "step" : 100, "format": "%1.0f", "screen": "raster" }, - { "type": "vec2", - "name": "overscan", - "text": "Overscan ", - "default": [ 1.0, 1.0 ], - "max" : [ 1.2, 1.2 ], - "min" : [ 0.8, 0.8 ], - "step" : 0.02, - "format": "%1.2f", - "screen": "raster" }, + { "type": "vec2", + "name": "overscan", + "text": "Overscan ", + "default": [ 1.0, 1.0 ], + "max" : [ 1.2, 1.2 ], + "min" : [ 0.8, 0.8 ], + "step" : 0.02, + "format": "%1.2f", + "screen": "raster" }, { "type": "float", "name": "CRTgamma", "text": "Gamma of simulated CRT", @@ -128,112 +155,128 @@ "step" : 0.05, "format": "%1.2f", "screen": "raster" }, - { "type": "vec2", - "name": "aspect", - "text": "Aspect ratio ", - "default": [ 1.0, 0.75 ], - "max" : [ 1.0, 1.0 ], - "min" : [ 0.3, 0.3 ], - "step" : 0.01, - "format": "%1.2f", - "screen": "raster" } + { "type": "vec2", + "name": "aspect", + "text": "Aspect ratio ", + "default": [ 1.0, 0.75 ], + "max" : [ 1.0, 1.0 ], + "min" : [ 0.3, 0.3 ], + "step" : 0.01, + "format": "%1.2f", + "screen": "raster" } + ], + "targets": [ + { "name": "internal1", + "mode": "guest" + }, + { "name": "internal2", + "mode": "guest" + }, + { "name": "mipmap", + "mode": "guest" + }, + { "name": "blur", + "mode": "guest" + }, + { "name": "phosphor", + "mode": "guest" + } ], - "targets": [ - { "name": "internal1", - "mode": "guest" - }, - { "name": "internal2", - "mode": "guest" - }, - { "name": "blur", - "mode": "guest" - }, - { "name": "phosphor", - "mode": "guest" - } - - ], - "passes": [ - { - "effect": "crt-geom/phosphor_apply", - "applytint": true, - "name": "phosphor apply", - "uniforms": [ - { "uniform": "u_phosphor_power", "slider": "phosphor_power" }, - { "uniform": "u_phosphor_amplitude","slider": "phosphor_amplitude" }, - { "uniform": "u_gamma", "slider": "CRTgamma" } - ], - "input": [ - { "sampler": "s_screen", "target": "screen" }, - { "sampler": "s_phosphor", "target": "phosphor" } - ], - "output": "internal1" - }, - { - "effect": "crt-geom/phosphor_update", - "name": "phosphor update", - "uniforms": [ - { "uniform": "u_phosphor_power", "slider": "phosphor_power" }, - { "uniform": "u_phosphor_amplitude","slider": "phosphor_amplitude" }, - { "uniform": "u_gamma", "slider": "CRTgamma" } - ], - "input": [ - { "sampler": "s_screen", "target": "screen" }, - { "sampler": "s_phosphor", "target": "phosphor" } - ], - "output": "phosphor" - }, - { - "effect": "crt-geom/gaussx", - "name": "Gaussian blur x", - "uniforms": [ - { "uniform": "u_width", "slider": "blurwidth" }, - { "uniform": "u_aspect","slider": "aspect" }, - { "uniform": "u_gamma", "slider": "CRTgamma" } - ], - "input": [ - { "sampler": "s_tex", "target": "internal1" } - ], - "output": "internal2" - }, - { - "effect": "crt-geom/gaussy", - "name": "Gaussian blur y", - "uniforms": [ - { "uniform": "u_width", "slider": "blurwidth" }, - { "uniform": "u_aspect","slider": "aspect" }, - { "uniform": "u_gamma", "slider": "CRTgamma" } - ], - "input": [ - { "sampler": "s_tex", "target": "internal2" } - ], - "output": "blur" - }, - { - "effect": "crt-geom/crt-geom-deluxe", - "name": "CRT", - "uniforms": [ - { "uniform": "curvature", "slider": "curvature" }, - { "uniform": "R", "slider": "R" }, - { "uniform": "d", "slider": "d" }, - { "uniform": "angle", "slider": "angle" }, - { "uniform": "cornersize", "slider": "cornersize" }, - { "uniform": "cornersmooth","slider": "cornersmooth" }, - { "uniform": "overscan", "slider": "overscan" }, - { "uniform": "aspect", "slider": "aspect" }, - { "uniform": "CRTgamma", "slider": "CRTgamma" }, - { "uniform": "monitorgamma","slider": "monitorgamma" }, - { "uniform": "aperture_strength","slider": "aperture_strength" }, - { "uniform": "halation", "slider": "halation" } - ], - - "input": [ - { "sampler": "mpass_texture", "target": "internal1" }, - { "sampler": "mask_texture", "texture": "bgfx/chains/crt-geom/aperture_1_2_bgr.png", "selection": "Shadow mask" }, - { "sampler": "blur_texture", "target": "blur" } - ], - - "output": "output" - } - ] + "passes": [ + { + "effect": "crt-geom/phosphor_apply", + "applytint": true, + "name": "phosphor apply", + "uniforms": [ + { "uniform": "u_phosphor_power", "slider": "phosphor_power" }, + { "uniform": "u_phosphor_amplitude","slider": "phosphor_amplitude" }, + { "uniform": "u_gamma", "slider": "CRTgamma" } + ], + "input": [ + { "sampler": "s_screen", "target": "screen" }, + { "sampler": "s_phosphor", "target": "phosphor" } + ], + "output": "internal1" + }, + { + "effect": "crt-geom/mipmap8", + "name": "mipmap", + "uniforms": [ + { "uniform": "u_smooth", "slider": "rasterbloom_smooth" } + ], + "input": [ + { "sampler": "s_screen", "target": "internal1" }, + { "sampler": "s_mipmap", "target": "mipmap" } + ], + "output": "mipmap" + }, + { + "effect": "crt-geom/phosphor_update", + "name": "phosphor update", + "uniforms": [ + { "uniform": "u_phosphor_power", "slider": "phosphor_power" }, + { "uniform": "u_phosphor_amplitude","slider": "phosphor_amplitude" }, + { "uniform": "u_gamma", "slider": "CRTgamma" } + ], + "input": [ + { "sampler": "s_screen", "target": "screen" }, + { "sampler": "s_phosphor", "target": "phosphor" } + ], + "output": "phosphor" + }, + { + "effect": "crt-geom/gaussx", + "name": "Gaussian blur x", + "uniforms": [ + { "uniform": "u_width", "slider": "blurwidth" }, + { "uniform": "u_aspect","slider": "aspect" }, + { "uniform": "u_gamma", "slider": "CRTgamma" } + ], + "input": [ + { "sampler": "s_tex", "target": "internal1" } + ], + "output": "internal2" + }, + { + "effect": "crt-geom/gaussy", + "name": "Gaussian blur y", + "uniforms": [ + { "uniform": "u_width", "slider": "blurwidth" }, + { "uniform": "u_aspect","slider": "aspect" }, + { "uniform": "u_gamma", "slider": "CRTgamma" } + ], + "input": [ + { "sampler": "s_tex", "target": "internal2" } + ], + "output": "blur" + }, + { + "effect": "crt-geom/crt-geom-deluxe", + "name": "CRT", + "uniforms": [ + { "uniform": "curvature", "slider": "curvature" }, + { "uniform": "R", "slider": "R" }, + { "uniform": "d", "slider": "d" }, + { "uniform": "angle", "slider": "angle" }, + { "uniform": "cornersize", "slider": "cornersize" }, + { "uniform": "cornersmooth","slider": "cornersmooth" }, + { "uniform": "overscan", "slider": "overscan" }, + { "uniform": "aspect", "slider": "aspect" }, + { "uniform": "CRTgamma", "slider": "CRTgamma" }, + { "uniform": "monitorgamma","slider": "monitorgamma" }, + { "uniform": "aperture_strength","slider": "aperture_strength" }, + { "uniform": "aperture_brightboost","slider": "aperture_brightboost" }, + { "uniform": "halation", "slider": "halation" }, + { "uniform": "blurwidth", "slider": "blurwidth" }, + { "uniform": "rasterbloom", "slider": "rasterbloom" } + ], + "input": [ + { "sampler": "mpass_texture", "target": "internal1" }, + { "sampler": "mask_texture", "texture": "bgfx/chains/crt-geom/aperture_1_2_bgr.png", "selection": "Shadow mask" }, + { "sampler": "blur_texture", "target": "blur" }, + { "sampler": "mipmap_texture", "target": "mipmap" } + ], + "output": "output" + } + ] } diff --git a/bgfx/chains/crt-geom.json b/bgfx/chains/crt-geom.json index 56e2210cbdb..c8d852e1b9a 100644 --- a/bgfx/chains/crt-geom.json +++ b/bgfx/chains/crt-geom.json @@ -11,6 +11,15 @@ "step" : 0.05, "format": "%1.2f", "screen": "raster" }, + { "type": "float", + "name": "aperture_brightboost", + "text": "Shadow mask brightness boost", + "default": 0.4, + "max" : 1.0, + "min" : 0.0, + "step" : 0.05, + "format": "%1.2f", + "screen": "raster" }, { "type": "float", "name": "curvature", "text": "Enable curvature", @@ -38,15 +47,15 @@ "step" : 0.1, "format": "%1.1f", "screen": "raster" }, - { "type": "vec2", - "name": "angle", - "text": "Tilt ", - "default": [ 0.0, 0.0 ], - "max" : [ 1.0, 1.0 ], - "min" : [-1.0,-1.0 ], - "step" : 0.01, - "format": "%1.2f", - "screen": "raster" }, + { "type": "vec2", + "name": "angle", + "text": "Tilt ", + "default": [ 0.0, 0.0 ], + "max" : [ 1.0, 1.0 ], + "min" : [-1.0,-1.0 ], + "step" : 0.01, + "format": "%1.2f", + "screen": "raster" }, { "type": "float", "name": "cornersize", "text": "Rounded corner size", @@ -65,15 +74,15 @@ "step" : 100, "format": "%1.0f", "screen": "raster" }, - { "type": "vec2", - "name": "overscan", - "text": "Overscan ", - "default": [ 1.0, 1.0 ], - "max" : [ 1.2, 1.2 ], - "min" : [ 0.8, 0.8 ], - "step" : 0.02, - "format": "%1.2f", - "screen": "raster" }, + { "type": "vec2", + "name": "overscan", + "text": "Overscan ", + "default": [ 1.0, 1.0 ], + "max" : [ 1.2, 1.2 ], + "min" : [ 0.8, 0.8 ], + "step" : 0.02, + "format": "%1.2f", + "screen": "raster" }, { "type": "float", "name": "CRTgamma", "text": "Gamma of simulated CRT", @@ -92,44 +101,42 @@ "step" : 0.05, "format": "%1.2f", "screen": "raster" }, - { "type": "vec2", - "name": "aspect", - "text": "Aspect ratio ", - "default": [ 1.0, 0.75 ], - "max" : [ 1.0, 1.0 ], - "min" : [ 0.3, 0.3 ], - "step" : 0.01, - "format": "%1.2f", - "screen": "raster" } + { "type": "vec2", + "name": "aspect", + "text": "Aspect ratio ", + "default": [ 1.0, 0.75 ], + "max" : [ 1.0, 1.0 ], + "min" : [ 0.3, 0.3 ], + "step" : 0.01, + "format": "%1.2f", + "screen": "raster" } + ], + "targets": [ ], - "targets": [ - - ], - "passes": [ - { - "effect": "crt-geom/crt-geom", - "applytint": true, - "name": "CRT", - "uniforms": [ - { "uniform": "curvature", "slider": "curvature" }, - { "uniform": "R", "slider": "R" }, - { "uniform": "d", "slider": "d" }, - { "uniform": "angle", "slider": "angle" }, - { "uniform": "cornersize", "slider": "cornersize" }, - { "uniform": "cornersmooth","slider": "cornersmooth" }, - { "uniform": "overscan", "slider": "overscan" }, - { "uniform": "aspect", "slider": "aspect" }, - { "uniform": "CRTgamma", "slider": "CRTgamma" }, - { "uniform": "monitorgamma","slider": "monitorgamma" }, - { "uniform": "aperture_strength", "slider": "aperture_strength" } - ], - - "input": [ - { "sampler": "mpass_texture", "target": "screen" }, - { "sampler": "mask_texture", "texture": "bgfx/chains/crt-geom/aperture_1_2_bgr.png", "selection": "Shadow mask" } - ], - - "output": "output" - } - ] + "passes": [ + { + "effect": "crt-geom/crt-geom", + "applytint": true, + "name": "CRT", + "uniforms": [ + { "uniform": "curvature", "slider": "curvature" }, + { "uniform": "R", "slider": "R" }, + { "uniform": "d", "slider": "d" }, + { "uniform": "angle", "slider": "angle" }, + { "uniform": "cornersize", "slider": "cornersize" }, + { "uniform": "cornersmooth","slider": "cornersmooth" }, + { "uniform": "overscan", "slider": "overscan" }, + { "uniform": "aspect", "slider": "aspect" }, + { "uniform": "CRTgamma", "slider": "CRTgamma" }, + { "uniform": "monitorgamma","slider": "monitorgamma" }, + { "uniform": "aperture_strength", "slider": "aperture_strength" }, + { "uniform": "aperture_brightboost","slider": "aperture_brightboost" } + ], + "input": [ + { "sampler": "mpass_texture", "target": "screen" }, + { "sampler": "mask_texture", "texture": "bgfx/chains/crt-geom/aperture_1_2_bgr.png", "selection": "Shadow mask" } + ], + "output": "output" + } + ] } diff --git a/bgfx/effects/crt-geom/crt-geom-deluxe.json b/bgfx/effects/crt-geom/crt-geom-deluxe.json index f3168d5ff1d..c561db7a9c5 100644 --- a/bgfx/effects/crt-geom/crt-geom-deluxe.json +++ b/bgfx/effects/crt-geom/crt-geom-deluxe.json @@ -1,43 +1,47 @@ { "blend": { - "equation": "add", - "srcColor": "1", - "dstColor": "0", - "srcAlpha": "1", - "dstAlpha": "0" + "equation": "add", + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" }, "depth": { - "function": "always", - "writeenable": false + "function": "always", + "writeenable": false }, "cull": { - "mode": "none" + "mode": "none" }, "write": { - "rgb": true, - "alpha": true + "rgb": true, + "alpha": true }, "vertex": "chains/crt-geom/vs_crt-geom", "fragment": "chains/crt-geom/fs_crt-geom-deluxe", "uniforms": [ - { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "u_tex_size1", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "u_quad_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "u_rotation_type", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, - { "name": "mpass_texture", "type": "int", "values": [ 0 ] }, - { "name": "mask_texture", "type": "int", "values": [ 1 ] }, - { "name": "blur_texture", "type": "int", "values": [ 1 ] }, - { "name": "curvature", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, - { "name": "CRTgamma", "type": "vec4", "values": [ 2.4, 0.0, 0.0, 0.0 ] }, - { "name": "monitorgamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] }, - { "name": "overscan", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "aspect", "type": "vec4", "values": [ 1.0, 0.75,0.0, 0.0 ] }, - { "name": "d", "type": "vec4", "values": [ 2.0, 0.0, 0.0, 0.0 ] }, - { "name": "R", "type": "vec4", "values": [ 3.5, 0.0, 0.0, 0.0 ] }, - { "name": "angle", "type": "vec4", "values": [ 0.0,-0.05,0.0, 0.0 ] }, - { "name": "cornersize", "type": "vec4", "values": [ 0.01,0.0, 0.0, 0.0 ] }, - { "name": "cornersmooth", "type": "vec4", "values": [ 1000.0,0.0,0.0,0.0 ] }, - { "name": "aperture_strength", "type": "vec4", "values": [ 0.25,0.0,0.0,0.0 ] }, - { "name": "halation", "type": "vec4", "values": [ 0.1,0.0,0.0,0.0 ] } + { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_tex_size1", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_quad_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_rotation_type", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, + { "name": "mpass_texture", "type": "int", "values": [ 0 ] }, + { "name": "mask_texture", "type": "int", "values": [ 1 ] }, + { "name": "blur_texture", "type": "int", "values": [ 2 ] }, + { "name": "mipmap_texture", "type": "int", "values": [ 3 ] }, + { "name": "curvature", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, + { "name": "CRTgamma", "type": "vec4", "values": [ 2.4, 0.0, 0.0, 0.0 ] }, + { "name": "monitorgamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] }, + { "name": "overscan", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "aspect", "type": "vec4", "values": [ 1.0, 0.75,0.0, 0.0 ] }, + { "name": "d", "type": "vec4", "values": [ 2.0, 0.0, 0.0, 0.0 ] }, + { "name": "R", "type": "vec4", "values": [ 3.5, 0.0, 0.0, 0.0 ] }, + { "name": "angle", "type": "vec4", "values": [ 0.0,-0.05,0.0, 0.0 ] }, + { "name": "cornersize", "type": "vec4", "values": [ 0.01,0.0, 0.0, 0.0 ] }, + { "name": "cornersmooth", "type": "vec4", "values": [ 1000.0,0.0,0.0,0.0 ] }, + { "name": "aperture_strength", "type": "vec4", "values": [ 0.25,0.0,0.0,0.0 ] }, + { "name": "aperture_brightboost","type": "vec4", "values": [ 0.25,0.0,0.0,0.0 ] }, + { "name": "halation", "type": "vec4", "values": [ 0.1,0.0,0.0,0.0 ] }, + { "name": "blurwidth", "type": "vec4", "values": [ 2.0,0.0,0.0,0.0 ] }, + { "name": "rasterbloom","type": "vec4", "values": [ 0.01,0.0,0.0,0.0 ] } ] } diff --git a/bgfx/effects/crt-geom/crt-geom.json b/bgfx/effects/crt-geom/crt-geom.json index fe8e184a4ec..12624942fe7 100644 --- a/bgfx/effects/crt-geom/crt-geom.json +++ b/bgfx/effects/crt-geom/crt-geom.json @@ -1,41 +1,42 @@ { "blend": { - "equation": "add", - "srcColor": "1", - "dstColor": "0", - "srcAlpha": "1", - "dstAlpha": "0" + "equation": "add", + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" }, "depth": { - "function": "always", - "writeenable": false + "function": "always", + "writeenable": false }, "cull": { - "mode": "none" + "mode": "none" }, "write": { - "rgb": true, - "alpha": true + "rgb": true, + "alpha": true }, "vertex": "chains/crt-geom/vs_crt-geom", "fragment": "chains/crt-geom/fs_crt-geom", "uniforms": [ - { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "u_tex_size1", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "u_quad_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "u_rotation_type", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, - { "name": "mpass_texture", "type": "int", "values": [ 0 ] }, - { "name": "mask_texture", "type": "int", "values": [ 1 ] }, - { "name": "curvature", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, - { "name": "CRTgamma", "type": "vec4", "values": [ 2.4, 0.0, 0.0, 0.0 ] }, - { "name": "monitorgamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] }, - { "name": "overscan", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "aspect", "type": "vec4", "values": [ 1.0, 0.75,0.0, 0.0 ] }, - { "name": "d", "type": "vec4", "values": [ 2.0, 0.0, 0.0, 0.0 ] }, - { "name": "R", "type": "vec4", "values": [ 3.5, 0.0, 0.0, 0.0 ] }, - { "name": "angle", "type": "vec4", "values": [ 0.0,-0.05,0.0, 0.0 ] }, - { "name": "cornersize", "type": "vec4", "values": [ 0.01,0.0, 0.0, 0.0 ] }, - { "name": "cornersmooth", "type": "vec4", "values": [ 1000.0,0.0,0.0,0.0 ] }, - { "name": "aperture_strength", "type": "vec4", "values": [ 0.25,0.0,0.0,0.0 ] } + { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_tex_size1", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_quad_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_rotation_type", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, + { "name": "mpass_texture", "type": "int", "values": [ 0 ] }, + { "name": "mask_texture", "type": "int", "values": [ 1 ] }, + { "name": "curvature", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, + { "name": "CRTgamma", "type": "vec4", "values": [ 2.4, 0.0, 0.0, 0.0 ] }, + { "name": "monitorgamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] }, + { "name": "overscan", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "aspect", "type": "vec4", "values": [ 1.0, 0.75,0.0, 0.0 ] }, + { "name": "d", "type": "vec4", "values": [ 2.0, 0.0, 0.0, 0.0 ] }, + { "name": "R", "type": "vec4", "values": [ 3.5, 0.0, 0.0, 0.0 ] }, + { "name": "angle", "type": "vec4", "values": [ 0.0,-0.05,0.0, 0.0 ] }, + { "name": "cornersize", "type": "vec4", "values": [ 0.01,0.0, 0.0, 0.0 ] }, + { "name": "cornersmooth", "type": "vec4", "values": [ 1000.0,0.0,0.0,0.0 ] }, + { "name": "aperture_strength", "type": "vec4", "values": [ 0.25,0.0,0.0,0.0 ] }, + { "name": "aperture_brightboost","type": "vec4", "values": [ 0.25,0.0,0.0,0.0 ] } ] } diff --git a/bgfx/effects/crt-geom/gaussx.json b/bgfx/effects/crt-geom/gaussx.json index 28e9cff1b87..4fc008f7954 100644 --- a/bgfx/effects/crt-geom/gaussx.json +++ b/bgfx/effects/crt-geom/gaussx.json @@ -1,29 +1,29 @@ { "blend": { - "equation": "add", - "srcColor": "1", - "dstColor": "0", - "srcAlpha": "1", - "dstAlpha": "0" + "equation": "add", + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" }, "depth": { - "function": "always", - "writeenable": false + "function": "always", + "writeenable": false }, "cull": { - "mode": "none" + "mode": "none" }, "write": { - "rgb": true, - "alpha": true + "rgb": true, + "alpha": true }, "vertex": "chains/crt-geom/vs_gaussx", "fragment": "chains/crt-geom/fs_gaussx", "uniforms": [ - { "name": "s_tex", "type": "int", "values": [ 0 ] }, - { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "u_width", "type": "vec4", "values": [ 2.0, 0.0, 0.0, 0.0 ] }, - { "name": "u_aspect", "type": "vec4", "values": [ 1.0,0.75, 0.0, 0.0 ] }, - { "name": "u_gamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] } + { "name": "s_tex", "type": "int", "values": [ 0 ] }, + { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_width", "type": "vec4", "values": [ 2.0, 0.0, 0.0, 0.0 ] }, + { "name": "u_aspect", "type": "vec4", "values": [ 1.0,0.75, 0.0, 0.0 ] }, + { "name": "u_gamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] } ] } diff --git a/bgfx/effects/crt-geom/gaussy.json b/bgfx/effects/crt-geom/gaussy.json index 65e324f0930..5f585c85688 100644 --- a/bgfx/effects/crt-geom/gaussy.json +++ b/bgfx/effects/crt-geom/gaussy.json @@ -1,29 +1,29 @@ { "blend": { - "equation": "add", - "srcColor": "1", - "dstColor": "0", - "srcAlpha": "1", - "dstAlpha": "0" + "equation": "add", + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" }, "depth": { - "function": "always", - "writeenable": false + "function": "always", + "writeenable": false }, "cull": { - "mode": "none" + "mode": "none" }, "write": { - "rgb": true, - "alpha": true + "rgb": true, + "alpha": true }, "vertex": "chains/crt-geom/vs_gaussy", "fragment": "chains/crt-geom/fs_gaussy", "uniforms": [ - { "name": "s_tex", "type": "int", "values": [ 0 ] }, - { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, - { "name": "u_width", "type": "vec4", "values": [ 2.0, 0.0, 0.0, 0.0 ] }, - { "name": "u_aspect", "type": "vec4", "values": [ 1.0,0.75, 0.0, 0.0 ] }, - { "name": "u_gamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] } + { "name": "s_tex", "type": "int", "values": [ 0 ] }, + { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_width", "type": "vec4", "values": [ 2.0, 0.0, 0.0, 0.0 ] }, + { "name": "u_aspect", "type": "vec4", "values": [ 1.0,0.75, 0.0, 0.0 ] }, + { "name": "u_gamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] } ] } diff --git a/bgfx/effects/crt-geom/mipmap8.json b/bgfx/effects/crt-geom/mipmap8.json new file mode 100644 index 00000000000..8ae25aa7c1e --- /dev/null +++ b/bgfx/effects/crt-geom/mipmap8.json @@ -0,0 +1,29 @@ +{ + "blend": { + "equation": "add", + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" + }, + "depth": { + "function": "always", + "writeenable": false + }, + "cull": { + "mode": "none" + }, + "write": { + "rgb": true, + "alpha": true + }, + "vertex": "chains/crt-geom/vs_mipmap8", + "fragment": "chains/crt-geom/fs_mipmap8", + "uniforms": [ + { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_tex_size1", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_smooth", "type": "vec4", "values": [ 0.5, 0.0, 0.0, 0.0 ] }, + { "name": "s_screen", "type": "int", "values": [ 0 ] }, + { "name": "s_mipmap", "type": "int", "values": [ 1 ] } + ] +} diff --git a/bgfx/effects/crt-geom/phosphor_apply.json b/bgfx/effects/crt-geom/phosphor_apply.json index 4353d0d9765..6b073d53a44 100644 --- a/bgfx/effects/crt-geom/phosphor_apply.json +++ b/bgfx/effects/crt-geom/phosphor_apply.json @@ -1,29 +1,29 @@ { "blend": { - "equation": "add", - "srcColor": "1", - "dstColor": "0", - "srcAlpha": "1", - "dstAlpha": "0" + "equation": "add", + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" }, "depth": { - "function": "always", - "writeenable": false + "function": "always", + "writeenable": false }, "cull": { - "mode": "none" + "mode": "none" }, "write": { - "rgb": true, - "alpha": true + "rgb": true, + "alpha": true }, "vertex": "chains/crt-geom/vs_phosphor_apply", "fragment": "chains/crt-geom/fs_phosphor_apply", "uniforms": [ - { "name": "s_screen", "type": "int", "values": [ 0 ] }, - { "name": "s_phosphor", "type": "int", "values": [ 1 ] }, - { "name": "u_phosphor_power", "type": "vec4", "values": [ 1.3, 0.0, 0.0, 0.0 ] }, - { "name": "u_phosphor_amplitude","type": "vec4", "values": [ 0.2, 0.0, 0.0, 0.0 ] }, - { "name": "u_gamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] } + { "name": "s_screen", "type": "int", "values": [ 0 ] }, + { "name": "s_phosphor", "type": "int", "values": [ 1 ] }, + { "name": "u_phosphor_power", "type": "vec4", "values": [ 1.3, 0.0, 0.0, 0.0 ] }, + { "name": "u_phosphor_amplitude","type": "vec4", "values": [ 0.2, 0.0, 0.0, 0.0 ] }, + { "name": "u_gamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] } ] } diff --git a/bgfx/effects/crt-geom/phosphor_update.json b/bgfx/effects/crt-geom/phosphor_update.json index c1808c8fb81..8895fef7656 100644 --- a/bgfx/effects/crt-geom/phosphor_update.json +++ b/bgfx/effects/crt-geom/phosphor_update.json @@ -1,29 +1,29 @@ { "blend": { - "equation": "add", - "srcColor": "1", - "dstColor": "0", - "srcAlpha": "1", - "dstAlpha": "0" + "equation": "add", + "srcColor": "1", + "dstColor": "0", + "srcAlpha": "1", + "dstAlpha": "0" }, "depth": { - "function": "always", - "writeenable": false + "function": "always", + "writeenable": false }, "cull": { - "mode": "none" + "mode": "none" }, "write": { - "rgb": true, - "alpha": true + "rgb": true, + "alpha": true }, "vertex": "chains/crt-geom/vs_phosphor_update", "fragment": "chains/crt-geom/fs_phosphor_update", "uniforms": [ - { "name": "s_screen", "type": "int", "values": [ 0 ] }, - { "name": "s_phosphor", "type": "int", "values": [ 1 ] }, - { "name": "u_phosphor_power", "type": "vec4", "values": [ 1.3, 0.0, 0.0, 0.0 ] }, - { "name": "u_phosphor_amplitude","type": "vec4", "values": [ 0.2, 0.0, 0.0, 0.0 ] }, - { "name": "u_gamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] } + { "name": "s_screen", "type": "int", "values": [ 0 ] }, + { "name": "s_phosphor", "type": "int", "values": [ 1 ] }, + { "name": "u_phosphor_power", "type": "vec4", "values": [ 1.3, 0.0, 0.0, 0.0 ] }, + { "name": "u_phosphor_amplitude","type": "vec4", "values": [ 0.2, 0.0, 0.0, 0.0 ] }, + { "name": "u_gamma", "type": "vec4", "values": [ 2.2, 0.0, 0.0, 0.0 ] } ] } diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom-deluxe.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom-deluxe.bin index c2beaf0a0bb..0f7b8478413 100644 Binary files a/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom-deluxe.bin and b/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom-deluxe.bin differ diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.bin index d9bc7650ad0..b10938c0365 100644 Binary files a/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.bin and b/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.bin differ diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_mipmap8.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_mipmap8.bin new file mode 100644 index 00000000000..be943521f64 Binary files /dev/null and b/bgfx/shaders/glsl/chains/crt-geom/fs_mipmap8.bin differ diff --git a/bgfx/shaders/glsl/chains/crt-geom/vs_mipmap8.bin b/bgfx/shaders/glsl/chains/crt-geom/vs_mipmap8.bin new file mode 100644 index 00000000000..7e83a3fefbb Binary files /dev/null and b/bgfx/shaders/glsl/chains/crt-geom/vs_mipmap8.bin differ diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc index a060de88ddd..82af2ebd3ec 100644 --- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc +++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc @@ -28,12 +28,17 @@ $input v_sinangle, v_cosangle, v_stretch, v_one, v_texCoord SAMPLER2D(mpass_texture, 0); SAMPLER2D(mask_texture, 1); SAMPLER2D(blur_texture, 2); +SAMPLER2D(mipmap_texture, 3); +vec4 TEX2D(vec2 c) +{ + vec2 underscan = step(0.0,c) * step(0.0,vec2_splat(1.0)-c); + vec4 col = texture2D(mpass_texture, c) * vec4_splat(underscan.x*underscan.y); #ifdef LINEAR_PROCESSING -# define TEX2D(c) pow(texture2D(mpass_texture, (c)), vec4(CRTgamma)) -#else -# define TEX2D(c) texture2D(mpass_texture, (c)) + col = pow(col, vec4_splat(CRTgamma.x)); #endif + return col; +} // Enable screen curvature. uniform vec4 curvature; @@ -43,6 +48,7 @@ uniform vec4 u_tex_size1; uniform vec4 u_quad_dims; uniform vec4 aperture_strength; +uniform vec4 aperture_brightboost; uniform vec4 CRTgamma; uniform vec4 monitorgamma; @@ -57,6 +63,22 @@ uniform vec4 cornersize; uniform vec4 cornersmooth; uniform vec4 halation; +uniform vec4 rasterbloom; + +uniform vec4 blurwidth; + +vec3 texblur(vec2 c) +{ + vec3 col = pow(texture2D(blur_texture,c).rgb, vec3_splat(CRTgamma.x)); + // taper the blur texture outside its border with a gaussian + float w = blurwidth.x / 320.0; + c = min(c, vec2_splat(1.0)-c) * aspect.xy * vec2_splat(1.0/w); + vec2 e2c = exp(-c*c); + // approximation of erf gives smooth step + // (convolution of gaussian with step) + c = (step(0.0,c)-vec2_splat(0.5)) * sqrt(vec2_splat(1.0)-e2c) * (vec2_splat(1.0) + vec2_splat(0.1749)*e2c) + vec2_splat(0.5); + return col * vec3_splat( c.x * c.y ); +} float intersect(vec2 xy , vec2 sinangle, vec2 cosangle) { @@ -157,8 +179,13 @@ void main() xy = transform(v_texCoord, v_stretch, v_sinangle, v_cosangle); else xy = (v_texCoord-vec2_splat(0.5))/overscan.xy+vec2_splat(0.5); - vec2 xy0 = xy; float cval = corner(xy); + // extract average brightness from the mipmap texture + float avgbright = dot(texture2D(mipmap_texture,vec2(1.0,1.0)).rgb,vec3_splat(1.0))/3.0; + float rbloom = 1.0 - rasterbloom.x * ( avgbright - 0.5 ); + // expand the screen when average brightness is higher + xy = (xy - vec2_splat(0.5)) * rbloom + vec2_splat(0.5); + vec2 xy0 = xy; // Of all the pixels that are mapped onto the texel we are // currently rendering, which pixel are we currently rendering? @@ -191,13 +218,13 @@ void main() // using the Lanczos coefficients above. vec4 col = clamp(TEX2D(xy + vec2(-v_one.x, 0.0))*coeffs.x + TEX2D(xy)*coeffs.y + - TEX2D(xy +vec2(v_one.x, 0.0))*coeffs.z + - TEX2D(xy + vec2(2.0 * v_one.x, 0.0))*coeffs.w , 0.0, 1.0); + TEX2D(xy +vec2(v_one.x, 0.0))*coeffs.z + + TEX2D(xy + vec2(2.0 * v_one.x, 0.0))*coeffs.w , 0.0, 1.0); vec4 col2 = clamp(TEX2D(xy + vec2(-v_one.x, v_one.y))*coeffs.x + - TEX2D(xy + vec2(0.0, v_one.y))*coeffs.y + - TEX2D(xy + v_one)*coeffs.z + - TEX2D(xy + vec2(2.0 * v_one.x, v_one.y))*coeffs.w , 0.0, 1.0); + TEX2D(xy + vec2(0.0, v_one.y))*coeffs.y + + TEX2D(xy + v_one)*coeffs.z + + TEX2D(xy + vec2(2.0 * v_one.x, v_one.y))*coeffs.w , 0.0, 1.0); #ifndef LINEAR_PROCESSING @@ -220,16 +247,29 @@ void main() vec3 mul_res = (col * weights + col2 * weights2).rgb; // halation and corners - vec3 blur = pow(texture2D(blur_texture,xy0).rgb, vec3_splat(CRTgamma.x)); - mul_res = mix(mul_res, blur, halation.x) * vec3_splat(cval); - - // Convert the image gamma for display on our output device. - mul_res = pow(mul_res, vec3_splat(1.0 / monitorgamma.x)); + vec3 blur = texblur(xy0); + // include factor of rbloom: + // (probably imperceptible) brightness reduction when raster grows + mul_res = mix(mul_res, blur, halation.x) * vec3_splat(cval*rbloom); // Shadow mask xy = v_texCoord.xy * u_quad_dims.xy / u_tex_size1.xy; - vec3 mask = texture2D(mask_texture, xy).rgb; - mask = mix(vec3_splat(1.0), mask, aperture_strength.x); + vec4 mask = texture2D(mask_texture, xy); + // count of total bright pixels is encoded in the mask's alpha channel + float nbright = 255.0 - 255.0*mask.a; + // fraction of bright pixels in the mask + float fbright = nbright / ( u_tex_size1.x * u_tex_size1.y ); + // average darkening factor of the mask + float aperture_average = mix(1.0-aperture_strength.x*(1.0-aperture_brightboost.x), 1.0, fbright); + // colour of dark mask pixels + vec3 clow = vec3_splat(1.0-aperture_strength.x) * mul_res + vec3_splat(aperture_strength.x*(aperture_brightboost.x)) * mul_res * mul_res; + float ifbright = 1.0 / fbright; + // colour of bright mask pixels + vec3 chi = vec3_splat(ifbright*aperture_average) * mul_res - vec3_splat(ifbright - 1.0) * clow; + vec3 cout = mix(clow,chi,mask.rgb); // mask texture selects dark vs bright + + // Convert the image gamma for display on our output device. + cout = pow(cout, vec3_splat(1.0 / monitorgamma.x)); - gl_FragColor = vec4(mul_res*mask, col.a); + gl_FragColor = vec4(cout,1.0); } diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc index 658e745cf14..f3f5513584a 100644 --- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc +++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc @@ -27,11 +27,16 @@ $input v_sinangle, v_cosangle, v_stretch, v_one, v_texCoord SAMPLER2D(mpass_texture, 0); SAMPLER2D(mask_texture, 1); + +vec4 TEX2D(vec2 c) +{ + vec2 underscan = step(0.0,c) * step(0.0,vec2_splat(1.0)-c); + vec4 col = texture2D(mpass_texture, c) * vec4_splat(underscan.x*underscan.y); #ifdef LINEAR_PROCESSING -# define TEX2D(c) pow(texture2D(mpass_texture, (c)), vec4(CRTgamma)) -#else -# define TEX2D(c) texture2D(mpass_texture, (c)) + col = pow(col, vec4_splat(CRTgamma.x)); #endif + return col; +} // Enable screen curvature. uniform vec4 curvature; @@ -41,6 +46,7 @@ uniform vec4 u_tex_size1; uniform vec4 u_quad_dims; uniform vec4 aperture_strength; +uniform vec4 aperture_brightboost; uniform vec4 CRTgamma; uniform vec4 monitorgamma; @@ -186,13 +192,13 @@ void main() // using the Lanczos coefficients above. vec4 col = clamp(TEX2D(xy + vec2(-v_one.x, 0.0))*coeffs.x + TEX2D(xy)*coeffs.y + - TEX2D(xy +vec2(v_one.x, 0.0))*coeffs.z + - TEX2D(xy + vec2(2.0 * v_one.x, 0.0))*coeffs.w , 0.0, 1.0); + TEX2D(xy +vec2(v_one.x, 0.0))*coeffs.z + + TEX2D(xy + vec2(2.0 * v_one.x, 0.0))*coeffs.w , 0.0, 1.0); vec4 col2 = clamp(TEX2D(xy + vec2(-v_one.x, v_one.y))*coeffs.x + - TEX2D(xy + vec2(0.0, v_one.y))*coeffs.y + - TEX2D(xy + v_one)*coeffs.z + - TEX2D(xy + vec2(2.0 * v_one.x, v_one.y))*coeffs.w , 0.0, 1.0); + TEX2D(xy + vec2(0.0, v_one.y))*coeffs.y + + TEX2D(xy + v_one)*coeffs.z + + TEX2D(xy + vec2(2.0 * v_one.x, v_one.y))*coeffs.w , 0.0, 1.0); #ifndef LINEAR_PROCESSING @@ -214,14 +220,24 @@ void main() #endif vec3 mul_res = (col * weights + col2 * weights2).rgb * vec3_splat(cval); - // Convert the image gamma for display on our output device. - mul_res = pow(mul_res, vec3_splat(1.0 / monitorgamma.x)); - - // Color the texel. - + // Shadow mask xy = v_texCoord.xy * u_quad_dims.xy / u_tex_size1.xy; - vec3 mask = texture2D(mask_texture, xy).rgb; - mask = mix(vec3_splat(1.0), mask, aperture_strength.x); + vec4 mask = texture2D(mask_texture, xy); + // count of total bright pixels is encoded in the mask's alpha channel + float nbright = 255.0 - 255.0*mask.a; + // fraction of bright pixels in the mask + float fbright = nbright / ( u_tex_size1.x * u_tex_size1.y ); + // average darkening factor of the mask + float aperture_average = mix(1.0-aperture_strength.x*(1.0-aperture_brightboost.x), 1.0, fbright); + // colour of dark mask pixels + vec3 clow = vec3_splat(1.0-aperture_strength.x) * mul_res + vec3_splat(aperture_strength.x*(aperture_brightboost.x)) * mul_res * mul_res; + float ifbright = 1.0 / fbright; + // colour of bright mask pixels + vec3 chi = vec3_splat(ifbright*aperture_average) * mul_res - vec3_splat(ifbright - 1.0) * clow; + vec3 cout = mix(clow,chi,mask.rgb); // mask texture selects dark vs bright + + // Convert the image gamma for display on our output device. + cout = pow(cout, vec3_splat(1.0 / monitorgamma.x)); - gl_FragColor = vec4(mul_res*mask, col.a); + gl_FragColor = vec4(cout,1.0); } diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc new file mode 100644 index 00000000000..0f86bdbc7ba --- /dev/null +++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_mipmap8.sc @@ -0,0 +1,148 @@ +$input v_texCoord + +#include "common.sh" + +SAMPLER2D(s_screen, 0); +SAMPLER2D(s_mipmap, 1); + +uniform vec4 u_tex_size0; +uniform vec4 u_tex_size1; +uniform vec4 u_smooth; + +/* + * Based loosely on the idea outlined at + * https://nyorain.github.io/mipmap-compute-shader.html + * Each higher mipmap level is delayed by one frame. + * + * A rectangle containing (1,1) has the last mipmap level + * (normally a single pixel containing the average of the frame), + * passed through a two-tap IIR temporal filter. + */ + +const vec2 v05 = vec2(0.5,0.5); + +// pix has integer coordinates -> average four pixels using bilinear filtering +vec3 sample_screen(vec2 pix) +{ + vec2 border = step(-0.5, u_tex_size0.xy - pix); + float weight = border.x * border.y; + + // avoid boundary! if dimensions are odd, average 1 or 2 pixels + vec2 x = clamp(pix, vec2_splat(0.0), u_tex_size0.xy - v05); + // if we're at the boundary, include weight factor + // -> effectively always average 4 pixels, with some of them possibly zero + border = clamp(u_tex_size0.xy-x,0.0,1.0); + weight *= border.x * border.y; + + vec3 tex = texture2D(s_screen, x / u_tex_size0.xy).rgb; + + return tex * vec3_splat(weight); +} + +vec3 sample_mipmap(vec2 pix, vec2 offset, vec2 size) +{ + vec2 border = step(-0.5, size - pix) * step(-0.5, pix); + float weight = border.x * border.y; + + // avoid boundary! if dimensions are odd, average 1 or 2 pixels + vec2 x = clamp(pix, vec2_splat(0.0), size - v05); + // if we're at the boundary, include weight factor + // -> effectively always average 4 pixels, with some of them possibly zero + border = clamp(size-x,0.0,1.0); + weight *= border.x * border.y; + + vec3 tex = texture2D(s_mipmap, (x + offset) / u_tex_size0.xy).rgb; + + return tex * vec3_splat(weight); +} + +void main() +{ + vec2 pix = v_texCoord.xy * u_tex_size0.xy; + vec2 x = pix*vec2_splat(8.0); + if (pix.x < u_tex_size0.x * 0.5) { + // first level: sample from screen texture + + // sample 4x4 grid + // each sample uses bilinear filtering to average a 2x2 region + // overall reduction by 8x8 + vec3 tex = ( sample_screen(x + vec2(-3.0,-3.0)) + + sample_screen(x + vec2(-3.0,-1.0)) + + sample_screen(x + vec2(-3.0, 1.0)) + + sample_screen(x + vec2(-3.0, 3.0)) + + sample_screen(x + vec2(-1.0,-3.0)) + + sample_screen(x + vec2(-1.0,-1.0)) + + sample_screen(x + vec2(-1.0, 1.0)) + + sample_screen(x + vec2(-1.0, 3.0)) + + sample_screen(x + vec2( 1.0,-3.0)) + + sample_screen(x + vec2( 1.0,-1.0)) + + sample_screen(x + vec2( 1.0, 1.0)) + + sample_screen(x + vec2( 1.0, 3.0)) + + sample_screen(x + vec2( 3.0,-3.0)) + + sample_screen(x + vec2( 3.0,-1.0)) + + sample_screen(x + vec2( 3.0, 1.0)) + + sample_screen(x + vec2( 3.0, 3.0)) ) * 0.0625; + + gl_FragColor = vec4(tex.rgb,1.0); + } else { + // higher levels: sample from mipmap texture + vec2 newsize = u_tex_size0.xy; // size of texture being sampled + float fac = 8.0; // keep track of the linear reduction factor + float dx = u_tex_size0.x; + vec2 offset = vec2_splat(0.0); + vec2 offset0 = offset; + bool fc = false; + + for (int i = 0; i < 3; i++) { // 3 is sufficient for dimensions up to 4k + // place subsequent levels to the right + if (pix.x > dx * 0.5) { + dx = dx * 0.5; + newsize = ceil(newsize*v05*v05*v05); // size of sampled texture is eighthed + fac *= 8.0; + offset0 = offset; + offset.x = offset.x + dx; + pix.x -= dx; + x = pix * vec2_splat(8.0); + if (newsize.x < 8.5 && newsize.y < 8.5) { // reducing to a single pixel + fc = true; + break; + } + } else break; + } + + if (fc) + x = vec2(4.0,4.0); + + vec3 tex = ( sample_mipmap(x + vec2(-3.0,-3.0),offset0,newsize) + + sample_mipmap(x + vec2(-3.0,-1.0),offset0,newsize) + + sample_mipmap(x + vec2(-3.0, 1.0),offset0,newsize) + + sample_mipmap(x + vec2(-3.0, 3.0),offset0,newsize) + + sample_mipmap(x + vec2(-1.0,-3.0),offset0,newsize) + + sample_mipmap(x + vec2(-1.0,-1.0),offset0,newsize) + + sample_mipmap(x + vec2(-1.0, 1.0),offset0,newsize) + + sample_mipmap(x + vec2(-1.0, 3.0),offset0,newsize) + + sample_mipmap(x + vec2( 1.0,-3.0),offset0,newsize) + + sample_mipmap(x + vec2( 1.0,-1.0),offset0,newsize) + + sample_mipmap(x + vec2( 1.0, 1.0),offset0,newsize) + + sample_mipmap(x + vec2( 1.0, 3.0),offset0,newsize) + + sample_mipmap(x + vec2( 3.0,-3.0),offset0,newsize) + + sample_mipmap(x + vec2( 3.0,-1.0),offset0,newsize) + + sample_mipmap(x + vec2( 3.0, 1.0),offset0,newsize) + + sample_mipmap(x + vec2( 3.0, 3.0),offset0,newsize) ) * 0.0625; + + if (fc) { // this sample yields average over the whole screen + // apply a compensation for the zeros included in the 8^n average + float f = fac*fac / (u_tex_size0.x * u_tex_size0.y); + vec3 col = tex * vec3_splat(f); + if (v_texCoord.y * u_tex_size1.y < ( offset0.y + u_tex_size1.y ) * 0.5) { + gl_FragColor = vec4(col,1.0); + } else { + // we are near (1,1): in this region include the temporal filter + vec4 old = texture2D(s_mipmap, v_texCoord.xy); + gl_FragColor = vec4(mix(col,old.rgb,u_smooth.x),1.0); + } + } else { + gl_FragColor = vec4(tex.rgb,1.0); + } + } +} diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc new file mode 100644 index 00000000000..bdd09148403 --- /dev/null +++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_mipmap8.sc @@ -0,0 +1,11 @@ +$input a_position, a_texcoord0, a_color0 +$output v_texCoord + +#include "common.sh" + +void main() +{ + // Do the standard vertex processing. + gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0)); + v_texCoord = a_texcoord0; +} -- cgit v1.2.3