Whirlpool (precision-stable)

Left to run, the whirlpool slowly turns grainy and chunky, worst near the center. That isn’t in the design — the iTime term adds a uniform angular offset, so the vortex should spin rigidly without ever changing detail. The decay is a numerical artifact:

  • iTime * 0.3 grows without bound, so cos=/=sin lose precision in their fractional argument as the magnitude climbs.
  • step(0.5, sw) is a hard, un-antialiased edge, so any coordinate error gets thresholded into a full pixel flip — and the quadrant boundaries pack tightest near the center, where the speckle shows first.

Two changes fix it, shown here via #+attr_diff as a changeset from the whirlpool — wrap the time angle so cos=/=sin never see a large argument, and swap step for an fwidth-scaled smoothstep so precision noise no longer flips whole pixels:

Diff: whirlpool-shader → whirlpool-stable-shader
--- whirlpool-shader
+++ whirlpool-stable-shader
@@ -1,20 +1,23 @@
 void mainImage( out vec4 fragColor, in vec2 fragCoord )
 {
   vec2 uv = fragCoord/iResolution.xy; // <0,1>

   vec2 p = uv - 0.5; // recenter so the swirl pivots on the middle
   float r = length(p); // distance from the center
   float a = atan(p.y, p.x); // current angle

-  // twist harder near the center, and let it flow slowly over time
-  a += 6.0 * exp(-3.0 * r) + iTime * 0.3;
+  // twist harder near the center; wrap the time term to one full turn so
+  // cos/sin never see a large argument (one revolution looks identical)
+  a += 6.0 * exp(-3.0 * r) + mod(iTime * 0.3, 6.2831853);

   // rebuild swirled coordinates back in <0,1>
   vec2 sw = vec2(cos(a), sin(a)) * r + 0.5;

   vec3 col = vec3(0); // start with black
-  col = vec3(step(0.5, sw), 0); // same quadrant step, now on the whirlpool
+  vec2 aa = fwidth(sw); // pixel footprint of the swirled coords
+  vec2 e = smoothstep(0.5 - aa, 0.5 + aa, sw); // antialiased quadrant edge
+  col = vec3(e, 0); // same quadrants, now without the speckle

   // Output to screen
   fragColor = vec4(col,1.0);
 }
// settings
theme:
fx: