float2 singularitySpiral(float2 c, float time, float iterator) { float radiusSq = max(dot(c, c), 0.0001); float angle = 0.5 * log(radiusSq) + time * iterator; return float2( c.x * cos(angle + 0.0) + c.y * cos(angle + 11.0), c.x * cos(angle + 33.0) + c.y * cos(angle + 0.0)) / max(iterator, 0.001); } float4 shadeVideo(ShaderContext context) { float2 resolution = max(context.outputResolution, float2(1.0, 1.0)); float2 fragCoord = context.uv * resolution; float safeScale = max(scale, 0.001); float safeRingRadius = max(ringRadius, 0.001); float safeTightness = max(tightness, 0.001); float seed = context.startupRandom; float time = context.time * speed + seed * 37.0; float2 p = (fragCoord + fragCoord - resolution) / resolution.y / safeScale; p -= center + float2(sin(seed * 6.2831853), cos(seed * 6.2831853)) * 0.035; float iterator = 0.2; float2 diagonal = normalize(float2(-1.0 + seed * 0.5, 1.0 - seed * 0.35)); float2 blackholeCenter = p - iterator * diagonal; float gravity = iterator * strength / max(dot(blackholeCenter, blackholeCenter), 0.0001); float2 skew = diagonal / (0.1 + gravity); float2 c = float2(p.x + p.y, p.x * skew.x + p.y * skew.y); float2 v = singularitySpiral(c, time, iterator); float2 waves = float2(0.0001, 0.0001); for (; iterator < 9.0; iterator += 1.0) { waves += 1.0 + sin(v); v += 0.7 * sin(v.yx * iterator + time) / iterator + 0.5; } float diskRadius = length(sin(v / 0.3) * 0.4 + c * float2(2.0, 4.0)); float disk = 2.0 + diskRadius * diskRadius * (0.25 * safeTightness) - diskRadius; float centerDarkness = 0.5 + 1.0 / max(dot(c, c), 0.0001); float rim = 0.025 + abs(length(p) - safeRingRadius) * safeTightness; float4 redBlueGradient = exp(c.x * float4(0.6, -0.4, -1.0, 0.0) * colorShift); float4 waveColor = waves.xyyx; float4 color = 1.0 - exp(-redBlueGradient / max(waveColor, float4(0.0001, 0.0001, 0.0001, 0.0001)) / disk / centerDarkness / rim * brightness); color.a = 1.0; return saturate(lerp(color, context.sourceColor, sourceMix)); }