Add gravitational-lensing prototype (SIS thin-lens, vertex-stage)#361
Open
rulkens wants to merge 2 commits into
Open
Add gravitational-lensing prototype (SIS thin-lens, vertex-stage)#361rulkens wants to merge 2 commits into
rulkens wants to merge 2 commits into
Conversation
Deflect background galaxies around a foreground lens directly in the points vertex stage, where each source's distance from the camera and the lens is known. This makes the effect physically honest: only sources *behind* the lens are bent, and the deflection scales with D_ls/D_s — the kind of distance-dependence a screen-space post-process pinch filter can't express (it would bend the foreground and Milky Way too). The lens model is a singular isothermal sphere (SIS): constant Einstein deflection theta_E, source at separation beta imaged outward to theta = beta + theta_E, so sources near the line of sight pile into an Einstein ring. A Gaussian envelope (~3 theta_E) localises the effect so an idealised SIS doesn't shift the whole sky. New helper: shaders/lib/lensing.wesl. Prototype shortcuts (to be formalised in a spec/plan): - Lens centre is the camera orbit target (the thing you've zoomed into), not a mass-weighted cluster. - theta_E is a UI-exaggerated angle in degrees (real cluster Einstein radii are ~arcseconds, invisible at zoom). - Only the SIS primary image is rendered; the inner counter-image and NFW profiles are follow-ups. Wiring: - io.wesl Uniforms gains a lensing block appended at offset 176 (struct grows 176 -> 208 bytes); picker in-place writes are all < 176 so they stay valid and picking lenses with the same params. - pointRenderer packs lensCenterWorld/lensEnabled/lensThetaE; threaded via PointDrawSettings + pointSpritesPass. - Toggle + exaggerated Einstein-radius slider live in the Debug panel (debug settings cluster), off by default. Settings auto-wake the renderer via the existing WAKE_ROUTES. Tests updated for the new debug fields + PointDrawSettings; full suite green (2978 tests). WESL link validated via the real wesl-plugin under vitest (pointRenderer test imports points/vertex.wesl?static). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7a4Pwz8yTrDtRcwGtojZb
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
skymap | 95f4c16 | Commit Preview URL Branch Preview URL |
Jun 23 2026, 10:45 PM |
Extends the lensing prototype with the Navarro–Frenk–White profile and a
mode switch. NFW deflection follows the closed-form g(x)/x (Wright &
Brainerd 2000): it rises from the core, peaks near the scale radius r_s,
then falls as ~ln(x)/x — the curvature that gives real clusters an inner
radial critical curve, which SIS's constant deflection can't produce.
Computed analytically in the shader rather than via a baked 1D LUT: it's
a few transcendentals per vertex (cheap) and avoids forcing a
texture+sampler bind group onto the SHARED pick pipeline (the pick pass
reuses points/vertex.wesl). arccosh(1/x) is expanded to its log form so
only core WGSL log/acos/sqrt are needed. The shape is peak-normalised
(÷0.3122) so the strength knob reads as peak deflection in BOTH modes —
toggling SIS↔NFW keeps the ring roughly sized and only changes profile.
The behind-lens gate, D_ls/D_s distance scaling, and distance-preserving
displacement are profile-agnostic and unchanged. NFW needs no Gaussian
envelope — g(x)/x self-localises at both small and large x.
Wiring:
- lib/lensing.wesl: nfwShape() + lensDeflect() gains mode + scaleRadiusMpc.
- io.wesl: two reserved pad slots become lensMode (u32) + lensScaleRadius
(f32) — NO struct size change (still 208 bytes), pick offsets untouched.
- New LensMode type ('sis'|'nfw'); debug settings gain lensMode +
lensScaleRadiusMpc with slice actions, selectors, defaults.
- DebugPanel lensing section gains an SIS/NFW radio toggle and an
NFW-only scale-radius slider (hidden in SIS mode).
Full suite green (2978 tests); typecheck + prettier clean. WESL link
validated via the real wesl-plugin under vitest.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7a4Pwz8yTrDtRcwGtojZb
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.
Deflect background galaxies around a foreground lens directly in the
points vertex stage, where each source's distance from the camera and
the lens is known. This makes the effect physically honest: only sources
behind the lens are bent, and the deflection scales with D_ls/D_s — the
kind of distance-dependence a screen-space post-process pinch filter
can't express (it would bend the foreground and Milky Way too).
The lens model is a singular isothermal sphere (SIS): constant Einstein
deflection theta_E, source at separation beta imaged outward to
theta = beta + theta_E, so sources near the line of sight pile into an
Einstein ring. A Gaussian envelope (~3 theta_E) localises the effect so
an idealised SIS doesn't shift the whole sky. New helper:
shaders/lib/lensing.wesl.
Prototype shortcuts (to be formalised in a spec/plan):
not a mass-weighted cluster.
radii are ~arcseconds, invisible at zoom).
NFW profiles are follow-ups.
Wiring:
grows 176 -> 208 bytes); picker in-place writes are all < 176 so they
stay valid and picking lenses with the same params.
via PointDrawSettings + pointSpritesPass.
(debug settings cluster), off by default. Settings auto-wake the
renderer via the existing WAKE_ROUTES.
Tests updated for the new debug fields + PointDrawSettings; full suite
green (2978 tests). WESL link validated via the real wesl-plugin under
vitest (pointRenderer test imports points/vertex.wesl?static).
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01Q7a4Pwz8yTrDtRcwGtojZb