summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author cgwg <cgwg@users.noreply.github.com>2021-03-19 16:38:07 +0100
committer GitHub <noreply@github.com>2021-03-20 02:38:07 +1100
commit931f85ee2709b8630c571c53be10e280fd4ed3bb (patch)
tree90a3df91f3720265678d780b99058ce6fcac006a
parentf15e301557c99f7e763dd933c0d47fa349bbd229 (diff)
bgfx: crt-geom and crt-geom-deluxe enhancements (#7872)
* Made spot size parameters adjustable also increased samples from 2 to 3 scanlines for crt-geom-deluxe. * Made horizontal interpolation adjustable. * bgfx crt-geom-deluxe: Made phosphor decay smoothly to zero at specified cutoff time. * bgfx crt-geom-deluxe: Added lowpass filter.
-rw-r--r--bgfx/chains/crt-geom-deluxe.json104
-rw-r--r--bgfx/chains/crt-geom.json43
-rw-r--r--bgfx/effects/crt-geom/crt-geom-deluxe.json4
-rw-r--r--bgfx/effects/crt-geom/crt-geom.json6
-rw-r--r--bgfx/effects/crt-geom/lowpass.json28
-rw-r--r--bgfx/effects/crt-geom/phosphor_apply.json1
-rw-r--r--bgfx/effects/crt-geom/phosphor_update.json1
-rw-r--r--bgfx/shaders/essl/chains/crt-geom/fs_crt-geom-deluxe.binbin10757 -> 17738 bytes
-rw-r--r--bgfx/shaders/essl/chains/crt-geom/fs_crt-geom.binbin9709 -> 13861 bytes
-rw-r--r--bgfx/shaders/essl/chains/crt-geom/fs_lowpass.binbin0 -> 6420 bytes
-rw-r--r--bgfx/shaders/essl/chains/crt-geom/fs_phosphor_apply.binbin775 -> 1508 bytes
-rw-r--r--bgfx/shaders/essl/chains/crt-geom/fs_phosphor_update.binbin1457 -> 2056 bytes
-rw-r--r--bgfx/shaders/essl/chains/crt-geom/vs_lowpass.binbin0 -> 2706 bytes
-rw-r--r--bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom-deluxe.binbin10255 -> 16986 bytes
-rw-r--r--bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.binbin9221 -> 13205 bytes
-rw-r--r--bgfx/shaders/glsl/chains/crt-geom/fs_lowpass.binbin0 -> 6119 bytes
-rw-r--r--bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_apply.binbin741 -> 1427 bytes
-rw-r--r--bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_update.binbin1394 -> 1966 bytes
-rw-r--r--bgfx/shaders/glsl/chains/crt-geom/vs_lowpass.binbin0 -> 2616 bytes
-rw-r--r--bgfx/shaders/metal/chains/crt-geom/fs_crt-geom-deluxe.binbin9068 -> 14995 bytes
-rw-r--r--bgfx/shaders/metal/chains/crt-geom/fs_crt-geom.binbin7987 -> 11798 bytes
-rw-r--r--bgfx/shaders/metal/chains/crt-geom/fs_lowpass.binbin0 -> 4587 bytes
-rw-r--r--bgfx/shaders/metal/chains/crt-geom/fs_phosphor_apply.binbin1158 -> 1579 bytes
-rw-r--r--bgfx/shaders/metal/chains/crt-geom/fs_phosphor_update.binbin1581 -> 1979 bytes
-rw-r--r--bgfx/shaders/metal/chains/crt-geom/vs_lowpass.binbin0 -> 3957 bytes
-rw-r--r--bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom-deluxe.binbin15085 -> 24166 bytes
-rw-r--r--bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom.binbin13212 -> 18581 bytes
-rw-r--r--bgfx/shaders/spirv/chains/crt-geom/fs_lowpass.binbin0 -> 7703 bytes
-rw-r--r--bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_apply.binbin2310 -> 2986 bytes
-rw-r--r--bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_update.binbin2739 -> 3391 bytes
-rw-r--r--bgfx/shaders/spirv/chains/crt-geom/vs_lowpass.binbin0 -> 4588 bytes
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom-deluxe.sc121
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_crt-geom.sc89
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc37
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc16
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc26
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc2
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc49
38 files changed, 444 insertions, 83 deletions
diff --git a/bgfx/chains/crt-geom-deluxe.json b/bgfx/chains/crt-geom-deluxe.json
index 0eabc4ac399..9c9dd18505b 100644
--- a/bgfx/chains/crt-geom-deluxe.json
+++ b/bgfx/chains/crt-geom-deluxe.json
@@ -21,6 +21,61 @@
"format": "%1.2f",
"screen": "raster" },
{ "type": "float",
+ "name": "spot_size",
+ "text": "Spot size minimum",
+ "default": 0.3,
+ "max" : 0.5,
+ "min" : 0.1,
+ "step" : 0.01,
+ "format": "%1.2f",
+ "screen": "raster" },
+ { "type": "float",
+ "name": "spot_growth",
+ "text": "Spot size dilation",
+ "default": 0.1,
+ "max" : 0.4,
+ "min" : 0.0,
+ "step" : 0.01,
+ "format": "%1.2f",
+ "screen": "raster" },
+ { "type": "float",
+ "name": "spot_growth_power",
+ "text": "Spot dilation onset power",
+ "default": 3.0,
+ "max" : 4.0,
+ "min" : 0.2,
+ "step" : 0.1,
+ "format": "%1.1f",
+ "screen": "raster" },
+ { "type": "float",
+ "name": "lowpass_cutoff",
+ "text": "Lowpass cutoff pixels/scanline",
+ "default": 200.0,
+ "max" :1000.0,
+ "min" : 100.0,
+ "step" : 10.0,
+ "format": "%1.0f",
+ "screen": "raster" },
+ { "type": "float",
+ "name": "lowpass_width",
+ "text": "Lowpass width",
+ "default": 80.0,
+ "max" : 300.0,
+ "min" : 0.0,
+ "step" : 10.0,
+ "format": "%1.0f",
+ "screen": "raster" },
+ { "type": "intenum",
+ "name": "x_interpolation",
+ "text": "Horizontal interpolation",
+ "default": 2,
+ "max" : 5,
+ "min" : 0,
+ "step" : 1,
+ "format": "%s",
+ "strings": [ "box", "linear", "Lanczos", "Catmull-Rom", "Mitchell-Netravali", "B-spline" ],
+ "screen": "raster" },
+ { "type": "float",
"name": "phosphor_power",
"text": "Phosphor decay power",
"default": 1.2,
@@ -30,6 +85,15 @@
"format": "%1.2f",
"screen": "raster" },
{ "type": "float",
+ "name": "phosphor_cutoff",
+ "text": "Phosphor decay cutoff frames",
+ "default": 300.0,
+ "max" : 1000.0,
+ "min" : 10.0,
+ "step" : 10.0,
+ "format": "%1.0f",
+ "screen": "raster" },
+ { "type": "float",
"name": "phosphor_amplitude",
"text": "Phosphor persistence amplitude",
"default": 0.04,
@@ -184,19 +248,16 @@
],
"passes": [
{
- "effect": "crt-geom/phosphor_apply",
- "applytint": true,
- "name": "phosphor apply",
+ "effect": "crt-geom/lowpass",
+ "name": "lowpass",
"uniforms": [
- { "uniform": "u_phosphor_power", "slider": "phosphor_power" },
- { "uniform": "u_phosphor_amplitude","slider": "phosphor_amplitude" },
- { "uniform": "u_gamma", "slider": "CRTgamma" }
+ { "uniform": "u_lowpass_cutoff", "slider": "lowpass_cutoff" },
+ { "uniform": "u_lowpass_width", "slider": "lowpass_width" }
],
"input": [
- { "sampler": "s_screen", "target": "screen" },
- { "sampler": "s_phosphor", "target": "phosphor" }
+ { "sampler": "s_screen", "target": "screen" }
],
- "output": "internal1"
+ "output": "internal2"
},
{
"effect": "crt-geom/mipmap8",
@@ -205,21 +266,38 @@
{ "uniform": "u_smooth", "slider": "rasterbloom_smooth" }
],
"input": [
- { "sampler": "s_screen", "target": "internal1" },
+ { "sampler": "s_screen", "target": "internal2" },
{ "sampler": "s_mipmap", "target": "mipmap" }
],
"output": "mipmap"
},
{
+ "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_phosphor_cutoff", "slider": "phosphor_cutoff" },
+ { "uniform": "u_gamma", "slider": "CRTgamma" }
+ ],
+ "input": [
+ { "sampler": "s_screen", "target": "internal2" },
+ { "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_phosphor_cutoff", "slider": "phosphor_cutoff" },
{ "uniform": "u_gamma", "slider": "CRTgamma" }
],
"input": [
- { "sampler": "s_screen", "target": "screen" },
+ { "sampler": "s_screen", "target": "internal2" },
{ "sampler": "s_phosphor", "target": "phosphor" }
],
"output": "phosphor"
@@ -266,6 +344,10 @@
{ "uniform": "monitorgamma","slider": "monitorgamma" },
{ "uniform": "aperture_strength","slider": "aperture_strength" },
{ "uniform": "aperture_brightboost","slider": "aperture_brightboost" },
+ { "uniform": "spot_size", "slider": "spot_size" },
+ { "uniform": "spot_growth", "slider": "spot_growth" },
+ { "uniform": "spot_growth_power", "slider": "spot_growth_power" },
+ { "uniform": "u_interp", "slider": "x_interpolation" },
{ "uniform": "halation", "slider": "halation" },
{ "uniform": "blurwidth", "slider": "blurwidth" },
{ "uniform": "rasterbloom", "slider": "rasterbloom" }
diff --git a/bgfx/chains/crt-geom.json b/bgfx/chains/crt-geom.json
index c8d852e1b9a..fae003f5c9c 100644
--- a/bgfx/chains/crt-geom.json
+++ b/bgfx/chains/crt-geom.json
@@ -21,6 +21,43 @@
"format": "%1.2f",
"screen": "raster" },
{ "type": "float",
+ "name": "spot_size",
+ "text": "Spot size minimum",
+ "default": 0.3,
+ "max" : 0.5,
+ "min" : 0.1,
+ "step" : 0.01,
+ "format": "%1.2f",
+ "screen": "raster" },
+ { "type": "float",
+ "name": "spot_growth",
+ "text": "Spot size dilation",
+ "default": 0.1,
+ "max" : 0.4,
+ "min" : 0.0,
+ "step" : 0.01,
+ "format": "%1.2f",
+ "screen": "raster" },
+ { "type": "float",
+ "name": "spot_growth_power",
+ "text": "Spot dilation onset power",
+ "default": 3.0,
+ "max" : 4.0,
+ "min" : 0.2,
+ "step" : 0.1,
+ "format": "%1.1f",
+ "screen": "raster" },
+ { "type": "intenum",
+ "name": "x_interpolation",
+ "text": "Horizontal interpolation",
+ "default": 2,
+ "max" : 5,
+ "min" : 0,
+ "step" : 1,
+ "format": "%s",
+ "strings": [ "box", "linear", "Lanczos", "Catmull-Rom", "Mitchell-Netravali", "B-spline" ],
+ "screen": "raster" },
+ { "type": "float",
"name": "curvature",
"text": "Enable curvature",
"default": 1.0,
@@ -130,7 +167,11 @@
{ "uniform": "CRTgamma", "slider": "CRTgamma" },
{ "uniform": "monitorgamma","slider": "monitorgamma" },
{ "uniform": "aperture_strength", "slider": "aperture_strength" },
- { "uniform": "aperture_brightboost","slider": "aperture_brightboost" }
+ { "uniform": "aperture_brightboost","slider": "aperture_brightboost" },
+ { "uniform": "spot_size", "slider": "spot_size" },
+ { "uniform": "spot_growth", "slider": "spot_growth" },
+ { "uniform": "spot_growth_power", "slider": "spot_growth_power" },
+ { "uniform": "u_interp", "slider": "x_interpolation" }
],
"input": [
{ "sampler": "mpass_texture", "target": "screen" },
diff --git a/bgfx/effects/crt-geom/crt-geom-deluxe.json b/bgfx/effects/crt-geom/crt-geom-deluxe.json
index c561db7a9c5..10f87874a4d 100644
--- a/bgfx/effects/crt-geom/crt-geom-deluxe.json
+++ b/bgfx/effects/crt-geom/crt-geom-deluxe.json
@@ -40,6 +40,10 @@
{ "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": "spot_size", "type": "vec4", "values": [ 0.3,0.0,0.0,0.0 ] },
+ { "name": "spot_growth","type": "vec4", "values": [ 0.1,0.0,0.0,0.0 ] },
+ { "name": "spot_growth_power", "type": "vec4", "values": [ 3.0,0.0,0.0,0.0 ] },
+ { "name": "u_interp", "type": "vec4", "values": [ 2.0,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 12624942fe7..5b2e1b6730e 100644
--- a/bgfx/effects/crt-geom/crt-geom.json
+++ b/bgfx/effects/crt-geom/crt-geom.json
@@ -37,6 +37,10 @@
{ "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": "aperture_brightboost","type": "vec4", "values": [ 0.25,0.0,0.0,0.0 ] },
+ { "name": "spot_size", "type": "vec4", "values": [ 0.3,0.0,0.0,0.0 ] },
+ { "name": "spot_growth","type": "vec4", "values": [ 0.1,0.0,0.0,0.0 ] },
+ { "name": "spot_growth_power", "type": "vec4", "values": [ 3.0,0.0,0.0,0.0 ] },
+ { "name": "u_interp", "type": "vec4", "values": [ 2.0,0.0,0.0,0.0 ] }
]
}
diff --git a/bgfx/effects/crt-geom/lowpass.json b/bgfx/effects/crt-geom/lowpass.json
new file mode 100644
index 00000000000..7115e2112be
--- /dev/null
+++ b/bgfx/effects/crt-geom/lowpass.json
@@ -0,0 +1,28 @@
+{
+ "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_lowpass",
+ "fragment": "chains/crt-geom/fs_lowpass",
+ "uniforms": [
+ { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
+ { "name": "u_lowpass_cutoff","type": "vec4", "values": [ 200.0, 0.0, 0.0, 0.0 ] },
+ { "name": "u_lowpass_width", "type": "vec4", "values": [ 80.0, 0.0, 0.0, 0.0 ] },
+ { "name": "s_screen", "type": "int", "values": [ 0 ] }
+ ]
+}
diff --git a/bgfx/effects/crt-geom/phosphor_apply.json b/bgfx/effects/crt-geom/phosphor_apply.json
index 6b073d53a44..dc6dfcb34b5 100644
--- a/bgfx/effects/crt-geom/phosphor_apply.json
+++ b/bgfx/effects/crt-geom/phosphor_apply.json
@@ -24,6 +24,7 @@
{ "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_phosphor_cutoff", "type": "vec4", "values": [300.0,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 8895fef7656..50cde93b69a 100644
--- a/bgfx/effects/crt-geom/phosphor_update.json
+++ b/bgfx/effects/crt-geom/phosphor_update.json
@@ -24,6 +24,7 @@
{ "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_phosphor_cutoff", "type": "vec4", "values": [300.0,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/essl/chains/crt-geom/fs_crt-geom-deluxe.bin b/bgfx/shaders/essl/chains/crt-geom/fs_crt-geom-deluxe.bin
index f014a53a5d7..49973286faa 100644
--- a/bgfx/shaders/essl/chains/crt-geom/fs_crt-geom-deluxe.bin
+++ b/bgfx/shaders/essl/chains/crt-geom/fs_crt-geom-deluxe.bin
Binary files differ
diff --git a/bgfx/shaders/essl/chains/crt-geom/fs_crt-geom.bin b/bgfx/shaders/essl/chains/crt-geom/fs_crt-geom.bin
index 48f65710391..0c866f28963 100644
--- a/bgfx/shaders/essl/chains/crt-geom/fs_crt-geom.bin
+++ b/bgfx/shaders/essl/chains/crt-geom/fs_crt-geom.bin
Binary files differ
diff --git a/bgfx/shaders/essl/chains/crt-geom/fs_lowpass.bin b/bgfx/shaders/essl/chains/crt-geom/fs_lowpass.bin
new file mode 100644
index 00000000000..e390298a362
--- /dev/null
+++ b/bgfx/shaders/essl/chains/crt-geom/fs_lowpass.bin
Binary files differ
diff --git a/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_apply.bin b/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_apply.bin
index 3630cfaaa7b..381479e4b9a 100644
--- a/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_apply.bin
+++ b/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_apply.bin
Binary files differ
diff --git a/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_update.bin b/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_update.bin
index 78cef4dfa16..b7809db5436 100644
--- a/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_update.bin
+++ b/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_update.bin
Binary files differ
diff --git a/bgfx/shaders/essl/chains/crt-geom/vs_lowpass.bin b/bgfx/shaders/essl/chains/crt-geom/vs_lowpass.bin
new file mode 100644
index 00000000000..a29c3521088
--- /dev/null
+++ b/bgfx/shaders/essl/chains/crt-geom/vs_lowpass.bin
Binary files differ
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 0f7b8478413..d24da626966 100644
--- a/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom-deluxe.bin
+++ b/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom-deluxe.bin
Binary files 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 b10938c0365..9176a6fd8c4 100644
--- a/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.bin
+++ b/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.bin
Binary files differ
diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_lowpass.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_lowpass.bin
new file mode 100644
index 00000000000..ca184aef7dc
--- /dev/null
+++ b/bgfx/shaders/glsl/chains/crt-geom/fs_lowpass.bin
Binary files differ
diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_apply.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_apply.bin
index 8feb7c80209..1877cf0c63f 100644
--- a/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_apply.bin
+++ b/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_apply.bin
Binary files differ
diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_update.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_update.bin
index 8a48edead09..2caaa822395 100644
--- a/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_update.bin
+++ b/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_update.bin
Binary files differ
diff --git a/bgfx/shaders/glsl/chains/crt-geom/vs_lowpass.bin b/bgfx/shaders/glsl/chains/crt-geom/vs_lowpass.bin
new file mode 100644
index 00000000000..88ebb214e32
--- /dev/null
+++ b/bgfx/shaders/glsl/chains/crt-geom/vs_lowpass.bin
Binary files differ
diff --git a/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom-deluxe.bin b/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom-deluxe.bin
index caf03a5cb5b..0817f98f581 100644
--- a/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom-deluxe.bin
+++ b/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom-deluxe.bin
Binary files differ
diff --git a/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom.bin b/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom.bin
index b915543f27b..698f6fc1961 100644
--- a/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom.bin
+++ b/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom.bin
Binary files differ
diff --git a/bgfx/shaders/metal/chains/crt-geom/fs_lowpass.bin b/bgfx/shaders/metal/chains/crt-geom/fs_lowpass.bin
new file mode 100644
index 00000000000..40b8ff0bc04
--- /dev/null
+++ b/bgfx/shaders/metal/chains/crt-geom/fs_lowpass.bin
Binary files differ
diff --git a/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_apply.bin b/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_apply.bin
index 3f4453b1490..57f35520720 100644
--- a/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_apply.bin
+++ b/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_apply.bin
Binary files differ
diff --git a/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_update.bin b/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_update.bin
index 73e77aba016..28f86d01a15 100644
--- a/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_update.bin
+++ b/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_update.bin
Binary files differ
diff --git a/bgfx/shaders/metal/chains/crt-geom/vs_lowpass.bin b/bgfx/shaders/metal/chains/crt-geom/vs_lowpass.bin
new file mode 100644
index 00000000000..7f16cc81cbc
--- /dev/null
+++ b/bgfx/shaders/metal/chains/crt-geom/vs_lowpass.bin
Binary files differ
diff --git a/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom-deluxe.bin b/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom-deluxe.bin
index 11396bc2297..fda6f08f24a 100644
--- a/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom-deluxe.bin
+++ b/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom-deluxe.bin
Binary files differ
diff --git a/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom.bin b/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom.bin
index 56c3783cf70..d94eef4c1c1 100644
--- a/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom.bin
+++ b/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom.bin
Binary files differ
diff --git a/bgfx/shaders/spirv/chains/crt-geom/fs_lowpass.bin b/bgfx/shaders/spirv/chains/crt-geom/fs_lowpass.bin
new file mode 100644
index 00000000000..4f8f994820d
--- /dev/null
+++ b/bgfx/shaders/spirv/chains/crt-geom/fs_lowpass.bin
Binary files differ
diff --git a/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_apply.bin b/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_apply.bin
index ac7b3373b36..2520a4347a7 100644
--- a/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_apply.bin
+++ b/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_apply.bin
Binary files differ
diff --git a/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_update.bin b/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_update.bin
index 20771f50017..cafea940d70 100644
--- a/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_update.bin
+++ b/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_update.bin
Binary files differ
diff --git a/bgfx/shaders/spirv/chains/crt-geom/vs_lowpass.bin b/bgfx/shaders/spirv/chains/crt-geom/vs_lowpass.bin
new file mode 100644
index 00000000000..318f409621b
--- /dev/null
+++ b/bgfx/shaders/spirv/chains/crt-geom/vs_lowpass.bin
Binary files 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 82af2ebd3ec..bf22d82c2e1 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
@@ -47,6 +47,12 @@ uniform vec4 u_tex_size0;
uniform vec4 u_tex_size1;
uniform vec4 u_quad_dims;
+uniform vec4 spot_size;
+uniform vec4 spot_growth;
+uniform vec4 spot_growth_power;
+
+uniform vec4 u_interp;
+
uniform vec4 aperture_strength;
uniform vec4 aperture_brightboost;
@@ -140,16 +146,67 @@ vec4 scanlineWeights(float distance, vec4 color)
// "weights" should have a higher peak at the center of the
// scanline than for a wider beam.
#ifdef USEGAUSSIAN
- vec4 wid = 0.3 + 0.1 * pow(color, vec4_splat(3.0));
+ vec4 wid = spot_size.x + spot_growth.x * pow(color, vec4_splat(spot_growth_power.x));
vec4 weights = vec4(distance / wid);
- return 0.4 * exp(-weights * weights) / wid;
+ float maxwid = spot_size.x + spot_growth.x;
+ float norm = maxwid / ( 1.0 + 2.0 * exp(-1.0/(maxwid*maxwid)) );
+ return norm * exp(-weights * weights) / wid;
#else
vec4 wid = 2.0 + 2.0 * pow(color, vec4_splat(4.0));
- vec4 weights = vec4_splat(distance / 0.3);
+ vec4 weights = vec4_splat(abs(distance) / 0.3);
return 1.4 * exp(-pow(weights * inversesqrt(0.5 * wid), wid)) / (0.6 + 0.2 * wid);
#endif
}
+vec4 cubic(vec4 x, float B, float C)
+{
+ // https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters
+ vec2 a = x.yz; // components in [0,1]
+ vec2 b = x.xw; // components in [1,2]
+ vec2 a2 = a*a;
+ vec2 b2 = b*b;
+ a = (2.0-1.5*B-1.0*C)*a*a2 + (-3.0+2.0*B+C)*a2 + (1.0-(1.0/3.0)*B);
+ b = ((-1.0/6.0)*B-C)*b*b2 + (B+5.0*C)*b2 + (-2.0*B-8.0*C)*b + ((4.0/3.0)*B+4.0*C);
+ return vec4(b.x,a.x,a.y,b.y);
+}
+
+vec4 x_coeffs(vec4 x, float pos_x)
+{
+ if (u_interp.x < 0.5) { // box
+ float wid = length(vec2(dFdx(pos_x),dFdy(pos_x)));
+ float dx = clamp((0.5 + 0.5*wid - x.y)/wid, 0.0, 1.0);
+ return vec4(0.0,dx,1.0-dx,0.0);
+ } else if (u_interp.x < 1.5) { // linear
+ return vec4(0.0, 1.0-x.y, 1.0-x.z, 0.0);
+ } else if (u_interp.x < 2.5) { // Lanczos
+ // Prevent division by zero.
+ vec4 coeffs = FIX(PI * x);
+ // Lanczos2 kernel.
+ coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
+ // Normalize.
+ coeffs /= dot(coeffs, vec4_splat(1.0));
+ return coeffs;
+ } else if (u_interp.x < 3.5) { // Catmull-Rom
+ return cubic(x,0.0,0.5);
+ } else if (u_interp.x < 4.5) { // Mitchell-Netravali
+ return cubic(x,1.0/3.0,1.0/3.0);
+ } else if (u_interp.x < 5.5) { // B-spline
+ return cubic(x,1.0,0.0);
+ }
+}
+
+vec4 sample_scanline(vec2 xy, vec4 coeffs, float onex)
+{
+ // Calculate the effective colour of the given
+ // scanline at the horizontal location of the current pixel,
+ // using the Lanczos coefficients.
+ vec4 col = clamp(TEX2D(xy + vec2(-onex, 0.0))*coeffs.x +
+ TEX2D(xy)*coeffs.y +
+ TEX2D(xy +vec2(onex, 0.0))*coeffs.z +
+ TEX2D(xy + vec2(2.0 * onex, 0.0))*coeffs.w , 0.0, 1.0);
+ return col;
+}
+
void main()
{
// Here's a helpful diagram to keep in mind while trying to
@@ -158,6 +215,10 @@ void main()
// | | | | |
// -------------------------------
// | | | | |
+ // | 00 | 10 | 20 | 30 | <-- previous scanline
+ // | | | | |
+ // -------------------------------
+ // | | | | |
// | 01 | 11 | 21 | 31 | <-- current scanline
// | | @ | | |
// -------------------------------
@@ -169,9 +230,10 @@ void main()
//
// Each character-cell represents a pixel on the output
// surface, "@" represents the current pixel (always somewhere
- // in the bottom half of the current scan-line, or the top-half
- // of the next scanline). The grid of lines represents the
+ // in the current scan-line). The grid of lines represents the
// edges of the texels of the underlying texture.
+ // The "deluxe" shader includes contributions from the
+ // previous, current, and next scanlines.
// Texture coordinates of the texel containing the active pixel.
vec2 xy;
@@ -189,62 +251,47 @@ void main()
// Of all the pixels that are mapped onto the texel we are
// currently rendering, which pixel are we currently rendering?
- vec2 ratio_scale = xy * u_tex_size0.xy - vec2_splat(0.5);
+ vec2 ratio_scale = xy * u_tex_size0.xy - vec2(0.5,0.0);
#ifdef OVERSAMPLE
float filter = fwidth(ratio_scale.y);
#endif
- vec2 uv_ratio = fract(ratio_scale);
+ vec2 uv_ratio = fract(ratio_scale) - vec2(0.0,0.5);
// Snap to the center of the underlying texel.
xy = (floor(ratio_scale) + vec2_splat(0.5)) / u_tex_size0.xy;
- // Calculate Lanczos scaling coefficients describing the effect
+ // Calculate scaling coefficients describing the effect
// of various neighbour texels in a scanline on the current
// pixel.
- vec4 coeffs = PI * vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
-
- // Prevent division by zero.
- coeffs = FIX(coeffs);
-
- // Lanczos2 kernel.
- coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
-
- // Normalize.
- coeffs /= dot(coeffs, vec4_splat(1.0));
-
- // Calculate the effective colour of the current and next
- // scanlines at the horizontal location of the current pixel,
- // 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);
-
- 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);
+ vec4 coeffs = x_coeffs(vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x), ratio_scale.x);
+ vec4 col = sample_scanline(xy, coeffs, v_one.x);
+ vec4 col_prev = sample_scanline(xy + vec2(0.0,-v_one.y), coeffs, v_one.x);
+ vec4 col_next = sample_scanline(xy + vec2(0.0, v_one.y), coeffs, v_one.x);
#ifndef LINEAR_PROCESSING
col = pow(col , vec4_splat(CRTgamma.x));
- col2 = pow(col2, vec4_splat(CRTgamma.x));
+ col_prev = pow(col_prev, vec4_splat(CRTgamma.x));
+ col_next = pow(col_next, vec4_splat(CRTgamma.x));
#endif
// Calculate the influence of the current and next scanlines on
// the current pixel.
vec4 weights = scanlineWeights(uv_ratio.y, col);
- vec4 weights2 = scanlineWeights(1.0 - uv_ratio.y, col2);
+ vec4 weights_prev = scanlineWeights(uv_ratio.y + 1.0, col_prev);
+ vec4 weights_next = scanlineWeights(uv_ratio.y - 1.0, col_next);
#ifdef OVERSAMPLE
uv_ratio.y =uv_ratio.y+1.0/3.0*filter;
weights = (weights+scanlineWeights(uv_ratio.y, col))/3.0;
- weights2=(weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2))/3.0;
+ weights_prev=(weights_prev+scanlineWeights(uv_ratio.y+1.0, col_prev))/3.0;
+ weights_next=(weights_next+scanlineWeights(uv_ratio.y-1.0, col_next))/3.0;
uv_ratio.y =uv_ratio.y-2.0/3.0*filter;
- weights=weights+scanlineWeights(abs(uv_ratio.y), col)/3.0;
- weights2=weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2)/3.0;
+ weights=weights+scanlineWeights(uv_ratio.y, col)/3.0;
+ weights_prev=weights_prev+scanlineWeights(uv_ratio.y+1.0, col_prev)/3.0;
+ weights_next=weights_next+scanlineWeights(uv_ratio.y-1.0, col_next)/3.0;
#endif
- vec3 mul_res = (col * weights + col2 * weights2).rgb;
+ vec3 mul_res = (col * weights + col_prev * weights_prev + col_next * weights_next).rgb;
// halation and corners
vec3 blur = texblur(xy0);
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 f3f5513584a..a767a060b99 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
@@ -45,6 +45,12 @@ uniform vec4 u_tex_size0;
uniform vec4 u_tex_size1;
uniform vec4 u_quad_dims;
+uniform vec4 spot_size;
+uniform vec4 spot_growth;
+uniform vec4 spot_growth_power;
+
+uniform vec4 u_interp;
+
uniform vec4 aperture_strength;
uniform vec4 aperture_brightboost;
@@ -120,9 +126,11 @@ vec4 scanlineWeights(float distance, vec4 color)
// "weights" should have a higher peak at the center of the
// scanline than for a wider beam.
#ifdef USEGAUSSIAN
- vec4 wid = 0.3 + 0.1 * pow(color, vec4_splat(3.0));
+ vec4 wid = spot_size.x + spot_growth.x * pow(color, vec4_splat(spot_growth_power.x));
vec4 weights = vec4(distance / wid);
- return 0.4 * exp(-weights * weights) / wid;
+ float maxwid = spot_size.x + spot_growth.x;
+ float norm = maxwid / ( 1.0 + exp(-1.0/(maxwid*maxwid)) );
+ return norm * exp(-weights * weights) / wid;
#else
vec4 wid = 2.0 + 2.0 * pow(color, vec4_splat(4.0));
vec4 weights = vec4_splat(distance / 0.3);
@@ -130,6 +138,55 @@ vec4 scanlineWeights(float distance, vec4 color)
#endif
}
+vec4 cubic(vec4 x, float B, float C)
+{
+ // https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters
+ vec2 a = x.yz; // components in [0,1]
+ vec2 b = x.xw; // components in [1,2]
+ vec2 a2 = a*a;
+ vec2 b2 = b*b;
+ a = (2.0-1.5*B-1.0*C)*a*a2 + (-3.0+2.0*B+C)*a2 + (1.0-(1.0/3.0)*B);
+ b = ((-1.0/6.0)*B-C)*b*b2 + (B+5.0*C)*b2 + (-2.0*B-8.0*C)*b + ((4.0/3.0)*B+4.0*C);
+ return vec4(b.x,a.x,a.y,b.y);
+}
+
+vec4 x_coeffs(vec4 x, float pos_x)
+{
+ if (u_interp.x < 0.5) { // box
+ float wid = length(vec2(dFdx(pos_x),dFdy(pos_x)));
+ float dx = clamp((0.5 + 0.5*wid - x.y)/wid, 0.0, 1.0);
+ return vec4(0.0,dx,1.0-dx,0.0);
+ } else if (u_interp.x < 1.5) { // linear
+ return vec4(0.0, 1.0-x.y, 1.0-x.z, 0.0);
+ } else if (u_interp.x < 2.5) { // Lanczos
+ // Prevent division by zero.
+ vec4 coeffs = FIX(PI * x);
+ // Lanczos2 kernel.
+ coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
+ // Normalize.
+ coeffs /= dot(coeffs, vec4_splat(1.0));
+ return coeffs;
+ } else if (u_interp.x < 3.5) { // Catmull-Rom
+ return cubic(x,0.0,0.5);
+ } else if (u_interp.x < 4.5) { // Mitchell-Netravali
+ return cubic(x,1.0/3.0,1.0/3.0);
+ } else if (u_interp.x < 5.5) { // B-spline
+ return cubic(x,1.0,0.0);
+ }
+}
+
+vec4 sample_scanline(vec2 xy, vec4 coeffs, float onex)
+{
+ // Calculate the effective colour of the given
+ // scanline at the horizontal location of the current pixel,
+ // using the Lanczos coefficients.
+ vec4 col = clamp(TEX2D(xy + vec2(-onex, 0.0))*coeffs.x +
+ TEX2D(xy)*coeffs.y +
+ TEX2D(xy +vec2(onex, 0.0))*coeffs.z +
+ TEX2D(xy + vec2(2.0 * onex, 0.0))*coeffs.w , 0.0, 1.0);
+ return col;
+}
+
void main()
{
// Here's a helpful diagram to keep in mind while trying to
@@ -173,33 +230,13 @@ void main()
// Snap to the center of the underlying texel.
xy = (floor(ratio_scale) + vec2_splat(0.5)) / u_tex_size0.xy;
- // Calculate Lanczos scaling coefficients describing the effect
+ // Calculate scaling coefficients describing the effect
// of various neighbour texels in a scanline on the current
// pixel.
- vec4 coeffs = PI * vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
-
- // Prevent division by zero.
- coeffs = FIX(coeffs);
-
- // Lanczos2 kernel.
- coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);
-
- // Normalize.
- coeffs /= dot(coeffs, vec4_splat(1.0));
-
- // Calculate the effective colour of the current and next
- // scanlines at the horizontal location of the current pixel,
- // 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);
-
- 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);
+ vec4 coeffs = x_coeffs(vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x), ratio_scale.x);
+ vec4 col = sample_scanline(xy, coeffs, v_one.x);
+ vec4 col2 = sample_scanline(xy + vec2(0.0, v_one.y), coeffs, v_one.x);
#ifndef LINEAR_PROCESSING
col = pow(col , vec4_splat(CRTgamma.x));
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc
new file mode 100644
index 00000000000..2f48bbac321
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_lowpass.sc
@@ -0,0 +1,37 @@
+$input v_texCoord, v_lpcoeffs1, v_lpcoeffs2
+
+#include "common.sh"
+
+SAMPLER2D(s_screen, 0);
+
+uniform vec4 u_tex_size0;
+
+vec3 sample_screen(vec2 c)
+{
+ vec2 underscan = step(0.0,c) * step(0.0,vec2_splat(1.0)-c);
+ vec3 col = texture2D(s_screen, c).rgb * vec3_splat(underscan.x*underscan.y);
+ return col;
+}
+
+void main()
+{
+ float onex = 1.0/u_tex_size0.x;
+
+ vec3 sum = sample_screen(v_texCoord) * vec3_splat(v_lpcoeffs1.x);
+ sum +=sample_screen(v_texCoord+vec2(-1.0*onex,0.0))*vec3_splat(v_lpcoeffs1.y);
+ sum +=sample_screen(v_texCoord+vec2( 1.0*onex,0.0))*vec3_splat(v_lpcoeffs1.y);
+ sum +=sample_screen(v_texCoord+vec2(-2.0*onex,0.0))*vec3_splat(v_lpcoeffs1.z);
+ sum +=sample_screen(v_texCoord+vec2( 2.0*onex,0.0))*vec3_splat(v_lpcoeffs1.z);
+ sum +=sample_screen(v_texCoord+vec2(-3.0*onex,0.0))*vec3_splat(v_lpcoeffs1.w);
+ sum +=sample_screen(v_texCoord+vec2( 3.0*onex,0.0))*vec3_splat(v_lpcoeffs1.w);
+ sum +=sample_screen(v_texCoord+vec2(-4.0*onex,0.0))*vec3_splat(v_lpcoeffs2.x);
+ sum +=sample_screen(v_texCoord+vec2( 4.0*onex,0.0))*vec3_splat(v_lpcoeffs2.x);
+ sum +=sample_screen(v_texCoord+vec2(-5.0*onex,0.0))*vec3_splat(v_lpcoeffs2.y);
+ sum +=sample_screen(v_texCoord+vec2( 5.0*onex,0.0))*vec3_splat(v_lpcoeffs2.y);
+ sum +=sample_screen(v_texCoord+vec2(-6.0*onex,0.0))*vec3_splat(v_lpcoeffs2.z);
+ sum +=sample_screen(v_texCoord+vec2( 6.0*onex,0.0))*vec3_splat(v_lpcoeffs2.z);
+ sum +=sample_screen(v_texCoord+vec2(-7.0*onex,0.0))*vec3_splat(v_lpcoeffs2.w);
+ sum +=sample_screen(v_texCoord+vec2( 7.0*onex,0.0))*vec3_splat(v_lpcoeffs2.w);
+
+ gl_FragColor = vec4( sum, 1.0 );
+}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc
index 507bbd05064..c45fb8f883f 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_apply.sc
@@ -7,8 +7,22 @@ SAMPLER2D(s_phosphor, 1);
uniform vec4 u_phosphor_power;
uniform vec4 u_phosphor_amplitude;
+uniform vec4 u_phosphor_cutoff;
uniform vec4 u_gamma;
+float decay(float t)
+{
+ // transition smoothly from power to linear at t=t1
+ float t1 = u_phosphor_cutoff.x / ( 1.0 + u_gamma.x / u_phosphor_power.x );
+ float tpow = pow( clamp(t,0.0,t1), -u_phosphor_power.x );
+ // smoothly fade out for t in [t1,cutoff]: linear in gamma space
+ t = clamp(t, 0.0, u_phosphor_cutoff.x);
+ float y = ( t < t1
+ ? tpow
+ : tpow * pow( ( u_phosphor_cutoff.x - t ) / ( u_phosphor_cutoff.x - t1 ), u_gamma.x ) );
+ return y;
+}
+
void main()
{
vec4 screen = texture2D(s_screen, v_texCoord);
@@ -20,7 +34,7 @@ void main()
// encode the upper 2 bits of the time elapsed in the lower 2 bits of b
float t = 255.0*phosphor.a + fract(phosphor.b*255.0/4.0)*1024.0;
- cphos *= vec3_splat( u_phosphor_amplitude.x * pow(t,-u_phosphor_power.x) );
+ cphos *= vec3_splat( u_phosphor_amplitude.x * decay(t) );
vec3 col = pow(cscrn + cphos, vec3_splat(1.0/u_gamma.x));
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc
index 9057fbdbf83..824a008e96b 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/fs_phosphor_update.sc
@@ -7,8 +7,22 @@ SAMPLER2D(s_phosphor, 1);
uniform vec4 u_phosphor_power;
uniform vec4 u_phosphor_amplitude;
+uniform vec4 u_phosphor_cutoff;
uniform vec4 u_gamma;
+float decay(float t)
+{
+ // transition smoothly from power to linear at t=t1
+ float t1 = u_phosphor_cutoff.x / ( 1.0 + u_gamma.x / u_phosphor_power.x );
+ float tpow = pow( clamp(t,0.0,t1), -u_phosphor_power.x );
+ // smoothly fade out for t in [t1,cutoff]: linear in gamma space
+ t = clamp(t, 0.0, u_phosphor_cutoff.x);
+ float y = ( t < t1
+ ? tpow
+ : tpow * pow( ( u_phosphor_cutoff.x - t ) / ( u_phosphor_cutoff.x - t1 ), u_gamma.x ) );
+ return y;
+}
+
void main()
{
vec4 screen = texture2D(s_screen, v_texCoord);
@@ -21,11 +35,11 @@ void main()
// encode the upper 2 bits of the time elapsed in the lower 2 bits of b
float t = 1.0 + 255.0*phosphor.a + fract(phosphor.b*255.0/4.0)*1024.0;
- bphos = ( t > 1023.0 ? 0.0 : bphos*pow(t,-u_phosphor_power.x) );
+ bphos = ( t > 1023.0 ? 0.0 : bphos * decay(t) );
- gl_FragColor = ( bscrn >= bphos ?
- vec4(screen.rg,floor(screen.b*255.0/4.0)*4.0/255.0,1.0/255.0)
- : vec4(phosphor.rg,
- (floor(phosphor.b*255.0/4.0)*4.0 + floor(t/256.0))/255.0,
- fract(t/256.0)*256.0/255.0 ) );
+ gl_FragColor = ( bscrn >= bphos
+ ? vec4(screen.rg,floor(screen.b*255.0/4.0)*4.0/255.0,1.0/255.0)
+ : vec4(phosphor.rg,
+ (floor(phosphor.b*255.0/4.0)*4.0 + floor(t/256.0))/255.0,
+ fract(t/256.0)*256.0/255.0 ) );
}
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc
index 8ba2cef453e..6b1e8e2bf66 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/varying.def.sc
@@ -4,6 +4,8 @@ vec2 v_sinangle : TEXCOORD2 = vec2(0.0,0.0);
vec2 v_cosangle : TEXCOORD3 = vec2(0.0,0.0);
vec2 v_one : TEXCOORD4 = vec2(0.0,0.0);
vec4 v_coeffs : TEXCOORD5 = vec4(0.0,0.0,0.0,0.0);
+vec4 v_lpcoeffs1: TEXCOORD6 = vec4(0.0,0.0,0.0,0.0);
+vec4 v_lpcoeffs2: TEXCOORD7 = vec4(0.0,0.0,0.0,0.0);
vec3 a_position : POSITION;
vec4 a_color0 : COLOR0;
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc
new file mode 100644
index 00000000000..4d948a63a89
--- /dev/null
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_lowpass.sc
@@ -0,0 +1,49 @@
+$input a_position, a_texcoord0, a_color0
+$output v_texCoord, v_lpcoeffs1, v_lpcoeffs2
+
+#include "common.sh"
+
+uniform vec4 u_tex_size0;
+uniform vec4 u_lowpass_cutoff;
+uniform vec4 u_lowpass_width;
+
+void main()
+{
+ // Do the standard vertex processing.
+ gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
+ v_texCoord = a_texcoord0;
+
+ // interpret the cutoff and width as target resolutions in pixels per scanline
+ // include factor of 1/2 because max frequency at given resolution is Nyquist
+ float a = 0.5 * u_lowpass_cutoff.x / u_tex_size0.x;
+ float b = 0.5 * u_lowpass_width.x / u_tex_size0.x;
+ float w0 = (a-0.5*b);
+ float w1 = (a+0.5*b);
+
+ float two_pi = 6.283185307179586;
+ vec3 n1 = vec3(1.0,2.0,3.0);
+ vec4 n2 = vec4(4.0,5.0,6.0,7.0);
+
+ // target frequency response:
+ // 1 for w < w0
+ // 0 for w > w1
+ // linearly decreasing for w0 < w < w1
+ // this will be approximated by including the lowest Fourier modes
+ if (w0 > 0.5) { // no filtering
+ v_lpcoeffs1 = vec4(1.0,0.0,0.0,0.0);
+ v_lpcoeffs2 = vec4_splat(0.0);
+ } else if (w1 > 0.5) { // don't reach zero
+ // here the target has a nonzero response at the Nyquist frequency
+ v_lpcoeffs1.x = w1 + w0 - (w1 - 0.5)*(w1 - 0.5)/(w1 - w0);
+ v_lpcoeffs1.yzw = 2.0 / ( two_pi*two_pi*(w1-w0)*n1*n1 ) * ( cos(two_pi*w0*n1) - cos(two_pi*0.5*n1) );
+ v_lpcoeffs2 = 2.0 / ( two_pi*two_pi*(w1-w0)*n2*n2 ) * ( cos(two_pi*w0*n2) - cos(two_pi*0.5*n2) );
+ } else if (w1 == w0) { // sharp cutoff
+ v_lpcoeffs1.x = 2.0 * w0;
+ v_lpcoeffs1.yzw = 2.0 / ( two_pi * n1 ) * sin(two_pi*w0*n1);
+ v_lpcoeffs2 = 2.0 / ( two_pi * n2 ) * sin(two_pi*w0*n2);
+ } else {
+ v_lpcoeffs1.x = w1 + w0;
+ v_lpcoeffs1.yzw = 2.0 / ( two_pi*two_pi*(w1-w0)*n1*n1 ) * ( cos(two_pi*w0*n1) - cos(two_pi*w1*n1) );
+ v_lpcoeffs2 = 2.0 / ( two_pi*two_pi*(w1-w0)*n2*n2 ) * ( cos(two_pi*w0*n2) - cos(two_pi*w1*n2) );
+ }
+}