diff options
| author | 2021-03-19 16:38:07 +0100 | |
|---|---|---|
| committer | 2021-03-20 02:38:07 +1100 | |
| commit | 931f85ee2709b8630c571c53be10e280fd4ed3bb (patch) | |
| tree | 90a3df91f3720265678d780b99058ce6fcac006a | |
| parent | f15e301557c99f7e763dd933c0d47fa349bbd229 (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.
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 Binary files differindex 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 diff --git a/bgfx/shaders/essl/chains/crt-geom/fs_crt-geom.bin b/bgfx/shaders/essl/chains/crt-geom/fs_crt-geom.bin Binary files differindex 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 diff --git a/bgfx/shaders/essl/chains/crt-geom/fs_lowpass.bin b/bgfx/shaders/essl/chains/crt-geom/fs_lowpass.bin Binary files differnew file mode 100644 index 00000000000..e390298a362 --- /dev/null +++ b/bgfx/shaders/essl/chains/crt-geom/fs_lowpass.bin diff --git a/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_apply.bin b/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_apply.bin Binary files differindex 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 diff --git a/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_update.bin b/bgfx/shaders/essl/chains/crt-geom/fs_phosphor_update.bin Binary files differindex 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 diff --git a/bgfx/shaders/essl/chains/crt-geom/vs_lowpass.bin b/bgfx/shaders/essl/chains/crt-geom/vs_lowpass.bin Binary files differnew file mode 100644 index 00000000000..a29c3521088 --- /dev/null +++ b/bgfx/shaders/essl/chains/crt-geom/vs_lowpass.bin 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 Binary files differindex 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 diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_crt-geom.bin Binary files differindex 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 diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_lowpass.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_lowpass.bin Binary files differnew file mode 100644 index 00000000000..ca184aef7dc --- /dev/null +++ b/bgfx/shaders/glsl/chains/crt-geom/fs_lowpass.bin diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_apply.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_apply.bin Binary files differindex 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 diff --git a/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_update.bin b/bgfx/shaders/glsl/chains/crt-geom/fs_phosphor_update.bin Binary files differindex 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 diff --git a/bgfx/shaders/glsl/chains/crt-geom/vs_lowpass.bin b/bgfx/shaders/glsl/chains/crt-geom/vs_lowpass.bin Binary files differnew file mode 100644 index 00000000000..88ebb214e32 --- /dev/null +++ b/bgfx/shaders/glsl/chains/crt-geom/vs_lowpass.bin 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 Binary files differindex 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 diff --git a/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom.bin b/bgfx/shaders/metal/chains/crt-geom/fs_crt-geom.bin Binary files differindex 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 diff --git a/bgfx/shaders/metal/chains/crt-geom/fs_lowpass.bin b/bgfx/shaders/metal/chains/crt-geom/fs_lowpass.bin Binary files differnew file mode 100644 index 00000000000..40b8ff0bc04 --- /dev/null +++ b/bgfx/shaders/metal/chains/crt-geom/fs_lowpass.bin diff --git a/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_apply.bin b/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_apply.bin Binary files differindex 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 diff --git a/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_update.bin b/bgfx/shaders/metal/chains/crt-geom/fs_phosphor_update.bin Binary files differindex 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 diff --git a/bgfx/shaders/metal/chains/crt-geom/vs_lowpass.bin b/bgfx/shaders/metal/chains/crt-geom/vs_lowpass.bin Binary files differnew file mode 100644 index 00000000000..7f16cc81cbc --- /dev/null +++ b/bgfx/shaders/metal/chains/crt-geom/vs_lowpass.bin 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 Binary files differindex 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 diff --git a/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom.bin b/bgfx/shaders/spirv/chains/crt-geom/fs_crt-geom.bin Binary files differindex 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 diff --git a/bgfx/shaders/spirv/chains/crt-geom/fs_lowpass.bin b/bgfx/shaders/spirv/chains/crt-geom/fs_lowpass.bin Binary files differnew file mode 100644 index 00000000000..4f8f994820d --- /dev/null +++ b/bgfx/shaders/spirv/chains/crt-geom/fs_lowpass.bin diff --git a/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_apply.bin b/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_apply.bin Binary files differindex 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 diff --git a/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_update.bin b/bgfx/shaders/spirv/chains/crt-geom/fs_phosphor_update.bin Binary files differindex 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 diff --git a/bgfx/shaders/spirv/chains/crt-geom/vs_lowpass.bin b/bgfx/shaders/spirv/chains/crt-geom/vs_lowpass.bin Binary files differnew file mode 100644 index 00000000000..318f409621b --- /dev/null +++ b/bgfx/shaders/spirv/chains/crt-geom/vs_lowpass.bin 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) ); + } +} |
