diff --git a/crt/crt-geom.slang b/crt/crt-geom.slang index 884ff0a..b29c798 100644 --- a/crt/crt-geom.slang +++ b/crt/crt-geom.slang @@ -170,7 +170,7 @@ vec4 scanlineWeights(float distance, vec4 color) void main() { gl_Position = global.MVP * Position; - vTexCoord = TexCoord; + vTexCoord = TexCoord * vec2(1.00001); // Precalculate a bunch of useful values we'll need in the fragment // shader. @@ -178,13 +178,13 @@ void main() cosangle = cos(angle); stretch = maxscale(); - ilfac = vec2(1.0,(global.SourceSize.y/200.0)); + ilfac = vec2(1.0, 1.0000001);//vec2(1.0,(global.SourceSize.y/200.0)); // The size of one texel, in texture-coordinates. one = ilfac / global.SourceSize.xy; // Resulting X pixel-coordinate of the pixel we're drawing. - mod_factor = TexCoord.x * global.SourceSize.x * global.OutputSize.x / global.SourceSize.x; + mod_factor = vTexCoord.x * global.SourceSize.x * global.OutputSize.x / global.SourceSize.x; } #pragma stage fragment @@ -408,7 +408,7 @@ void main() vec3 dotMaskWeights = mix( vec3(1.0, 1.0 - DOTMASK, 1.0), vec3(1.0 - DOTMASK, 1.0, 1.0 - DOTMASK), - floor(mod(mod_factor, 2.01)) + floor(mod(mod_factor, 2.0)) ); mul_res *= dotMaskWeights; diff --git a/crt/shaders/dotmask.slang b/crt/shaders/dotmask.slang new file mode 100644 index 0000000..48cbd7b --- /dev/null +++ b/crt/shaders/dotmask.slang @@ -0,0 +1,102 @@ +#version 450 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} global; + +#define DOTMASK_STRENGTH 0.3 +#define maskDark 0.5 +#define maskLight 1.5 +#define shadowMask 0.0 + +#define mod_factor vTexCoord.x * global.SourceSize.x * global.OutputSize.x / global.SourceSize.x + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +// Shadow mask. +vec3 Mask(vec2 pos){ + vec3 mask=vec3(maskDark,maskDark,maskDark); + +// Very compressed TV style shadow mask. + if (shadowMask == 1.0) { + float line=maskLight; + float odd=0.0; + if(fract(pos.x/6.0)<0.5)odd=1.0; + if(fract((pos.y+odd)/2.0)<0.5)line=maskDark; + pos.x=fract(pos.x/3.0); + + if(pos.x<0.333)mask.r=maskLight; + else if(pos.x<0.666)mask.g=maskLight; + else mask.b=maskLight; + mask*=line; + } + +// Aperture-grille. + else if (shadowMask == 2.0) { + pos.x=fract(pos.x/3.0); + + if(pos.x<0.333)mask.r=maskLight; + else if(pos.x<0.666)mask.g=maskLight; + else mask.b=maskLight; + } + +// Stretched VGA style shadow mask (same as prior shaders). + else if (shadowMask == 3.0) { + pos.x+=pos.y*3.0; + pos.x=fract(pos.x/6.0); + + if(pos.x<0.333)mask.r=maskLight; + else if(pos.x<0.666)mask.g=maskLight; + else mask.b=maskLight; + } + +// VGA style shadow mask. + else if (shadowMask == 4.0) { + pos.xy=floor(pos.xy*vec2(1.0,0.5)); + pos.x+=pos.y*3.0; + pos.x=fract(pos.x/6.0); + + if(pos.x<0.333)mask.r=maskLight; + else if(pos.x<0.666)mask.g=maskLight; + else mask.b=maskLight; + } + + return mask;} + +void main() +{ +vec3 res = texture(Source, vTexCoord).rgb; + +float mask = 1.0 - DOTMASK_STRENGTH; + +//cgwg's dotmask emulation: +//Output pixels are alternately tinted green and magenta +vec3 dotMaskWeights = mix(vec3(1.0, mask, 1.0), + vec3(mask, 1.0, mask), + floor(mod(mod_factor, 2.0))); +if (shadowMask == 0) { + res *= dotMaskWeights; + } +else { + res *= Mask(floor(1.000001 * vTexCoord.xy * global.OutputSize.xy + vec2(0.5))); + } + FragColor = vec4(res, 1.0); +} \ No newline at end of file