Skip to content

Attractor depth: perspective, depth_fade, depth_hue, spin

Three of these four are exact no-ops on every flat family, the same way a b c d already carry family-specific meanings. perspective, depth_fade and depth_hue do something only on the 3-D families — thomas and lorenz. On de_jong, clifford and the five IFS figures they are exactly the identity: those maps have no third coordinate, so the engine hands the shader a depth extent of zero and every cue collapses to a no-op. Binding them there is not an error and produces no warning — it produces nothing at all. (Verified by capture: at any setting, zero pixels differ — asserted for all three in core/tests/attractor.rs.)

depth_fade is a no-op on a flat family too, and the arithmetic is why it once was not (design-backlog 0067). The haze is 1 − depth_fade · (1 − depth01(dn)), and a flat family’s dn ≡ 0 would put the multiplier at 1 − depth_fade/2, so depth_fade = 0.9 would dim a flat figure 45 % everywhere with no depth gradient (measured on attractor_dissolve: 20.1 % of pixels moved, max channel delta 97, while perspective and depth_hue moved zero). The fade term is now multiplied by the family’s has-depth flag, so all three cues are the identity together. If an old draft leaned on the dimming as an undocumented brightness trim on a flat family, it silently brightened back — exposure is the parameter that means “dimmer” and says so.

spin is the exception and reaches every family. The flat ones rotate in-plane through the same angle, so an audio-driven spin is a real look on De Jong today, and a fern that rocks a couple of degrees either side of upright reads as wind. That asymmetry is deliberate; do not read it as an oversight.

ParamWhat it doesRange that means something
perspectiveNear material grows and far material shrinks, position and point size together. Segments foreshorten, because both endpoints project independently.0 (orthographic, the default) .. ~0.3 in practice; the clamp is at 0.8 and the reason to stop short of it is below
depth_fadeAttenuates brightness with distance — the substitute for occlusion, which this scene does not do. 1 takes the far end to black.0 (off) .. 1
depth_hueShifts the palette coordinate by ±depth_hue/2 across the depth range, so distance moves colour as well as contrast — on a ramp that travels in hue at roughly constant lightness. On a dark-to-light ramp (which is what the 3-D presets have shipped) it duplicates depth_fade instead, and under ink_amount = 1 it is structurally dead, like saturation. design-backlog 00620 (off) .. 2 * min(hue_center, 1 - hue_center), past which the offset wraps on the LUT’s repeat sampler and far material lands on the near colour
spinRate multiplier on the display rotation. 1 is unchanged, 0 holds the figure still, negative reverses it.any

Four things you cannot discover by binding them:

  • perspective is clamped at 0.8, silently. A preset asking for more gets the ceiling, not a warning — the same undiscoverable-ceiling shape bloom_threshold and vigor already carry. The number means the figure’s depth half-extent as a fraction of the camera distance, so the near-to-far magnification ratio is (1 + p) / (1 - p): 0.5 gives 3:1, 0.8 gives 9:1, and the singularity would be at 1.

  • perspective mostly MOVES the figure, and a zoom edit cannot recover that. The magnification is applied before the view transform, so raising it does make the figure bigger — but that is the small half. Measured peak-to-peak over four spin phases on a bare Lorenz, 600 px square:

    perspectivecentre-x swingwidest span
    0.000.04 NDC522 px
    0.150.11 NDC525 px
    0.250.20 NDC529 px
    0.400.37 NDC542 px
    0.600.55 NDC555 px

    The near side is magnified, so the projected centroid shifts toward whichever side is currently near — and as the figure turns, that shift orbits. The swing is about 0.9 x perspective in NDC; the size growth across that whole sweep is 6 %. A zoom is a static scale, so it cannot recover a phase-varying translation: all it can do is shrink the figure until the orbit fits inside the frame, which is what the 3-D presets paid for (attractor_lorenz, since retired, went 1.32 -> 1.16; attractor_thomas 1.14 -> 1.02). So the real ceiling is ~0.3, not the 0.8 clamp — past that the figure visibly slides around the frame instead of turning in place, which is a worse artifact than the flatness perspective was bought to fix. The clamp is not where the projection breaks; at 0.8 it is still a true perspective divide and reads as a strong wide angle, not a fisheye. This ceiling note is design-backlog 0061’s documented resolution; the deeper fix — re-centring the projection on the figure’s projected centroid — remains unowned.

  • spin is a multiplier on 0.18 rad/s (spin = 1 is one revolution per 34.9 seconds), and its usable ceiling is set by fade, not by taste — spin and fade are one look. A frame of trail drawn while the figure turns is a frame of rotational smear: push the pair too far and the accumulation stops being a trace of the trajectory and becomes concentric arcs, which destroys exactly the volume perspective was bought to buy. Measured: at fade = 0.932 (~15 frames of trail) the rendered ladder 1 / 2 / 3 / 5 / 8 reads crisp, crisp, softening, smeared, scribble — usable peak about 1.9; attractor_thomas runs fade = 0.955 (~22 frames) and its ceiling is correspondingly lower, about 1.3. The arithmetic agrees: holding the smear under ~5° needs rate < 0.087 / (frames / 60) rad/s, so the ceiling falls as fade rises. (This bullet used to say 24 is where the rotation becomes legible — true for a trail-free scene, wrong for every attractor preset that ships; design-backlog 0063.) The phase is integrated, so a spin bound to audio accelerates the figure rather than snapping it to a new angle — but the integration fixes the discontinuity, not the range: a wide binding like 1 + bass * 5 swings the figure through most of a revolution between transients and reads as tumbling, not drive. The 3-D presets have modulated narrowly (the since-retired Lorenz 1.01.8, Thomas 1.01.3).

  • The illusion has a density limit and haze does not remove it. Nothing occludes anything here — two strands crossing simply sum — so as [particles] density rises the figure reads more and more as X-ray whatever these are set to. If depth stops reading, lower density before raising perspective.

Built from a8ce055 at version 0.115.0. This site tracks main and is not versioned per release.