diff --git a/scanlines/res-independent-scalines.slangp b/scanlines/res-independent-scanlines.slangp similarity index 100% rename from scanlines/res-independent-scalines.slangp rename to scanlines/res-independent-scanlines.slangp diff --git a/scanlines/scanlines-rere.slangp b/scanlines/scanlines-rere.slangp new file mode 100644 index 0000000..a448987 --- /dev/null +++ b/scanlines/scanlines-rere.slangp @@ -0,0 +1,4 @@ +shaders = 1 + +shader0 = shaders/scanlines-rere.slang +filter_linear0 = true diff --git a/scanlines/shaders/scanlines-rere.slang b/scanlines/shaders/scanlines-rere.slang new file mode 100644 index 0000000..4ae8381 --- /dev/null +++ b/scanlines/shaders/scanlines-rere.slang @@ -0,0 +1,81 @@ +#version 450 + +/* + by Rere + license: public domain +*/ + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float thickness; + float glow; + float sGamma; + float tGamma; + float highlights; + float boost; +} params; + +#pragma parameter thickness "Scanline thickness" 0.50 0.00 1.00 0.01 +#pragma parameter glow "Scanline glow" 0.75 0.00 1.00 0.01 +#pragma parameter highlights "Scanline highlights" 0.75 0.00 1.00 0.01 +#pragma parameter boost "Luminance boost" 0.25 0.00 1.00 0.01 +#pragma parameter sGamma "Source gamma" 2.40 1.00 3.00 0.01 +#pragma parameter tGamma "Target gamma" 2.20 1.00 3.00 0.01 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#define pi 3.141592654 +#define luminance(c) (0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) + +vec3 gammaFn(vec3 c, float gamma) { + return vec3(pow(c.x, gamma), pow(c.y, gamma), pow(c.z, gamma)); +} + +#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 float thickness; +layout(location = 2) out float glow; +layout(location = 3) out float highlights; +layout(location = 4) out float boost; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; + thickness = 0.5 + mix(0.0, 2.0, params.thickness); + glow = mix(-0.5, 0.5, params.glow); + highlights = mix(0.0, 1.0, params.highlights); + boost = mix(0.0, 5.0, params.boost); +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in float thickness; +layout(location = 2) in float glow; +layout(location = 3) in float highlights; +layout(location = 4) in float boost; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ + vec2 uv = vTexCoord.xy; + vec3 col = texture(Source, uv).rgb; + col = gammaFn(col, params.sGamma); + float L = luminance(col); + float y = fract(uv.y * params.SourceSize.y * 1.0); + y = pow(sin(y * pi), thickness); + y = (y + glow) / (1.0 + glow); + float g = 1.0 + L * (1.0 - L) * boost; + col = mix(col, col * g * y, 1.0 - L * highlights); + FragColor = vec4(gammaFn(col, 1.0 / params.tGamma), 1.0); +}