Live: https://3dsolarsystem.online
A real-time photorealistic solar system viewer built with Three.js and a lot of custom GLSL. Started as a weekend project, ended up touching pretty much every photoreal-rendering trick
that runs at 60 FPS in WebGL. Sharing because some of the techniques might be useful to others.
Highlights
Hillaire-style atmospheric scattering — ray-traced planet shadow on the atmosphere shell (the night side has a true geometric umbra cone, not a smoothstep falloff), chord-length
Beer-Lambert per-wavelength extinction along the view ray so the limb actually reddens at the terminator instead of being painted orange.
OKLCh perceptual gradient mixing everywhere — shared GLSL snippet drives the aurora’s green<->pink-violet curtain, the Milky Way disc gradient, Saturn ring band colours, reflection
nebulae, the wormhole lensing chain. Bujack 2025’s non-Riemannian colour-space paper translates to ~30 lines of shader and noticeably cleaner mid-tones on every wide-hue gradient.
8K NASA Earth + procedural sub-texel detail — Solar System Scope 8K daymap/clouds/night, NASA GEBCO 8K topography, Solar System Scope 8K normal map. Fragment-shader fbm overlay
synthesises infinite-zoom detail beyond the texel grid when the camera is at ISS altitude. Earth vertex shader uses the GEBCO elevation map for actual vertex displacement so mountains
deform the silhouette at the limb (not just painted-on shading).
Multi-step horizon-shadow ray-march on the Earth surface gives the Himalayas / Andes / Rockies dramatic long shadows at sunrise/sunset.
Parent-planet eclipse shadow on moons with blood-moon Beer-Lambert tint — light reaching an eclipsed Moon is refracted through Earth’s atmosphere, Rayleigh strips blue/green leaving
the deep red. Same shader handles Jupiter’s umbra colouring the Galilean moons during their eclipses.
Procedural cloud detail on gas giants — band-aligned fbm that fades in as the camera approaches Jupiter / Saturn / Uranus / Neptune. Unbounded zoom because detail is synthesised at
the fragment level.
Cone-curtain aurora ribbons over the magnetic pole with OKLCh-mixed altitude-stratified colour and longitudinal fold noise.
ISS + Voyager from NASA’s free 3D-Resources glTF library — and a fun float-precision fight at ISS close zoom (camera ~0.0001 scene units from an object at world ~142 units) solved
with a proxy-camera origin-shift render pass that swaps RenderPass.camera for a local-coordinate clone right before composer.render().
Custom MAX quality preset — full DPR, 8× MSAA, FXAA stacked on SMAA, 256-segment planet spheres, 192-segment atmosphere. Targets workstation GPUs.
Other features
- Three-zone Earth terminator (warm extinction tint + asymmetric day/night mask + cyan twilight limb arc)
- City-light micro-flicker on the night side
- Constellation overlay (Hipparcos + IAU lines)
- 33-object deep-sky catalogue with NASA / Hubble imagery
- JPL ephemeris-driven planet orbits
- Photo mode, scale-realistic mode, screensaver mode
Open to feedback — and especially curious if anyone has tackled the WebGL orbital-distance precision problem more elegantly than camera origin-shift. Repo + write-up coming once I tidy
up.
Built with: Three.js, custom GLSL shaders, GSAP, Tone.js, Vite, deployed to Vercel.