Skip to content

GalaxyJS 3.4.0 "Optics" — an optional three.js tier + 6 scenes (80 → 86) - #6

Merged
Edwson merged 5 commits into
mainfrom
release/v3.4.0
Aug 7, 2026
Merged

GalaxyJS 3.4.0 "Optics" — an optional three.js tier + 6 scenes (80 → 86)#6
Edwson merged 5 commits into
mainfrom
release/v3.4.0

Conversation

@Edwson

@Edwson Edwson commented Aug 7, 2026

Copy link
Copy Markdown
Owner

What's in it

Six new animations (80 → 86) on a new, optional three.js tier. The library still has zero required dependencies.

registerAnimation now accepts renderer: "three", and registerThree(name, { defaults, scene }) gives a scene the same lifecycle every other animation gets. three.js is fetched by dynamic import() the first time such a scene mounts — once per page, shared by all six. A page that never mounts one requests nothing. If the load fails, the surface paints a still poster, exactly as the WebGL2 tier degrades when WebGL2 is missing.

Galaxy.useThree(THREE);                              // bring your own — no network
Galaxy.create("spiralForge", "#hero", { threeUrl })  // or point elsewhere
Galaxy.rendererOf(name)                              // "2d" | "webgl2" | "three"

Each of the six does something the 2D and fragment-shader tiers genuinely cannot:

Scene What is actually real
eventHorizon photons integrated through the Schwarzschild metric (d²u/dφ² = -u + 3/2·rs·u²) — photon ring, Einstein ring and the lensed far side of the disk emerge from the geodesics; Doppler beaming (I ∝ δ⁴) gives the real asymmetry
molecularCloud a 128³ Data3DTexture raymarched in local space, lit from within by an embedded protostar via a secondary Beer–Lambert shadow ray + Henyey–Greenstein phase — true parallax and self-occlusion
spiralForge 340,000 stars in one draw call, orbits integrated in the vertex shader against a flat rotation curve; arms shear because ω varies with radius; blackbody colour from a mass–temperature relation
ringedWorld Rayleigh single scattering (blue limb, reddened terminator) and mutual shadowing — ring shadow on the planet carrying its own gaps, planet shadow on the rings, from one shared density function
gravitySim GPGPU: state lives in float render targets and never returns to the CPU; symplectic leapfrog keeps orbits stable; two attractors on an eccentric Kepler orbit raise tidal tails each pericentre
starGlare a hand-rolled HDR chain, no addons — bright pass, progressive bloom, anamorphic streak, chromatic aberration, filmic tonemap

Also fixed

A shader whose program failed to build crashed instead of falling back. glPosterFallback reached for the 2D context unconditionally, but a canvas that already has a live WebGL2 context can never hand one back — so the "graceful" path threw Cannot set properties of null. This affected the WebGL2 tier as shipped in 3.3.0, not just the new one. The poster now paints the host element with the equivalent CSS gradient when there is no 2D context.

Verification

  • npm run validate green: manifest → lint (0 errors) → minify → test.mjstest-mcp.mjs
  • new tests assert the tier stays optional: three is not a dependency, is never statically imported, is loaded by dynamic import, and — because terser had already dead-code-eliminated it once — that the minified bundle still contains it
  • all six rendered headless and inspected, with the CDN intercepted so the real lazy-import path runs offline
  • contracts measured, not assumed: under prefers-reduced-motion all six paint a real still frame with zero rAF ticks; with three.js unreachable all six fall back to a poster with no throws

Counts

86 animations — 2D 72 · WebGL2 8 · three.js 6 (optional). Also adds the PR/issue templates and dependabot config, which existed locally but had never been pushed.

@Edwson
Edwson merged commit a68839a into main Aug 7, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant