Back to shaders
Shader test bench
Analog Glitch 9.fs
runnable fragment
Complete GLSL fragment shader. Stronghold runs it directly when the browser can compile it.
Code
uniform sampler2D inputImage;
uniform float timeSpeed;
uniform float glitchIntensity;
uniform float colorSeparation;
uniform float verticalRollSpeed;
uniform int interlaced;
uniform float interlaceStrength;
uniform float interlaceWarpAmount;
uniform float warpCenter;
uniform float warpRange;
uniform int randomizeWarpPosition;
uniform float warpSeedSpeed;
uniform float interlaceSkewAmount;
uniform float skewBias;
precision mediump float;
/*{
"CATEGORIES": ["Stylize", "Glitch", "Analog"],
"DESCRIPTION": "Created by ProjectileObjects. Analog glitch with scanline warp, vertical roll, directional skew, and sync distortion.",
"ISFVSN": "2",
"INPUTS": [
{ "NAME": "inputImage", "TYPE": "image" },
{
"NAME": "timeSpeed", "TYPE": "float", "DEFAULT": 1.0,
"MIN": 0.0, "MAX": 5.0, "LABEL": "Time Speed"
},
{
"NAME": "glitchIntensity", "TYPE": "float", "DEFAULT": 0.3,
"MIN": 0.0, "MAX": 1.0, "LABEL": "Glitch Intensity"
},
{
"NAME": "colorSeparation", "TYPE": "float", "DEFAULT": 0.02,
"MIN": 0.0, "MAX": 0.1, "LABEL": "Color Separation"
},
{
"NAME": "verticalRollSpeed", "TYPE": "float", "DEFAULT": 0.2,
"MIN": 0.0, "MAX": 2.0, "LABEL": "Vertical Roll Speed"
},
{
"NAME": "interlaced", "TYPE": "bool", "DEFAULT": true,
"LABEL": "Interlaced Effect"
},
{
"NAME": "interlaceStrength", "TYPE": "float", "DEFAULT": 0.3,
"MIN": 0.0, "MAX": 1.0, "LABEL": "Interlace Strength"
},
{
"NAME": "interlaceWarpAmount", "TYPE": "float", "DEFAULT": 0.05,
"MIN": 0.0, "MAX": 0.3, "LABEL": "Interlace Warp Amount"
},
{
"NAME": "warpCenter", "TYPE": "float", "DEFAULT": 0.5,
"MIN": 0.0, "MAX": 1.0, "LABEL": "Warp Vertical Center"
},
{
"NAME": "warpRange", "TYPE": "float", "DEFAULT": 0.3,
"MIN": 0.0, "MAX": 1.0, "LABEL": "Warp Vertical Range"
},
{
"NAME": "randomizeWarpPosition", "TYPE": "bool",
"DEFAULT": false, "LABEL": "Auto-Shift Warp Center"
},
{
"NAME": "warpSeedSpeed", "TYPE": "float", "DEFAULT": 0.5,
"MIN": 0.0, "MAX": 5.0, "LABEL": "Warp Drift Speed"
},
{
"NAME": "interlaceSkewAmount", "TYPE": "float", "DEFAULT": 0.02,
"MIN": 0.0, "MAX": 0.2, "LABEL": "Skew Strength"
},
{
"NAME": "skewBias", "TYPE": "float", "DEFAULT": 0.0,
"MIN": -1.0, "MAX": 1.0, "LABEL": "Skew Direction Bias"
}
]
}*/
float hash(float x) {
return fract(sin(x * 17.372) * 43758.5453123);
}
void main() {
vec2 uv = (gl_FragCoord.xy / u_resolution.xy);
float time = u_time * timeSpeed;
// Horizontal glitch tear
float randLine = hash(uv.y + time * 2.0);
float hOffset = glitchIntensity * 0.05 * randLine;
// Interlace line toggle
float interlaceLine = interlaced ? step(0.5, fract(uv.y * u_resolution.y * 0.5)) : 1.0;
float interlaceEffect = mix(1.0, interlaceLine, interlaceStrength);
// Animate warp center if enabled
float animatedWarpCenter = warpCenter;
if (randomizeWarpPosition) {
float noise = sin(time * warpSeedSpeed) * 0.5 + 0.5;
animatedWarpCenter = mix(0.1, 0.9, noise);
}
float distFromCenter = abs(uv.y - animatedWarpCenter);
float warpMask = smoothstep(warpRange, 0.0, distFromCenter);
// Horizontal scanline ripple warp
float warp = sin(uv.y * u_resolution.y * 5.0 + time * 15.0) * interlaceWarpAmount * warpMask;
float warpedX = uv.x + warp * interlaceEffect;
// Skew with directional bias
float lineID = floor(uv.y * u_resolution.y);
float baseJitter = hash(lineID + time * 10.0);
float skewRandom = (baseJitter - 0.5) * 2.0;
float skew = (skewRandom + skewBias) * 0.5;
// Apply roll and skew
float rolledY = uv.y + time * verticalRollSpeed;
float skewedY = rolledY + skew * interlaceSkewAmount * warpMask;
vec2 warpedUV = vec2(warpedX + hOffset, mod(skewedY, 1.0));
// RGB chromatic offset
vec2 redOffset = vec2(colorSeparation, 0.0);
vec2 greenOffset = vec2(0.0);
vec2 blueOffset = vec2(-colorSeparation, 0.0);
vec4 red = texture2D(inputImage, warpedUV + redOffset);
vec4 green = texture2D(inputImage, warpedUV + greenOffset);
vec4 blue = texture2D(inputImage, warpedUV + blueOffset);
vec4 color = vec4(red.r, green.g, blue.b, 1.0);
// Scanline flicker
float scanline = 0.9 + 0.1 * sin(uv.y * u_resolution.y * 2.0 + time * 20.0);
color.rgb *= scanline * interlaceEffect;
gl_FragColor = color;
}