From 5fd80ad7ea07f31dc7fea644c0b4845f6b5d3197 Mon Sep 17 00:00:00 2001 From: hunterk Date: Mon, 27 Apr 2020 14:45:44 -0500 Subject: [PATCH] make res-independent scanlines better, add built-in res control to geom --- crt/shaders/crt-geom.slang | 20 +++--- .../shaders/res-independent-scanlines.slang | 61 +++++++++++++------ 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/crt/shaders/crt-geom.slang b/crt/shaders/crt-geom.slang index 46d569b..2e09d13 100644 --- a/crt/shaders/crt-geom.slang +++ b/crt/shaders/crt-geom.slang @@ -2,9 +2,6 @@ layout(push_constant) uniform Push { - vec4 OutputSize; - vec4 OriginalSize; - vec4 SourceSize; uint FrameCount; float CRTgamma; float monitorgamma; @@ -22,12 +19,14 @@ layout(push_constant) uniform Push float CURVATURE; float interlace_detect; float lum; + float xsize, ysize; } registers; layout(std140, set = 0, binding = 0) uniform UBO { mat4 MVP; vec4 OutputSize; + vec4 SourceSize; } global; #pragma parameter CRTgamma "CRTGeom Target Gamma" 2.4 0.1 5.0 0.1 @@ -47,6 +46,13 @@ layout(std140, set = 0, binding = 0) uniform UBO #pragma parameter lum "CRTGeom Luminance" 0.0 0.0 1.0 0.01 #pragma parameter interlace_detect "CRTGeom Interlacing Simulation" 1.0 0.0 1.0 1.0 +#pragma parameter xsize "Simulated Width (0==Auto)" 0.0 0.0 1920.0 16.0 +#pragma parameter ysize "Simulated Height (0==Auto)" 0.0 0.0 1080.0 16.0 + +vec2 height = (registers.ysize > 0.001) ? vec2(registers.ysize, 1./registers.ysize) : global.SourceSize.yw; +vec2 width = (registers.xsize > 0.001) ? vec2(registers.xsize, 1./registers.xsize) : global.SourceSize.xz; +vec4 SourceSize = vec4(width.x, height.x, width.y, height.y); + /* CRT-interlaced @@ -166,15 +172,15 @@ void main() sinangle = sin(vec2(registers.x_tilt, registers.y_tilt)); cosangle = cos(vec2(registers.x_tilt, registers.y_tilt)); stretch = maxscale(); - TextureSize = vec2(registers.SHARPER * registers.SourceSize.x, registers.SourceSize.y); + TextureSize = vec2(registers.SHARPER * SourceSize.x, SourceSize.y); - ilfac = vec2(1.0, clamp(floor(registers.SourceSize.y/200.0), 1.0, 2.0)); + ilfac = vec2(1.0, clamp(floor(SourceSize.y/200.0), 1.0, 2.0)); // The size of one texel, in texture-coordinates. one = ilfac / TextureSize; // Resulting X pixel-coordinate of the pixel we're drawing. - mod_factor = vTexCoord.x * registers.SourceSize.x * registers.OutputSize.x / registers.SourceSize.x; + mod_factor = vTexCoord.x * SourceSize.x * global.OutputSize.x / SourceSize.x; } #pragma stage fragment @@ -393,7 +399,7 @@ void main() vec3 dotMaskWeights = mix( vec3(1.0, 1.0 - registers.DOTMASK, 1.0), vec3(1.0 - registers.DOTMASK, 1.0, 1.0 - registers.DOTMASK), - floor(mod(mod_factor, 2.0)) + floor(mod(gl_FragCoord.x, 2.0)) ); mul_res *= dotMaskWeights; diff --git a/scanlines/shaders/res-independent-scanlines.slang b/scanlines/shaders/res-independent-scanlines.slang index f18dc89..53992b7 100644 --- a/scanlines/shaders/res-independent-scanlines.slang +++ b/scanlines/shaders/res-independent-scanlines.slang @@ -1,9 +1,12 @@ #version 450 /* - based on scanline shader by: - Author: Themaister - License: Public domain + Resolution-Independent Scanlines + based on + Scanlines Sine Absolute Value + An ultra light scanline shader + by RiskyJumps + license: public domain */ layout(push_constant) uniform Push @@ -12,16 +15,25 @@ layout(push_constant) uniform Push vec4 OriginalSize; vec4 OutputSize; uint FrameCount; - vec4 FinalViewportSize; - float SCANLINE_SINE_COMP_B; - float scanline_size; + float amp; + float phase; + float lines_black; + float lines_white; + float mask, mask_weight, imageSize; } params; -#pragma parameter SCANLINE_SINE_COMP_B "Scanline Sine Comp B" 0.25 0.0 1.0 0.05 -#pragma parameter scanline_size "Scanline Scale" 4.0 2.0 10.0 0.5 +#pragma parameter amp "Amplitude" 1.2500 0.000 2.000 0.05 +#pragma parameter phase "Phase" 0.5000 0.000 2.000 0.05 +#pragma parameter lines_black "Lines Blacks" 0.0000 0.000 1.000 0.05 +#pragma parameter lines_white "Lines Whites" 1.0000 0.000 2.000 0.05 -#define SCANLINE_SINE_COMP_B params.SCANLINE_SINE_COMP_B -#define scanline_size params.scanline_size +#pragma parameter mask "Mask Layout" 0.0 0.0 19.0 1.0 +#pragma parameter mask_weight "Mask Weight" 0.5 0.0 1.0 0.01 +#pragma parameter imageSize "Simulated Image Height" 224.0 144.0 260.0 1.0 + +#define freq 0.500000 +#define offset 0.000000 +#define pi 3.141592654 layout(std140, set = 0, binding = 0) uniform UBO { @@ -29,32 +41,45 @@ layout(std140, set = 0, binding = 0) uniform UBO } global; #define pi 3.141592654 +#include "../../include/subpixel_masks.h" #pragma stage vertex layout(location = 0) in vec4 Position; layout(location = 1) in vec2 TexCoord; layout(location = 0) out vec2 vTexCoord; -layout(location = 1) out vec2 omega; +layout(location = 1) out float omega; void main() { gl_Position = global.MVP * Position; vTexCoord = TexCoord; - omega = vec2(pi * params.OutputSize.x, 2.0 * pi * params.SourceSize.y); + omega = 2.0 * pi * freq; // Angular frequency } #pragma stage fragment layout(location = 0) in vec2 vTexCoord; -layout(location = 1) in vec2 omega; +layout(location = 1) in float omega; layout(location = 0) out vec4 FragColor; layout(set = 0, binding = 2) uniform sampler2D Source; void main() { - vec2 sine_comp = vec2(0.0, SCANLINE_SINE_COMP_B); - vec3 res = texture(Source, vTexCoord).xyz; - vec2 fragcoord = fract(floor(vTexCoord.xy * params.OutputSize.xy * 1.0001) / scanline_size); - vec3 scanline = (fragcoord.y > 0.3333)? res : vec3(SCANLINE_SINE_COMP_B * res);//res * ((1. - 0.75 * SCANLINE_SINE_COMP_B) + dot(sine_comp * sin((fragcoord / scanline_size) * omega), vec2(1.0, 1.0))); - FragColor = vec4(scanline.x, scanline.y, scanline.z, 1.0); + float angle = (gl_FragCoord.y * params.OutputSize.w) * omega * params.imageSize + params.phase; + vec3 color = texture(Source, vTexCoord).xyz; + float grid; + + float lines; + + lines = sin(angle); + lines *= params.amp; + lines += offset; + lines = abs(lines); + lines *= params.lines_white - params.lines_black; + lines += params.lines_black; + color *= lines; + + FragColor = vec4(color.xyz, 1.0); + FragColor.rgb *= mask_weights(gl_FragCoord.xy, params.mask_weight, int(params.mask)); } +