float hash21(float2 p) { return frac(sin(dot(p, float2(127.1, 311.7))) * 43758.5453123); } float4 shadeVideo(ShaderContext context) { float2 blocks = max(blockCount, float2(1.0, 1.0)); float2 blockId = floor(context.uv * blocks); float n = hash21(blockId + floor(context.time * 8.0)); float historyFrame = floor(lerp(1.0, 7.0, n)); float rowNoise = hash21(float2(floor(context.uv.y * blocks.y), floor(context.time * 5.0))); float tear = (rowNoise * 2.0 - 1.0) * tearAmount * amount * 0.08; float2 offset = float2(tear, (hash21(blockId + 19.0) * 2.0 - 1.0) * amount * 0.025); float2 moshedUv = clamp(context.uv + offset, 0.0, 1.0); float4 previous = sampleTemporalHistory(int(historyFrame), moshedUv); float2 chromaOffset = float2(chromaShift / max(context.outputResolution.x, 1.0), 0.0) * amount; float r = sampleVideo(clamp(context.uv + chromaOffset, 0.0, 1.0)).r; float b = sampleVideo(clamp(context.uv - chromaOffset, 0.0, 1.0)).b; float3 current = float3(r, context.sourceColor.g, b); float blockMask = step(0.35, n) * amount; float3 color = lerp(current, previous.rgb, blockMask); return float4(saturate(color), context.sourceColor.a); }