Skip to content

thienzz/Cosmos

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

131 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cosmos Explorer

A browser-native, scientifically grounded exploration of the universe at every scale.
Open a tab. Fall into Mercury. Pull the camera back through the asteroid belt, past Pluto, out through the Local Bubble, across the Milky Way, beyond Andromeda, until the cosmic web fills the sky. No installs. No video files. Every pixel is math.

TypeScript React Three.js Vite Rust WebGL 2.0 License


Why this exists

The universe is the most interesting object humans have ever measured, and almost nobody can fly through it.

The polished tools that exist either cost money (SpaceEngine), require an install (Celestia), or pin you to one scale at a time (Stellarium for the night sky, Solar System Scope for the planets, Aladin for catalogues). None of them runs in a browser tab. None of them lets a high-school student go from "what does Titan's surface look like" to "where is M87's jet pointed" in the same camera. None of them treats the universe as one continuous thing.

Cosmos Explorer is what happens when you treat the observable universe as a single scene — moons, planets, asteroids, comets, stars, nebulae, galaxies, clusters, voids, filaments, and the cosmic microwave background, all reachable from one camera, all rendered the same way: procedural GLSL shaders running on the visitor's GPU.

Three commitments shape every line of code:

  1. Real data, every time. Positions come from Gaia DR3, JPL DE441, MPC, NASA Exoplanet Archive, and the SDSS/HyperLEDA catalogues. Coordinates are ICRS J2000.0. Planetary ephemerides go through NASA SPICE kernels when sub-kilometre accuracy is wanted.
  2. No textures, no shortcuts. Every surface — Mars's dust storms, Jupiter's belts, the Crab Nebula's filaments, M51's spiral arms, Sagittarius A*'s accretion disc — is generated by a procedural shader. The download stays tiny; the zoom stays infinite.
  3. The web is the platform. No Electron, no native client, no GPU driver gymnastics. WebGL 2.0 and a logarithmic depth buffer. If your laptop renders a YouTube video, it will render the universe.

The result is meant to work for three audiences at once:

  • The curious can wander. The opening view is the Local Bubble; one drag and you're at Earth, two scrolls and you're inside Saturn's rings, a search and you're at the Crab Pulsar.
  • Educators get a single tool that crosses scales — orbital mechanics, stellar evolution, galactic morphology, and large-scale structure are all the same camera move apart.
  • Researchers and tinkerers get an inspectable, MIT-style stack. Every shader is a .frag file in this repo. Every catalogue is a TypeScript table or a binary tile. Fork it, replace the cosmology model, point the tile server at a different dataset.

What you can run today

Everything below boots in the browser from pnpm --filter web dev:

Demo URL flag What you see
Unified scene (default) / Stellar regime with procedural starfield + named-entity markers + working search + time controls + audio
Solar system ?demo=solarsystem Sun + 8 planets + 5 dwarf planets + 21 named moons + 260 minor bodies, Kepler-propagated at up to 10⁹× real-time, Saturn's rings shaded by particle density
100 K-star tile stream ?demo=starfield The browser fetches binary star tiles, decodes them in a worker, and uploads a THREE.Points cloud — 16 tiles, ~1.5 MB total, one draw call per tile
Planets ?demo=planets Procedural PBR for the 8 solar planets plus exoplanet archetypes — surface noise, atmosphere scattering, ring shading, all GLSL
Moons ?demo=moons Galilean moons, Titan, Enceladus, Triton, the irregular Trojan family, sesquinary captures
Nebulae ?demo=nebulae Volumetric raymarched HII (Hα/OIII/SII), reflection, dark, planetary, supernova remnant
Galaxies ?demo=galaxies Spiral, elliptical, irregular, lenticular morphologies — logarithmic arms, Sérsic bulges, dust lanes, HII knots
Exotic objects ?demo=exotic Black hole with weak-field Schwarzschild lensing (background bends), pulsar with rotating lighthouse beams, magnetar with twisted-dipole helical field
Cosmic web ?demo=cosmicweb Filaments + voids + cluster nodes + Planck-2018-styled CMB boundary sphere

Other things that already work end-to-end:

  • Search — autocomplete with 100-query LRU, full-text, cone search (RA/Dec/radius), keyboard navigation, race-guarded by request id so a slower earlier keystroke can't overwrite the latest.
  • Fly-to — cubic-Bezier with ease-in-out and perpendicular-projection obstacle avoidance; camera lands on the lit hemisphere; Escape cancels mid-flight.
  • TimeplaybackSpeed = sim_seconds/real_seconds, log10 slider from 1× to 10⁹×, jump presets (±1 hr / day / month / year / decade), reverse + reset-to-now, Julian↔Gregorian conversion good through BCE.
  • Live ephemeris — frontend pulls a 730-day window from /v1/ephemeris/range/{naifId}, cubic-Catmull-Rom interpolates between samples for sub-km chord error, falls back to client-side Kepler when the service is down.
  • WebSocket streaming — typed dispatch for ephemeris_push, tile_priority, data_version_update; exponential-backoff reconnect; cache busts on version bumps.
  • Tile streaming — three-tier lookup (in-memory → IndexedDB via Dexie → network), priority queue, LRU eviction on a 192 MB GPU budget and 500 MB disk budget, AbortController on regime change.
  • Procedural audio — Tone.js scale-regime soundscapes that crossfade through Solar System → Stellar → Galactic → Cosmic, master / ambient / effects channels, mute, AUD-001 user-gesture compliance.
  • Post-processing — HDR Float16 buffer → bloom pyramid → ACES tonemap → optional FXAA / chromatic aberration / film grain / scanlines / vignette / Schwarzschild lensing, every effect a flat #define so the composite shader stays branchless.
  • Accessibility — skip links, reduced-motion media query → static visuals, high-contrast media query → CRT effect off, aria-live announcements on every selection / fly-to / search.
  • Tests — 700+ Vitest unit tests across the web app, 18 Rust integration tests on the tile server, Playwright E2E covering search → fly-to → ephemeris → WebSocket happy-paths.

What is not yet built (and what the roadmap covers): full Gaia DR3 ingestion, the 4 M HyperLEDA / SDSS galaxy tile pyramid, the 1.3 M MPC asteroid catalogue, deployed backend services, and the polish pass on the long tail of exotic-object shaders.


Architecture

┌────────────────────────────────────────────────────────────────────┐
│  apps/web — React 18 + Three.js r184 + Zustand + Vite              │
│  ────────────────────────────────────────────────                  │
│  React UI (declarative)   ←  Zustand stores  →   Three.js rAF      │
│                                  ↕                                 │
│                          Web Workers                               │
│              tile decoding · search · physics                      │
└──────────────┬─────────────────────────────────────────────────────┘
               │  HTTP/2 binary tiles + WebSocket (viewport / time)
┌──────────────┴─────────────────────────────────────────────────────┐
│  apps/api          — Fastify API gateway                           │
│  apps/tile-server  — Rust / axum, 50k req/s target                 │
│  apps/ephemeris    — FastAPI + SpiceyPy (JPL SPICE / DE441)        │
│  apps/etl          — Python ingestion (Gaia DR3, SDSS, MPC, JPL)   │
│                                                                    │
│  PostgreSQL 16 + PostGIS 3.4 · Redis 7 · Elasticsearch 8           │
└────────────────────────────────────────────────────────────────────┘

The two-loop problem. React's reconciliation loop and Three.js's requestAnimationFrame loop are different paradigms running side by side. They bridge through Zustand stores using a state-temperature model — hot state (camera, time) read via getState() with zero subscriptions, warm state (selection, search) throttled at 100 ms, cool state (mode, regime) via standard React subscriptions, cold state (settings, bookmarks) persisted to IndexedDB.

Camera-relative rendering. Every frame subtracts the camera's world position before uploading geometry to the GPU, so float32 doesn't collapse 13.8 Gly away.

Logarithmic depth buffer. A standard 24-bit depth buffer z-fights from astronomical unit scale to gigaparsec scale. gl_FragDepth = log2(z) * logDepthBufFC * 0.5 solves it; every shader writes it under #ifdef USE_LOGARITHMIC_DEPTH_BUFFER.

Scale-regime state machine. Solar System ↔ Stellar ↔ Galactic ↔ Cosmic, each transition gated by a hysteresis band that swaps LOD, tile filters, and ambient audio without flicker.


Quick start

# 1. Copy the environment template.
cp .env.example .env

# 2. Install dependencies (pnpm workspaces).
pnpm install

# 3. Frontend only — runs against mocked API, every demo works.
pnpm --filter web dev

# 4. With backend (Postgres + Redis + Elasticsearch + API + tile-server + ephemeris).
docker compose -f infra/docker/docker-compose.yml up -d
pnpm --filter web dev

Open http://localhost:5173. Try ?demo=solarsystem, ?demo=nebulae, ?demo=exotic to see the gallery scenes.

Useful commands

pnpm test                  # Vitest across the workspace
pnpm --filter web test:e2e # Playwright
pnpm typecheck             # tsc --noEmit, strict
pnpm lint                  # ESLint + Prettier
pnpm build                 # Turborepo production build

Repository layout

cosmos-explorer/
├── apps/
│   ├── web/           # React + Three.js renderer
│   ├── api/           # Fastify API gateway
│   ├── tile-server/   # Rust tile server (50k req/s target)
│   ├── ephemeris/     # Python ephemeris (FastAPI + SPICE)
│   └── etl/           # Python ingestion DAGs
├── packages/
│   ├── api-client/        # Generated from OpenAPI
│   ├── tile-decoder/      # Binary tile format
│   ├── coordinate-utils/  # ICRS J2000.0 ↔ Cartesian, Kepler solver
│   └── shared-types/      # Cross-package TypeScript types
├── data/
│   ├── catalogs/          # Constellations, named stars, NGC/IC, Messier
│   ├── seeds/             # Bundled bright-star + solar-system seed data
│   ├── spice/             # JPL SPICE kernels (Git LFS, ~600 MB)
│   ├── tiles/             # Pre-baked demo tiles (100K stars)
│   └── fixtures/          # Test fixtures
└── infra/docker/          # docker-compose for local dev

Roadmap

The project is organised into four work tracks. Each track ships incrementally; the frontend already runs against mocked data while the backend tracks catch up.

Track A — Backend foundation (in progress)

Status Milestone
Monorepo scaffold (pnpm + Turborepo), TypeScript strict, ESLint, Prettier
Docker Compose for Postgres + PostGIS, Redis, Elasticsearch, API gateway
Fastify health checks + structured logging
Alembic migrations baseline
CI workflow (lint + typecheck + test + Rust build)
Backend deployed (staging)
Auth tiers (anonymous / registered / research)

Track B — Data ingestion (not started)

Status Milestone
Gaia DR3 streaming ingestion (~1.8 B stars → tile pyramid)
SDSS DR17 + HyperLEDA galaxy ingestion (~4 M galaxies)
MPC asteroid catalogue (~1.3 M small bodies)
NASA Exoplanet Archive (5.8 K confirmed exoplanets, joined to Gaia host stars)
IllustrisTNG cosmic-web mesh import
Airflow DAGs for nightly refresh

Track E — Tile pyramid + streaming (scaffold done, demo working)

Status Milestone
Binary tile format (float16 coords, packed magnitude/colour/spectral)
Tile decoder package with native + software float16
Rust tile server (axum) — stars / galaxies / cosmic-web endpoints, ETag, brotli, CORS
TileStreamingManager — priority queue, three-tier cache, LRU eviction
100 K-star pre-baked demo tiles
HEALPix order/pixel addressing for galaxies
Dev-mode middleware serves data/tiles/* without the Rust server
PgBouncer pooling for high-concurrency tile reads
CDN-fronted tile distribution

Track V — Visual coverage (majority shipped)

The visual side is the most mature. Every shader is procedural; together they cover the 9 entity families from the spec.

Status Family What's done
Stars Point-sprite shader with Ballesteros B-V → temperature → Tanner-Helland blackbody RGB (ΔE76 ≤ 3 per spectral class); plus extended star-type gallery
Solar system 296-body catalogue, client Kepler propagator with parented moons, Saturn ring system
Planets Procedural PBR for 8 solar planets + exoplanet archetypes (Hot Jupiter, Super-Earth, Hycean, …)
Moons Galilean, Titan, Enceladus, Triton, Trojan, sesquinary, shepherd variants
Small bodies Asteroid field renderer + named comets
Nebulae Volumetric raymarching for emission / reflection / dark / planetary / supernova
Galaxies Spiral / elliptical / irregular / lenticular morphologies + AGN / morphology-special variants; LOD ladder volumetric → billboard → point
Exotic Black hole + Schwarzschild lensing post-pass, pulsar, magnetar, quasi-star, primordial / Planck / topology / TZO variants
Large-scale structure Cosmic web filaments + voids, cluster collision, OB / open / globular cluster shaders
CMB Planck-2018-styled boundary sphere (false-colour temperature, optional dipole)
Polish pass Long-tail uniform tuning, exotic-object accuracy reviews, FU Ori / Herbig Ae/Be variants

Track UX — Interaction and craft (continuing)

Status Milestone
Search (autocomplete, full-text, cone) with race-guarded request ids
Fly-to with obstacle avoidance, lit-hemisphere arrival
Time controls (log slider, jump presets, reverse, reset-to-now)
Live ephemeris (730-day cached window, cubic interp, Kepler fallback)
WebSocket (ephemeris push, tile priority, data-version invalidation)
Post-processing chain (bloom, FXAA, CA, vignette, scanlines, lensing)
Procedural ambient audio per scale regime
Accessibility — skip links, reduced motion, high contrast, aria-live
Guided tours (narration timeline, scripted camera + UI choreography)
Bookmarks + shareable deep links
Mobile + touch input polish

Beyond that, the long-term ambition is the full census: the 1.8 B-star Gaia stream, the 4 M-galaxy HEALPix pyramid, the 1.3 M MPC catalogue, the IllustrisTNG mesh, and the 5.8 K confirmed exoplanets parented to their Gaia host stars — all reachable from the same camera.


License

License is not yet finalised. If you'd like to use any part of this work, open an issue.


Built with TypeScript, Three.js, and a logarithmic depth buffer.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors