From 523aceef44b3e3ee54ef2dce83ab7446c4e05e13 Mon Sep 17 00:00:00 2001 From: hunterk Date: Wed, 8 Mar 2017 10:32:29 -0600 Subject: [PATCH] rework lottes-multipass to be nicer/slower; old version is moved to 'old' subdir --- .../crt-lottes-multipass/bloompass.slang | 343 +++++++++++++++++ .../crt-lottes-multipass-fast-and-ugly.slang | 225 +++++++++++ .../crt-lottes-multipass-fast-and-ugly.slangp | 25 ++ .../{ => old}/crt-lottes-multipass-glow.slang | 2 +- .../old/crt-lottes-multipass-old.slangp | 55 +++ .../{ => old}/crt-lottes-multipass.slang | 2 +- .../crt-lottes-multipass/old/horz3.slang | 77 ++++ .../{ => old}/horz3minus1.slang | 0 .../{ => old}/horz3plus1.slang | 0 .../{ => old}/horz5.slang | 0 .../{ => old}/horz5minus2.slang | 0 .../{ => old}/horz5plus2.slang | 0 .../{ => old}/horz7.slang | 0 .../{ => old}/horz7minus1.slang | 0 .../{ => old}/horz7plus1.slang | 0 .../{ => old}/linearize.slang | 0 .../{ => old}/threshold.slang | 0 .../crt-lottes-multipass/scanpass.slang | 359 ++++++++++++++++++ presets/bigblur-lottes-multipass.slangp | 20 +- presets/crt-lottes-trinitron.slangp | 20 +- 20 files changed, 1106 insertions(+), 22 deletions(-) create mode 100644 crt/shaders/crt-lottes-multipass/bloompass.slang create mode 100644 crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-fast-and-ugly.slang create mode 100644 crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-fast-and-ugly.slangp rename crt/shaders/crt-lottes-multipass/{ => old}/crt-lottes-multipass-glow.slang (99%) create mode 100644 crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-old.slangp rename crt/shaders/crt-lottes-multipass/{ => old}/crt-lottes-multipass.slang (99%) create mode 100644 crt/shaders/crt-lottes-multipass/old/horz3.slang rename crt/shaders/crt-lottes-multipass/{ => old}/horz3minus1.slang (100%) rename crt/shaders/crt-lottes-multipass/{ => old}/horz3plus1.slang (100%) rename crt/shaders/crt-lottes-multipass/{ => old}/horz5.slang (100%) rename crt/shaders/crt-lottes-multipass/{ => old}/horz5minus2.slang (100%) rename crt/shaders/crt-lottes-multipass/{ => old}/horz5plus2.slang (100%) rename crt/shaders/crt-lottes-multipass/{ => old}/horz7.slang (100%) rename crt/shaders/crt-lottes-multipass/{ => old}/horz7minus1.slang (100%) rename crt/shaders/crt-lottes-multipass/{ => old}/horz7plus1.slang (100%) rename crt/shaders/crt-lottes-multipass/{ => old}/linearize.slang (100%) rename crt/shaders/crt-lottes-multipass/{ => old}/threshold.slang (100%) create mode 100644 crt/shaders/crt-lottes-multipass/scanpass.slang diff --git a/crt/shaders/crt-lottes-multipass/bloompass.slang b/crt/shaders/crt-lottes-multipass/bloompass.slang new file mode 100644 index 0000000..7bff9ca --- /dev/null +++ b/crt/shaders/crt-lottes-multipass/bloompass.slang @@ -0,0 +1,343 @@ +#version 450 + +layout(push_constant) uniform Push +{ + float hardScan; + float hardPix; + float warpX; + float warpY; + float maskDark; + float maskLight; + float scaleInLinearGamma; + float shadowMask; + float brightBoost; + float hardBloomScan; + float hardBloomPix; + float bloomAmount; + float shape; +} param; + +#pragma parameter hardScan "hardScan" -8.0 -20.0 0.0 1.0 +#pragma parameter hardPix "hardPix" -3.0 -20.0 0.0 1.0 +#pragma parameter warpX "warpX" 0.031 0.0 0.125 0.01 +#pragma parameter warpY "warpY" 0.041 0.0 0.125 0.01 +#pragma parameter maskDark "maskDark" 0.5 0.0 2.0 0.1 +#pragma parameter maskLight "maskLight" 1.5 0.0 2.0 0.1 +#pragma parameter scaleInLinearGamma "scaleInLinearGamma" 1.0 0.0 1.0 1.0 +#pragma parameter shadowMask "shadowMask" 3.0 0.0 4.0 1.0 +#pragma parameter brightBoost "brightness boost" 1.0 0.0 2.0 0.05 +#pragma parameter hardBloomPix "bloom-x soft" -1.5 -2.0 -0.5 0.1 +#pragma parameter hardBloomScan "bloom-y soft" -2.0 -4.0 -1.0 0.1 +#pragma parameter bloomAmount "bloom amount" 0.4 0.0 1.0 0.05 +#pragma parameter shape "filter kernel shape" 2.0 0.0 10.0 0.05 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +// PUBLIC DOMAIN CRT STYLED SCAN-LINE SHADER +// +// by Timothy Lottes +// +// This is more along the style of a really good CGA arcade monitor. +// With RGB inputs instead of NTSC. +// The shadow mask example has the mask rotated 90 degrees for less chromatic aberration. +// +// Left it unoptimized to show the theory behind the algorithm. +// +// It is an example what I personally would want as a display option for pixel art games. +// Please take and use, change, or whatever. + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 FragCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D Original; + +//Uncomment to reduce instructions with simpler linearization +//(fixes HD3000 Sandy Bridge IGP) +//#define SIMPLE_LINEAR_GAMMA +#define DO_BLOOM 1 + +// ------------- // + +// sRGB to Linear. +// Assuming using sRGB typed textures this should not be needed. +#ifdef SIMPLE_LINEAR_GAMMA +float ToLinear1(float c) +{ + return c; +} +vec3 ToLinear(vec3 c) +{ + return c; +} +vec3 ToSrgb(vec3 c) +{ + return pow(c, vec3(1.0 / 2.2)); +} +#else +float ToLinear1(float c) +{ + if (param.scaleInLinearGamma == 0) + return c; + + return(c<=0.04045) ? c/12.92 : pow((c + 0.055)/1.055, 2.4); +} + +vec3 ToLinear(vec3 c) +{ + if (param.scaleInLinearGamma==0) + return c; + + return vec3(ToLinear1(c.r), ToLinear1(c.g), ToLinear1(c.b)); +} + +// Linear to sRGB. +// Assuming using sRGB typed textures this should not be needed. +float ToSrgb1(float c) +{ + if (param.scaleInLinearGamma == 0) + return c; + + return(c<0.0031308 ? c*12.92 : 1.055*pow(c, 0.41666) - 0.055); +} + +vec3 ToSrgb(vec3 c) +{ + if (param.scaleInLinearGamma == 0) + return c; + + return vec3(ToSrgb1(c.r), ToSrgb1(c.g), ToSrgb1(c.b)); +} +#endif + + + +// Nearest emulated sample given floating point position and texel offset. +// Also zero's off screen. +vec3 Fetch(vec2 pos,vec2 off){ + pos=(floor(pos*global.SourceSize.xy+off)+vec2(0.5,0.5))/global.SourceSize.xy; +#ifdef SIMPLE_LINEAR_GAMMA + return ToLinear(param.brightBoost * pow(texture(Original,pos.xy).rgb, vec3(2.2))); +#else + return ToLinear(param.brightBoost * texture(Original,pos.xy).rgb); +#endif +} + +// Distance in emulated pixels to nearest texel. +vec2 Dist(vec2 pos) +{ + pos = pos*global.SourceSize.xy; + + return -((pos - floor(pos)) - vec2(0.5)); +} + +// 1D Gaussian. +float Gaus(float pos, float scale) +{ + return exp2(scale*pow(abs(pos), param.shape)); +} + +// 3-tap Gaussian filter along horz line. +vec3 Horz3(vec2 pos, float off) +{ + vec3 b = Fetch(pos, vec2(-1.0, off)); + vec3 c = Fetch(pos, vec2( 0.0, off)); + vec3 d = Fetch(pos, vec2( 1.0, off)); + float dst = Dist(pos).x; + + // Convert distance to weight. + float scale = param.hardPix; + float wb = Gaus(dst-1.0,scale); + float wc = Gaus(dst+0.0,scale); + float wd = Gaus(dst+1.0,scale); + + // Return filtered sample. + return (b*wb+c*wc+d*wd)/(wb+wc+wd); +} + +// 5-tap Gaussian filter along horz line. +vec3 Horz5(vec2 pos,float off){ + vec3 a = Fetch(pos,vec2(-2.0, off)); + vec3 b = Fetch(pos,vec2(-1.0, off)); + vec3 c = Fetch(pos,vec2( 0.0, off)); + vec3 d = Fetch(pos,vec2( 1.0, off)); + vec3 e = Fetch(pos,vec2( 2.0, off)); + + float dst = Dist(pos).x; + // Convert distance to weight. + float scale = param.hardPix; + float wa = Gaus(dst - 2.0, scale); + float wb = Gaus(dst - 1.0, scale); + float wc = Gaus(dst + 0.0, scale); + float wd = Gaus(dst + 1.0, scale); + float we = Gaus(dst + 2.0, scale); + + // Return filtered sample. + return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we); +} + +// 7-tap Gaussian filter along horz line. +vec3 Horz7(vec2 pos,float off) +{ + vec3 a = Fetch(pos, vec2(-3.0, off)); + vec3 b = Fetch(pos, vec2(-2.0, off)); + vec3 c = Fetch(pos, vec2(-1.0, off)); + vec3 d = Fetch(pos, vec2( 0.0, off)); + vec3 e = Fetch(pos, vec2( 1.0, off)); + vec3 f = Fetch(pos, vec2( 2.0, off)); + vec3 g = Fetch(pos, vec2( 3.0, off)); + + float dst = Dist(pos).x; + // Convert distance to weight. + float scale = param.hardBloomPix; + float wa = Gaus(dst - 3.0, scale); + float wb = Gaus(dst - 2.0, scale); + float wc = Gaus(dst - 1.0, scale); + float wd = Gaus(dst + 0.0, scale); + float we = Gaus(dst + 1.0, scale); + float wf = Gaus(dst + 2.0, scale); + float wg = Gaus(dst + 3.0, scale); + + // Return filtered sample. + return (a*wa+b*wb+c*wc+d*wd+e*we+f*wf+g*wg)/(wa+wb+wc+wd+we+wf+wg); +} + +// Return scanline weight. +float Scan(vec2 pos, float off) +{ + float dst = Dist(pos).y; + + return Gaus(dst + off, param.hardScan); +} + +// Return scanline weight for bloom. +float BloomScan(vec2 pos, float off) +{ + float dst = Dist(pos).y; + + return Gaus(dst + off, param.hardBloomScan); +} + +// Allow nearest three lines to effect pixel. +vec3 Tri(vec2 pos) +{ + vec3 a = Horz3(pos,-1.0); + vec3 b = Horz5(pos, 0.0); + vec3 c = Horz3(pos, 1.0); + + float wa = Scan(pos,-1.0); + float wb = Scan(pos, 0.0); + float wc = Scan(pos, 1.0); + + return a*wa + b*wb + c*wc; +} + +// Small bloom. +vec3 Bloom(vec2 pos) +{ + vec3 a = Horz5(pos,-2.0); + vec3 b = Horz7(pos,-1.0); + vec3 c = Horz7(pos, 0.0); + vec3 d = Horz7(pos, 1.0); + vec3 e = Horz5(pos, 2.0); + + float wa = BloomScan(pos,-2.0); + float wb = BloomScan(pos,-1.0); + float wc = BloomScan(pos, 0.0); + float wd = BloomScan(pos, 1.0); + float we = BloomScan(pos, 2.0); + + return a*wa+b*wb+c*wc+d*wd+e*we; +} + +// Distortion of scanlines, and end of screen alpha. +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos *= vec2(1.0 + (pos.y*pos.y)*param.warpX, 1.0 + (pos.x*pos.x)*param.warpY); + + return pos*0.5 + 0.5; +} + +// Shadow mask. +vec3 Mask(vec2 pos) +{ + vec3 mask = vec3(param.maskDark, param.maskDark, param.maskDark); + + // Very compressed TV style shadow mask. + if (param.shadowMask == 1.0) + { + float line = param.maskLight; + float odd = 0.0; + + if (fract(pos.x*0.166666666) < 0.5) odd = 1.0; + if (fract((pos.y + odd) * 0.5) < 0.5) line = param.maskDark; + + pos.x = fract(pos.x*0.333333333); + + if (pos.x < 0.333) mask.r = param.maskLight; + else if (pos.x < 0.666) mask.g = param.maskLight; + else mask.b = param.maskLight; + mask*=line; + } + + // Aperture-grille. + else if (param.shadowMask == 2.0) + { + pos.x = fract(pos.x*0.333333333); + + if (pos.x < 0.333) mask.r = param.maskLight; + else if (pos.x < 0.666) mask.g = param.maskLight; + else mask.b = param.maskLight; + } + + // Stretched VGA style shadow mask (same as prior shaders). + else if (param.shadowMask == 3.0) + { + pos.x += pos.y*3.0; + pos.x = fract(pos.x*0.166666666); + + if (pos.x < 0.333) mask.r = param.maskLight; + else if (pos.x < 0.666) mask.g = param.maskLight; + else mask.b = param.maskLight; + } + + // VGA style shadow mask. + else if (param.shadowMask == 4.0) + { + pos.xy = floor(pos.xy*vec2(1.0, 0.5)); + pos.x += pos.y*3.0; + pos.x = fract(pos.x*0.166666666); + + if (pos.x < 0.333) mask.r = param.maskLight; + else if (pos.x < 0.666) mask.g = param.maskLight; + else mask.b = param.maskLight; + } + + return mask; +} + +void main() +{ + vec2 pos = vTexCoord; + + FragColor = vec4(Bloom(pos)*param.bloomAmount, 1.0); +} diff --git a/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-fast-and-ugly.slang b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-fast-and-ugly.slang new file mode 100644 index 0000000..f300bfc --- /dev/null +++ b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-fast-and-ugly.slang @@ -0,0 +1,225 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; + float hardScan; + float warpX; + float warpY; + float maskDark; + float maskLight; + float shadowMask; + float bloomAmount; + float hardBloomScan; + float shape; +} params; + +#pragma parameter hardScan "hardScan" -8.0 -20.0 0.0 1.0 +#pragma parameter warpX "warpX" 0.031 0.0 0.125 0.01 +#pragma parameter warpY "warpY" 0.041 0.0 0.125 0.01 +#pragma parameter maskDark "maskDark" 0.5 0.0 2.0 0.1 +#pragma parameter maskLight "maskLight" 1.5 0.0 2.0 0.1 +#pragma parameter shadowMask "shadowMask" 3.0 0.0 4.0 1.0 +#pragma parameter hardBloomScan "bloom-y soft" -2.0 -4.0 -1.0 0.1 +#pragma parameter bloomAmount "bloom amount" 0.15 0.0 1.0 0.05 +#pragma parameter shape "filter kernel shape" 2.0 0.0 10.0 0.05 + +#define DO_BLOOM + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +// PUBLIC DOMAIN CRT STYLED SCAN-LINE SHADER +// +// by Timothy Lottes +// +// This is more along the style of a really good CGA arcade monitor. +// With RGB inputs instead of NTSC. +// The shadow mask example has the mask rotated 90 degrees for less chromatic aberration. +// +// Left it unoptimized to show the theory behind the algorithm. +// +// It is an example what I personally would want as a display option for pixel art games. +// Please take and use, change, or whatever. + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 FragCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D horz3; +layout(set = 0, binding = 3) uniform sampler2D horz5; +layout(set = 0, binding = 4) uniform sampler2D horz7; + +// Linear to sRGB. +// Assuming using sRGB typed textures this should not be needed. +float ToSrgb1(float c) +{ + return(c < 0.0031308 ? c*12.92 : 1.055*pow(c, 0.41666) - 0.055); +} + +vec3 ToSrgb(vec3 c) +{ + return vec3(ToSrgb1(c.r), ToSrgb1(c.g), ToSrgb1(c.b)); +} + +// Distance in emulated pixels to nearest texel. +vec2 Dist(vec2 pos) +{ + pos = pos*params.SourceSize.xy; + + return -((pos - floor(pos)) - vec2(0.5)); +} + +// 1D Gaussian. +float Gaus(float pos, float scale) +{ + return exp2(scale*pow(abs(pos), params.shape)); +} + +// Return scanline weight. +float Scan(vec2 pos, float off) +{ + float dst = Dist(pos).y; + + return Gaus(dst + off, params.hardScan); +} + +// Return scanline weight for bloom. +float BloomScan(vec2 pos, float off) +{ + float dst = Dist(pos).y; + + return Gaus(dst + off, params.hardBloomScan); +} + +// Allow nearest three lines to effect pixel. +vec3 Tri(vec2 pos) +{ + vec3 a = textureOffset(horz3, pos, ivec2(1, 0)).rgb;//Horz3(pos,-1.0); + vec3 b = texture(horz5, pos).rgb;//Horz5(pos, 0.0); + vec3 c = textureOffset(horz3, pos, ivec2(-1, 0)).rgb;//Horz3(pos, 1.0); + + float wa = Scan(pos, -1.0); + float wb = Scan(pos, 0.0); + float wc = Scan(pos, 1.0); + + return a*wa+b*wb+c*wc; +} + +// Small bloom. +vec3 Bloom(vec2 pos) +{ + vec3 a = textureOffset(horz5, pos, ivec2(-2, 0)).rgb;//Horz5(pos,-2.0); + vec3 b = textureOffset(horz7, pos, ivec2(-1, 0)).rgb;//Horz7(pos,-1.0); + vec3 c = texture(horz7, pos).rgb;//Horz7(pos, 0.0); + vec3 d = textureOffset(horz7, pos, ivec2(1, 0)).rgb;//Horz7(pos, 1.0); + vec3 e = textureOffset(horz5, pos, ivec2(2, 0)).rgb;//Horz5(pos, 2.0); + + float wa = BloomScan(pos, -2.0); + float wb = BloomScan(pos, -1.0); + float wc = BloomScan(pos, 0.0); + float wd = BloomScan(pos, 1.0); + float we = BloomScan(pos, 2.0); + + return a*wa+b*wb+c*wc+d*wd+e*we; +} + +// Distortion of scanlines, and end of screen alpha. +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos *= vec2(1.0 + (pos.y*pos.y)*params.warpX, 1.0 + (pos.x*pos.x)*params.warpY); + + return pos*0.5 + 0.5; +} + +// Shadow mask. +vec3 Mask(vec2 pos) +{ + vec3 mask = vec3(params.maskDark, params.maskDark, params.maskDark); + + // Very compressed TV style shadow mask. + if (params.shadowMask == 1.0) + { + float line = params.maskLight; + float odd = 0.0; + + if (fract(pos.x*0.166666666) < 0.5) odd = 1.0; + if (fract((pos.y + odd) * 0.5) < 0.5) line = params.maskDark; + + pos.x = fract(pos.x*0.333333333); + + if (pos.x < 0.333) mask.r = params.maskLight; + else if (pos.x < 0.666) mask.g = params.maskLight; + else mask.b = params.maskLight; + mask*=line; + } + + // Aperture-grille. + else if (params.shadowMask == 2.0) + { + pos.x = fract(pos.x*0.333333333); + + if (pos.x < 0.333) mask.r = params.maskLight; + else if (pos.x < 0.666) mask.g = params.maskLight; + else mask.b = params.maskLight; + } + + // Stretched VGA style shadow mask (same as prior shaders). + else if (params.shadowMask == 3.0) + { + pos.x += pos.y*3.0; + pos.x = fract(pos.x*0.166666666); + + if (pos.x < 0.333) mask.r = params.maskLight; + else if (pos.x < 0.666) mask.g = params.maskLight; + else mask.b = params.maskLight; + } + + // VGA style shadow mask. + else if (params.shadowMask == 4.0) + { + pos.xy = floor(pos.xy*vec2(1.0, 0.5)); + pos.x += pos.y*3.0; + pos.x = fract(pos.x*0.166666666); + + if (pos.x < 0.333) mask.r = params.maskLight; + else if (pos.x < 0.666) mask.g = params.maskLight; + else mask.b = params.maskLight; + } + + return mask; +} + +void main() +{ + vec2 pos = Warp(vTexCoord); + vec3 outColor = Tri(pos); + + + + if (params.shadowMask > 0.0) + outColor.rgb *= Mask(vTexCoord.xy / params.OutputSize.zw * 1.000001); + + #ifdef DO_BLOOM + //Add Bloom + outColor.rgb += Bloom(pos)*params.bloomAmount; +#endif + + FragColor = vec4(ToSrgb(outColor.rgb), 1.0); +} diff --git a/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-fast-and-ugly.slangp b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-fast-and-ugly.slangp new file mode 100644 index 0000000..23b87c0 --- /dev/null +++ b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-fast-and-ugly.slangp @@ -0,0 +1,25 @@ +shaders = 5 + +shader0 = linearize.slang +srgb_framebuffer0 = true +alias0 = "REFERENCE" + +shader1 = horz3.slang +srgb_framebuffer1 = true +scale_type1 = source +filter_linear1 = true +alias1 = horz3 + +shader2 = horz5.slang +srgb_framebuffer2 = true +scale_type2 = source +filter_linear2 = true +alias2 = horz5 + +shader3 = horz7.slang +srgb_framebuffer3 = true +scale_type3 = source +filter_linear3 = true +alias3 = horz7 + +shader4 = crt-lottes-multipass.slang \ No newline at end of file diff --git a/crt/shaders/crt-lottes-multipass/crt-lottes-multipass-glow.slang b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-glow.slang similarity index 99% rename from crt/shaders/crt-lottes-multipass/crt-lottes-multipass-glow.slang rename to crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-glow.slang index a4426b2..a73d918 100755 --- a/crt/shaders/crt-lottes-multipass/crt-lottes-multipass-glow.slang +++ b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-glow.slang @@ -33,7 +33,7 @@ layout(push_constant) uniform Push #pragma parameter ntsc "NTSC Colors" 0.0 0.0 1.0 1.0 #define DO_BLOOM -#include "../../../misc/colorspace-tools.h" +#include "../../../../misc/colorspace-tools.h" layout(std140, set = 0, binding = 0) uniform UBO { diff --git a/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-old.slangp b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-old.slangp new file mode 100644 index 0000000..e54c168 --- /dev/null +++ b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-old.slangp @@ -0,0 +1,55 @@ +shaders = 10 + +shader0 = linearize.slang +srgb_framebuffer0 = true +alias0 = "REFERENCE" + +shader1 = horz3minus1.slang +srgb_framebuffer1 = true +scale_type1 = source +filter_linear1 = true +alias1 = horz3minus1 + +shader2 = horz3plus1.slang +srgb_framebuffer2 = true +scale_type2 = source +filter_linear2 = true +alias2 = horz3plus1 + +shader3 = horz5minus2.slang +srgb_framebuffer3 = true +scale_type3 = source +filter_linear3 = true +alias3 = horz5minus2 + +shader4 = horz5.slang +srgb_framebuffer4 = true +scale_type4 = source +filter_linear4 = true +alias4 = horz5 + +shader5 = horz5plus2.slang +srgb_framebuffer5 = true +scale_type5 = source +filter_linear5 = true +alias5 = horz5plus2 + +shader6 = horz7minus1.slang +srgb_framebuffer6 = true +scale_type6 = source +filter_linear6 = true +alias6 = horz7minus1 + +shader7 = horz7.slang +srgb_framebuffer7 = true +scale_type7 = source +filter_linear7 = true +alias7 = horz7 + +shader8 = horz7plus1.slang +srgb_framebuffer8 = true +scale_type8 = source +filter_linear8 = true +alias8 = horz7plus1 + +shader9 = crt-lottes-multipass.slang \ No newline at end of file diff --git a/crt/shaders/crt-lottes-multipass/crt-lottes-multipass.slang b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass.slang similarity index 99% rename from crt/shaders/crt-lottes-multipass/crt-lottes-multipass.slang rename to crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass.slang index e23cfe6..73b441c 100644 --- a/crt/shaders/crt-lottes-multipass/crt-lottes-multipass.slang +++ b/crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass.slang @@ -225,4 +225,4 @@ void main() outColor.rgb *= Mask(vTexCoord.xy / params.OutputSize.zw * 1.000001); FragColor = vec4(ToSrgb(outColor.rgb), 1.0); -} +} \ No newline at end of file diff --git a/crt/shaders/crt-lottes-multipass/old/horz3.slang b/crt/shaders/crt-lottes-multipass/old/horz3.slang new file mode 100644 index 0000000..f8f7072 --- /dev/null +++ b/crt/shaders/crt-lottes-multipass/old/horz3.slang @@ -0,0 +1,77 @@ +#version 450 + +#define hardPix -3.0 +#define brightboost 1 +#define shape 2.0 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 REFERENCESize; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +// vTexCoord = floor(global.REFERENCESize.xy * TexCoord); +// vTexCoord = (vTexCoord + 0.5) * global.REFERENCESize.zw; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D REFERENCE; + +// Nearest emulated sample given floating point position and texel offset. +// Also zero's off screen. +vec3 Fetch(vec2 pos, vec2 off) +{ + pos = vTexCoord;//(floor(pos*global.REFERENCESize.xy+off)+vec2(0.5,0.5)) * global.REFERENCESize.zw; + + return brightboost * texture(REFERENCE, pos.xy).rgb; +} + +// Distance in emulated pixels to nearest texel. +vec2 Dist(vec2 pos) +{ + pos = pos*global.REFERENCESize.xy; + + return -((pos - floor(pos)) - vec2(0.5)); +} + +// 1D Gaussian. +float Gaus(float pos, float scale) +{ + return exp2(scale*pow(abs(pos), shape)); +} + +// 3-tap Gaussian filter along horz line. +vec3 Horz3(vec2 pos, float off) +{ + vec3 b = Fetch(pos,vec2(-1.0, off)); + vec3 c = Fetch(pos,vec2( 0.0, off)); + vec3 d = Fetch(pos,vec2( 1.0, off)); + float dst = Dist(pos).x; + + // Convert distance to weight. + float scale = hardPix; + float wb = Gaus(dst - 1.0, scale); + float wc = Gaus(dst + 0.0, scale); + float wd = Gaus(dst + 1.0, scale); + + // Return filtered sample. + return (b*wb+c*wc+d*wd) / (wb+wc+wd); +} + +void main() +{ + FragColor = vec4(Horz3(vTexCoord, 0.0).rgb, 1.0); +} diff --git a/crt/shaders/crt-lottes-multipass/horz3minus1.slang b/crt/shaders/crt-lottes-multipass/old/horz3minus1.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/horz3minus1.slang rename to crt/shaders/crt-lottes-multipass/old/horz3minus1.slang diff --git a/crt/shaders/crt-lottes-multipass/horz3plus1.slang b/crt/shaders/crt-lottes-multipass/old/horz3plus1.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/horz3plus1.slang rename to crt/shaders/crt-lottes-multipass/old/horz3plus1.slang diff --git a/crt/shaders/crt-lottes-multipass/horz5.slang b/crt/shaders/crt-lottes-multipass/old/horz5.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/horz5.slang rename to crt/shaders/crt-lottes-multipass/old/horz5.slang diff --git a/crt/shaders/crt-lottes-multipass/horz5minus2.slang b/crt/shaders/crt-lottes-multipass/old/horz5minus2.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/horz5minus2.slang rename to crt/shaders/crt-lottes-multipass/old/horz5minus2.slang diff --git a/crt/shaders/crt-lottes-multipass/horz5plus2.slang b/crt/shaders/crt-lottes-multipass/old/horz5plus2.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/horz5plus2.slang rename to crt/shaders/crt-lottes-multipass/old/horz5plus2.slang diff --git a/crt/shaders/crt-lottes-multipass/horz7.slang b/crt/shaders/crt-lottes-multipass/old/horz7.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/horz7.slang rename to crt/shaders/crt-lottes-multipass/old/horz7.slang diff --git a/crt/shaders/crt-lottes-multipass/horz7minus1.slang b/crt/shaders/crt-lottes-multipass/old/horz7minus1.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/horz7minus1.slang rename to crt/shaders/crt-lottes-multipass/old/horz7minus1.slang diff --git a/crt/shaders/crt-lottes-multipass/horz7plus1.slang b/crt/shaders/crt-lottes-multipass/old/horz7plus1.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/horz7plus1.slang rename to crt/shaders/crt-lottes-multipass/old/horz7plus1.slang diff --git a/crt/shaders/crt-lottes-multipass/linearize.slang b/crt/shaders/crt-lottes-multipass/old/linearize.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/linearize.slang rename to crt/shaders/crt-lottes-multipass/old/linearize.slang diff --git a/crt/shaders/crt-lottes-multipass/threshold.slang b/crt/shaders/crt-lottes-multipass/old/threshold.slang similarity index 100% rename from crt/shaders/crt-lottes-multipass/threshold.slang rename to crt/shaders/crt-lottes-multipass/old/threshold.slang diff --git a/crt/shaders/crt-lottes-multipass/scanpass.slang b/crt/shaders/crt-lottes-multipass/scanpass.slang new file mode 100644 index 0000000..139b52a --- /dev/null +++ b/crt/shaders/crt-lottes-multipass/scanpass.slang @@ -0,0 +1,359 @@ +#version 450 + +// PUBLIC DOMAIN CRT STYLED SCAN-LINE SHADER +// +// by Timothy Lottes +// +// This is more along the style of a really good CGA arcade monitor. +// With RGB inputs instead of NTSC. +// The shadow mask example has the mask rotated 90 degrees for less chromatic aberration. +// +// Left it unoptimized to show the theory behind the algorithm. +// +// It is an example what I personally would want as a display option for pixel art games. +// Please take and use, change, or whatever. + +layout(push_constant) uniform Push +{ + float hardScan; + float hardPix; + float warpX; + float warpY; + float maskDark; + float maskLight; + float scaleInLinearGamma; + float shadowMask; + float brightBoost; + float hardBloomScan; + float hardBloomPix; + float bloomAmount; + float shape; +} param; + +#pragma parameter hardScan "hardScan" -8.0 -20.0 0.0 1.0 +#pragma parameter hardPix "hardPix" -3.0 -20.0 0.0 1.0 +#pragma parameter warpX "warpX" 0.031 0.0 0.125 0.01 +#pragma parameter warpY "warpY" 0.041 0.0 0.125 0.01 +#pragma parameter maskDark "maskDark" 0.5 0.0 2.0 0.1 +#pragma parameter maskLight "maskLight" 1.5 0.0 2.0 0.1 +#pragma parameter scaleInLinearGamma "scaleInLinearGamma" 1.0 0.0 1.0 1.0 +#pragma parameter shadowMask "shadowMask" 3.0 0.0 4.0 1.0 +#pragma parameter brightBoost "brightness boost" 1.0 0.0 2.0 0.05 +#pragma parameter hardBloomPix "bloom-x soft" -1.5 -2.0 -0.5 0.1 +#pragma parameter hardBloomScan "bloom-y soft" -2.0 -4.0 -1.0 0.1 +#pragma parameter bloomAmount "bloom amount" 0.40 0.0 1.0 0.05 +#pragma parameter shape "filter kernel shape" 2.0 0.0 10.0 0.05 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} global; + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord * 1.00001; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 FragCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D Original; +layout(set = 0, binding = 4) uniform sampler2D BloomPass; + +//Uncomment to reduce instructions with simpler linearization +//(fixes HD3000 Sandy Bridge IGP) +//#define SIMPLE_LINEAR_GAMMA +#define DO_BLOOM 1 + +// ------------- // + +// sRGB to Linear. +// Assuming using sRGB typed textures this should not be needed. +#ifdef SIMPLE_LINEAR_GAMMA +float ToLinear1(float c) +{ + return c; +} +vec3 ToLinear(vec3 c) +{ + return c; +} +vec3 ToSrgb(vec3 c) +{ + return pow(c, vec3(1.0 / 2.2)); +} +#else +float ToLinear1(float c) +{ + if (param.scaleInLinearGamma == 0) + return c; + + return(c<=0.04045) ? c/12.92 : pow((c + 0.055)/1.055, 2.4); +} + +vec3 ToLinear(vec3 c) +{ + if (param.scaleInLinearGamma==0) + return c; + + return vec3(ToLinear1(c.r), ToLinear1(c.g), ToLinear1(c.b)); +} + +// Linear to sRGB. +// Assuming using sRGB typed textures this should not be needed. +float ToSrgb1(float c) +{ + if (param.scaleInLinearGamma == 0) + return c; + + return(c<0.0031308 ? c*12.92 : 1.055*pow(c, 0.41666) - 0.055); +} + +vec3 ToSrgb(vec3 c) +{ + if (param.scaleInLinearGamma == 0) + return c; + + return vec3(ToSrgb1(c.r), ToSrgb1(c.g), ToSrgb1(c.b)); +} +#endif + + + +// Nearest emulated sample given floating point position and texel offset. +// Also zero's off screen. +vec3 Fetch(vec2 pos,vec2 off){ + pos=(floor(pos*global.SourceSize.xy+off)+vec2(0.5,0.5))/global.SourceSize.xy; +#ifdef SIMPLE_LINEAR_GAMMA + return ToLinear(param.brightBoost * pow(texture(Original,pos.xy).rgb, vec3(2.2))); +#else + return ToLinear(param.brightBoost * texture(Original,pos.xy).rgb); +#endif +} + +// Distance in emulated pixels to nearest texel. +vec2 Dist(vec2 pos) +{ + pos = pos*global.SourceSize.xy; + + return -((pos - floor(pos)) - vec2(0.5)); +} + +// 1D Gaussian. +float Gaus(float pos, float scale) +{ + return exp2(scale*pow(abs(pos), param.shape)); +} + +// 3-tap Gaussian filter along horz line. +vec3 Horz3(vec2 pos, float off) +{ + vec3 b = Fetch(pos, vec2(-1.0, off)); + vec3 c = Fetch(pos, vec2( 0.0, off)); + vec3 d = Fetch(pos, vec2( 1.0, off)); + float dst = Dist(pos).x; + + // Convert distance to weight. + float scale = param.hardPix; + float wb = Gaus(dst-1.0,scale); + float wc = Gaus(dst+0.0,scale); + float wd = Gaus(dst+1.0,scale); + + // Return filtered sample. + return (b*wb+c*wc+d*wd)/(wb+wc+wd); +} + +// 5-tap Gaussian filter along horz line. +vec3 Horz5(vec2 pos,float off){ + vec3 a = Fetch(pos,vec2(-2.0, off)); + vec3 b = Fetch(pos,vec2(-1.0, off)); + vec3 c = Fetch(pos,vec2( 0.0, off)); + vec3 d = Fetch(pos,vec2( 1.0, off)); + vec3 e = Fetch(pos,vec2( 2.0, off)); + + float dst = Dist(pos).x; + // Convert distance to weight. + float scale = param.hardPix; + float wa = Gaus(dst - 2.0, scale); + float wb = Gaus(dst - 1.0, scale); + float wc = Gaus(dst + 0.0, scale); + float wd = Gaus(dst + 1.0, scale); + float we = Gaus(dst + 2.0, scale); + + // Return filtered sample. + return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we); +} + +// 7-tap Gaussian filter along horz line. +vec3 Horz7(vec2 pos,float off) +{ + vec3 a = Fetch(pos, vec2(-3.0, off)); + vec3 b = Fetch(pos, vec2(-2.0, off)); + vec3 c = Fetch(pos, vec2(-1.0, off)); + vec3 d = Fetch(pos, vec2( 0.0, off)); + vec3 e = Fetch(pos, vec2( 1.0, off)); + vec3 f = Fetch(pos, vec2( 2.0, off)); + vec3 g = Fetch(pos, vec2( 3.0, off)); + + float dst = Dist(pos).x; + // Convert distance to weight. + float scale = param.hardBloomPix; + float wa = Gaus(dst - 3.0, scale); + float wb = Gaus(dst - 2.0, scale); + float wc = Gaus(dst - 1.0, scale); + float wd = Gaus(dst + 0.0, scale); + float we = Gaus(dst + 1.0, scale); + float wf = Gaus(dst + 2.0, scale); + float wg = Gaus(dst + 3.0, scale); + + // Return filtered sample. + return (a*wa+b*wb+c*wc+d*wd+e*we+f*wf+g*wg)/(wa+wb+wc+wd+we+wf+wg); +} + +// Return scanline weight. +float Scan(vec2 pos, float off) +{ + float dst = Dist(pos).y; + + return Gaus(dst + off, param.hardScan); +} + +// Return scanline weight for bloom. +float BloomScan(vec2 pos, float off) +{ + float dst = Dist(pos).y; + + return Gaus(dst + off, param.hardBloomScan); +} + +// Allow nearest three lines to effect pixel. +vec3 Tri(vec2 pos) +{ + vec3 a = Horz3(pos,-1.0); + vec3 b = Horz5(pos, 0.0); + vec3 c = Horz3(pos, 1.0); + + float wa = Scan(pos,-1.0); + float wb = Scan(pos, 0.0); + float wc = Scan(pos, 1.0); + + return a*wa + b*wb + c*wc; +} + +// Small bloom. +vec3 Bloom(vec2 pos) +{ + vec3 a = Horz5(pos,-2.0); + vec3 b = Horz7(pos,-1.0); + vec3 c = Horz7(pos, 0.0); + vec3 d = Horz7(pos, 1.0); + vec3 e = Horz5(pos, 2.0); + + float wa = BloomScan(pos,-2.0); + float wb = BloomScan(pos,-1.0); + float wc = BloomScan(pos, 0.0); + float wd = BloomScan(pos, 1.0); + float we = BloomScan(pos, 2.0); + + return a*wa+b*wb+c*wc+d*wd+e*we; +} + +// Distortion of scanlines, and end of screen alpha. +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos *= vec2(1.0 + (pos.y*pos.y)*param.warpX, 1.0 + (pos.x*pos.x)*param.warpY); + + return pos*0.5 + 0.5; +} + +// Shadow mask. +vec3 Mask(vec2 pos) +{ + vec3 mask = vec3(param.maskDark, param.maskDark, param.maskDark); + + // Very compressed TV style shadow mask. + if (param.shadowMask == 1.0) + { + float line = param.maskLight; + float odd = 0.0; + + if (fract(pos.x*0.166666666) < 0.5) odd = 1.0; + if (fract((pos.y + odd) * 0.5) < 0.5) line = param.maskDark; + + pos.x = fract(pos.x*0.333333333); + + if (pos.x < 0.333) mask.r = param.maskLight; + else if (pos.x < 0.666) mask.g = param.maskLight; + else mask.b = param.maskLight; + mask*=line; + } + + // Aperture-grille. + else if (param.shadowMask == 2.0) + { + pos.x = fract(pos.x*0.333333333); + + if (pos.x < 0.333) mask.r = param.maskLight; + else if (pos.x < 0.666) mask.g = param.maskLight; + else mask.b = param.maskLight; + } + + // Stretched VGA style shadow mask (same as prior shaders). + else if (param.shadowMask == 3.0) + { + pos.x += pos.y*3.0; + pos.x = fract(pos.x*0.166666666); + + if (pos.x < 0.333) mask.r = param.maskLight; + else if (pos.x < 0.666) mask.g = param.maskLight; + else mask.b = param.maskLight; + } + + // VGA style shadow mask. + else if (param.shadowMask == 4.0) + { + pos.xy = floor(pos.xy*vec2(1.0, 0.5)); + pos.x += pos.y*3.0; + pos.x = fract(pos.x*0.166666666); + + if (pos.x < 0.333) mask.r = param.maskLight; + else if (pos.x < 0.666) mask.g = param.maskLight; + else mask.b = param.maskLight; + } + + return mask; +} + +void main() +{ + vec2 pos = Warp(vTexCoord); + vec3 outColor = Tri(pos).rgb; + + if (param.shadowMask > 0.0) + outColor.rgb *= Mask(vTexCoord.xy / global.OutputSize.zw * 1.000001); +#ifdef DO_BLOOM + //Add Bloom + outColor.rgb += mix( vec3(0.0), texture(BloomPass, pos).rgb, param.bloomAmount); +#endif +#ifdef GL_ES /* TODO/FIXME - hacky clamp fix */ + vec2 bordertest = (pos); + if ( bordertest.x > 0.0001 && bordertest.x < 0.9999 && bordertest.y > 0.0001 && bordertest.y < 0.9999) + outColor.rgb = outColor.rgb; + else + outColor.rgb = vec3(0.0); +#endif + + FragColor = vec4(ToSrgb(outColor.rgb), 1.0); +} diff --git a/presets/bigblur-lottes-multipass.slangp b/presets/bigblur-lottes-multipass.slangp index 59d3b1e..f4ec960 100644 --- a/presets/bigblur-lottes-multipass.slangp +++ b/presets/bigblur-lottes-multipass.slangp @@ -1,58 +1,58 @@ shaders = 13 -shader0 = ../crt/shaders/crt-lottes-multipass/linearize.slang +shader0 = ../crt/shaders/crt-lottes-multipass/old/linearize.slang srgb_framebuffer0 = true alias0 = "REFERENCE" -shader1 = ../crt/shaders/crt-lottes-multipass/horz3minus1.slang +shader1 = ../crt/shaders/crt-lottes-multipass/old/horz3minus1.slang srgb_framebuffer1 = true scale_type1 = source filter_linear1 = true alias1 = horz3minus1 -shader2 = ../crt/shaders/crt-lottes-multipass/horz3plus1.slang +shader2 = ../crt/shaders/crt-lottes-multipass/old/horz3plus1.slang srgb_framebuffer2 = true scale_type2 = source filter_linear2 = true alias2 = horz3plus1 -shader3 = ../crt/shaders/crt-lottes-multipass/horz5minus2.slang +shader3 = ../crt/shaders/crt-lottes-multipass/old/horz5minus2.slang srgb_framebuffer3 = true scale_type3 = source filter_linear3 = true alias3 = horz5minus2 -shader4 = ../crt/shaders/crt-lottes-multipass/horz5.slang +shader4 = ../crt/shaders/crt-lottes-multipass/old/horz5.slang srgb_framebuffer4 = true scale_type4 = source filter_linear4 = true alias4 = horz5 -shader5 = ../crt/shaders/crt-lottes-multipass/horz5plus2.slang +shader5 = ../crt/shaders/crt-lottes-multipass/old/horz5plus2.slang srgb_framebuffer5 = true scale_type5 = source filter_linear5 = true alias5 = horz5plus2 -shader6 = ../crt/shaders/crt-lottes-multipass/horz7minus1.slang +shader6 = ../crt/shaders/crt-lottes-multipass/old/horz7minus1.slang srgb_framebuffer6 = true scale_type6 = source filter_linear6 = true alias6 = horz7minus1 -shader7 = ../crt/shaders/crt-lottes-multipass/horz7.slang +shader7 = ../crt/shaders/crt-lottes-multipass/old/horz7.slang srgb_framebuffer7 = true scale_type7 = source filter_linear7 = true alias7 = horz7 -shader8 = ../crt/shaders/crt-lottes-multipass/horz7plus1.slang +shader8 = ../crt/shaders/crt-lottes-multipass/old/horz7plus1.slang srgb_framebuffer8 = true scale_type8 = source filter_linear8 = true alias8 = horz7plus1 -shader9 = ../crt/shaders/crt-lottes-multipass/crt-lottes-multipass.slang +shader9 = ../crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass.slang scale_type9 = source scale9 = 4.0 filter_linear9 = false diff --git a/presets/crt-lottes-trinitron.slangp b/presets/crt-lottes-trinitron.slangp index a7f3cc4..9c0aa73 100755 --- a/presets/crt-lottes-trinitron.slangp +++ b/presets/crt-lottes-trinitron.slangp @@ -24,7 +24,7 @@ shader4 = ../crt/shaders/crt-royale/src/crt-royale-first-pass-linearize-crt-gamm srgb_framebuffer4 = true alias4 = "REFERENCE" -shader5 = "../crt/shaders/crt-lottes-multipass/threshold.slang" +shader5 = "../crt/shaders/crt-lottes-multipass/old/threshold.slang" srgb_framebuffer5 = "true" shader6 = "../blurs/blur9fast-vertical.slang" @@ -40,55 +40,55 @@ scale_type7 = "source" scale7 = "1.0" srgb_framebuffer7 = "true" -shader8 = ../crt/shaders/crt-lottes-multipass/horz3minus1.slang +shader8 = ../crt/shaders/crt-lottes-multipass/old/horz3minus1.slang srgb_framebuffer8 = true scale_type8 = source filter_linear8 = true alias8 = horz3minus1 -shader9 = ../crt/shaders/crt-lottes-multipass/horz3plus1.slang +shader9 = ../crt/shaders/crt-lottes-multipass/old/horz3plus1.slang srgb_framebuffer9 = true scale_type9 = source filter_linear9 = true alias9 = horz3plus1 -shader10 = ../crt/shaders/crt-lottes-multipass/horz5minus2.slang +shader10 = ../crt/shaders/crt-lottes-multipass/old/horz5minus2.slang srgb_framebuffer10 = true scale_type10 = source filter_linear10 = true alias10 = horz5minus2 -shader11 = ../crt/shaders/crt-lottes-multipass/horz5.slang +shader11 = ../crt/shaders/crt-lottes-multipass/old/horz5.slang srgb_framebuffer11 = true scale_type11 = source filter_linear11 = true alias11 = horz5 -shader12 = ../crt/shaders/crt-lottes-multipass/horz5plus2.slang +shader12 = ../crt/shaders/crt-lottes-multipass/old/horz5plus2.slang srgb_framebuffer12 = true scale_type12 = source filter_linear12 = true alias12 = horz5plus2 -shader13 = ../crt/shaders/crt-lottes-multipass/horz7minus1.slang +shader13 = ../crt/shaders/crt-lottes-multipass/old/horz7minus1.slang srgb_framebuffer13 = true scale_type13 = source filter_linear13 = true alias13 = horz7minus1 -shader14 = ../crt/shaders/crt-lottes-multipass/horz7.slang +shader14 = ../crt/shaders/crt-lottes-multipass/old/horz7.slang srgb_framebuffer14 = true scale_type14 = source filter_linear14 = true alias14 = horz7 -shader15 = ../crt/shaders/crt-lottes-multipass/horz7plus1.slang +shader15 = ../crt/shaders/crt-lottes-multipass/old/horz7plus1.slang srgb_framebuffer15 = true scale_type15 = source filter_linear15 = true alias15 = horz7plus1 -shader16 = ../crt/shaders/crt-lottes-multipass/crt-lottes-multipass-glow.slang +shader16 = ../crt/shaders/crt-lottes-multipass/old/crt-lottes-multipass-glow.slang texture_wrap_mode16 = "clamp_to_edge" scale16 = 4.0 scale_type16 = source