Files
video-shader-toys/shaders/trigger-ripple/shader.slang
Aiden 6502344d0a
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 1m33s
CI / Windows Release Package (push) Successful in 2m4s
Added trigger
2026-05-06 14:01:23 +10:00

35 lines
1.5 KiB
Plaintext

float4 shadeVideo(ShaderContext context)
{
if (drop <= 0)
return context.sourceColor;
float age = max(context.time - dropTime, 0.0);
float2 aspect = float2(context.outputResolution.x / max(context.outputResolution.y, 1.0), 1.0);
float2 fromDrop = (context.uv - center) * aspect;
float radius = length(fromDrop);
float2 c0 = (float2(0.0, 0.0) - center) * aspect;
float2 c1 = (float2(1.0, 0.0) - center) * aspect;
float2 c2 = (float2(0.0, 1.0) - center) * aspect;
float2 c3 = (float2(1.0, 1.0) - center) * aspect;
float maxRadius = max(max(length(c0), length(c1)), max(length(c2), length(c3)));
float progress = saturate(age / max(speed, 0.001));
float waveRadius = progress * maxRadius;
float distanceToWave = radius - waveRadius;
float waveWidth = max(width * maxRadius, 0.0001);
float ring = (1.0 - smoothstep(waveWidth, waveWidth * 1.65, abs(distanceToWave))) * exp(-progress * damping * 0.35);
float crest = 1.0 - smoothstep(0.0, waveWidth * 0.35, abs(distanceToWave));
float ripple = ring * (distanceToWave >= 0.0 ? 1.0 : -0.55);
float2 direction = radius > 0.0001 ? fromDrop / radius : float2(0.0, 0.0);
float2 uvOffset = direction * (ripple * strength);
uvOffset.x /= aspect.x;
float2 refractedUv = clamp(context.uv - uvOffset, float2(0.0, 0.0), float2(1.0, 1.0));
float4 refracted = sampleVideo(refractedUv);
float highlight = saturate(ring * 0.75 + crest * 0.55);
refracted.rgb += highlight * 0.075;
return saturate(refracted);
}