feat: replace Julia Set and Mandelbrot with Julia Family, a slice of parameter space (#209) - #287
Merged
Merged
Conversation
…parameter space (#209) Five 1200x1200 bands on the 5:1 wall, each a complete Julia set, c stepping across a short line through parameter space centred on a boundary waypoint. The row therefore spans the connected/dust transition -- visible in a single frame, not only over time -- and sweeps as the centre travels between waypoints. Measured at 6000x1200 on a real GPU: 65.2 fps. Readable at 12% washout. ## The three decisions #209 asked to be recorded Composition C, dive-with-following-Julia, and replace both savers. Two of them needed qualifying, and both qualifications are in the module header: **C needed reinterpreting.** Taken literally -- c varying per pixel column -- a Julia set gets one vertical line per parameter and the frame is a smear, because a Julia set needs both dimensions of the z-plane. Built as bands instead, which is what the 5:1 aspect divides into squares anyway. **The dive could not be kept.** A Julia iteration adds c to an O(1) z every step, so at a 2^80 zoom the bands' c values differ by ~1e-24 and are indistinguishable in float32 from each other and their shared base: every band would render the same set from about the 17th doubling. Recovering it needs perturbation theory per band, five CPU reference orbits, far beyond this issue. What #121 contributes is its curated boundary coordinates, which is the property that matters here -- a window centred on one straddles the boundary, which is what makes the transition exist at all. So mandelbrot.js is deleted and nothing inherits the deep zoom. That was confirmed explicitly after the precision limit was known. One criterion C makes moot: "the c marker is clearly visible and unmistakably tied to the Julia view". There is no map under C, so there is nothing to mark. ## The first render failed the washout criterion It came out as a flat saturated orange field with the sets sitting on top -- the worst possible starting point for 12% ambient, and nothing for bloom to pick out because everything was already bright. Fading the far exterior to black put the light where the structure is: dark interior, bright boundary filigree, which is both the classic rendering and the one that survives a lit room. No frame-rate cost. ## Re-measuring the baselines found them stale `npm run baselines` rewrites all entries, so this re-measured the whole set -- and several were well out of date, all from savers changed earlier today: Flow Field 0.0872 -> 0.1388 (#228) Raymarch Fractal 0.0081 -> 0.0186 (#230) Reaction Diffusion 0.0149 -> 0.034 DVD Logo 0.0026 -> 0.0065 (#252) Stale baselines make the check UNDER-protective: Raymarch's real density is 0.0186 against a recorded 0.0081, so it could have halved and still passed. Two consequences worth naming rather than absorbing: Julia Family measures 0.0001, which puts it under STRUCTURE_MIN_ABS_DROP and so outside the density-drop rule, alongside Plasma and Wave Tank. That is a direct cost of the darkening above. The uniform-spread rule from #227 exists for exactly this blind spot and does still apply, and this saver has wide spread by construction. Wave Tank moved from exactly 0 to 0.0007. Both readings mean "no edges"; it landed either side of zero on two runs, and only the exact zero took the separate zero-baseline branch. That is what actually broke the pinned "only one saver below the margin" invariant, which is now updated to the measured set of three with the reasoning recorded. ## Everything that counts savers registry.js, structure-baselines.js, the user guide list renumbered to 29 with Julia Family at position 5, both count claims in the guide and README, and the shader-saver file list in screensaver-seed.test.js. 675 tests pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #209.
Five 1200×1200 bands on the 5:1 wall, each a complete Julia set,
cstepping across a short linethrough parameter space centred on a boundary waypoint. The row spans the connected/dust
transition — visible in a single frame, not only over time — and sweeps as the centre travels.
65.2 fps at 6000×1200 on a real GPU. Readable at 12% washout.
The three decisions, and the two that needed qualifying
Composition C needed reinterpreting. Literally —
cvarying per pixel column — each columngets one vertical line of its Julia set and the frame is a smear, because a Julia set needs both
dimensions of the z-plane. Built as bands, which is what 5:1 divides into squares anyway.
The dive could not be kept. A Julia iteration adds
cto an O(1)zevery step, so at 2⁸⁰the bands'
cvalues differ by ~1e-24 — indistinguishable in float32 from each other and theirshared base. Every band would render the identical set from about the 17th doubling. Recovering it
means perturbation theory per band, five CPU reference orbits, far beyond this issue's scope.
What #121 contributes is its curated boundary coordinates, which is the property that matters:
a window centred on one straddles the boundary, which is what makes the transition exist at all.
mandelbrot.jsis deleted and nothing inherits the deep zoom — confirmed explicitly after theprecision limit was known.
One criterion C makes moot: "the
cmarker is clearly visible and unmistakably tied to theJulia view". There's no map under C, so there is nothing to mark.
The first render failed the washout criterion outright
A flat saturated orange field with the sets sitting on it — the worst starting point for 12%
ambient, and nothing for bloom to pick out because everything was already bright. Fading the far
exterior to black put the light where the structure is: dark interior, bright boundary filigree.
Classic rendering, survives a lit room, no frame-rate cost.
Re-measuring the baselines found them stale
npm run baselinesrewrites every entry, so this re-measured the whole set — and several werewell out of date, all from savers changed earlier today:
Stale baselines make the check under-protective. Raymarch's real density is 0.0186 against a
recorded 0.0081 — it could have halved and still passed.
Two consequences named rather than absorbed:
Julia Family measures 0.0001, under
STRUCTURE_MIN_ABS_DROP, so it sits outside thedensity-drop rule alongside Plasma and Wave Tank. That is a direct cost of the darkening above.
The uniform-spread rule from #227 exists for exactly this blind spot and still applies, and this
saver has wide spread by construction. Annotated next to the number so a future reader doesn't
think it's broken.
Wave Tank moved from exactly 0 to 0.0007. Both readings mean "no edges" — it landed either
side of zero on two runs, and only the exact zero took the separate zero-baseline branch. That is
what actually broke the pinned "only one saver below the margin" invariant, now updated to the
measured set of three with the reasoning recorded.
Everything that counts savers
registry.js,structure-baselines.js, the guide list renumbered to 29 with Julia Family atposition 5, both count claims in the guide and README, and the shader-saver file list in
screensaver-seed.test.js. 675 tests pass, lint clean including the GLSL template check.What I could not verify
The rotation actually reaching it in the app, and the waypoint walk over a full ten-minute slot —
both stills here are 5–6 seconds in. The band count adapting to other aspects (2 on 16:9, 1 on
square) is arithmetic I have read but not rendered.