Simulation · 2025
Solar Simulation
A high-fidelity solar system in modern OpenGL — real ephemerides, physically based shading, volumetric atmospheres.
4.6 GL version
Simulation
2025
Key decisions
- Planets are placed from a truncated VSOP87 ephemeris rather than circles, so eclipses fall out of the simulation for free instead of being staged.
- Atmospheres are ray-marched Rayleigh and Mie scattering instead of a fresnel rim, because that is what makes the terminator read correctly.
- God rays and bloom are composited into the HDR scene before the AgX tonemap, because a god ray added after tonemapping looks painted on.
- An ImGui panel exposes time rate, focus body, exposure and render toggles, because a renderer you cannot inspect is a renderer you cannot debug.
Positions before pixels
The temptation in a solar system renderer is to place planets on circles and
spend everything on shaders. This one starts from a truncated VSOP87
ephemeris — per-planet harmonic series with Meeus-style coefficients in
HighFidelityEphemeris — so the eight major planets are where they actually
are for a given date. The Moon, Titan, Triton, Halley and a 5,000-strong
instanced asteroid belt sit on top of Keplerian elements with secular rates,
and the update runs in two passes: heliocentric bodies first, then moons
relative to their parent’s position. Get the positions right and eclipses fall
out of the simulation for free rather than being staged.
An eclipse you had to script is a special effect. An eclipse that happens because the bodies are where they should be is a simulation.
The shading
Planet surfaces are GGX microfacet — distribution, Smith geometry and a roughness-aware Schlick fresnel — with normal maps, night lights, a specular-ocean mask that drops sea roughness toward 0.045, and cloud shadows sampled from the drifting cloud layer. Atmospheres are not a fresnel rim — they are ray-marched Rayleigh and Mie scattering: up to 48 view samples with a 12-sample light march, exponential density at two scale heights, a Rayleigh phase term and a Mie lobe at g = 0.78, plus a cheap multi-scatter ambient. That is what makes the terminator read correctly and gives the thin blue band at the limb its actual falloff.
The sun carries a billboard corona, and eclipse shadows come from ray-sphere tests against up to four occluders with a penumbra term, so a transit darkens gradually instead of flipping a bit.
The pipeline
Render into a 1.5× supersampled HDR target and downsample. Half-res bright-pass bloom with ping-pong blur, then radial god rays gated on the sun’s screen position and masked by scene depth, then the composite pass: FXAA in HDR, sharpen, a soft shoulder, AgX tonemap, vignette, grain and radial chromatic aberration — in that order, because god rays computed after tonemapping look painted on. Everything stays HDR until the tonemap operator.
Scale is the hard problem in this genre: you need a spacecraft close enough to a surface to see displacement, and Neptune in the same frame. Four sphere LOD tiers from 64×36 up to 512×256, selected by camera distance in planetary radii, plus adaptive near and far clip planes handle it without z-fighting.
An ImGui panel exposes time rate on a logarithmic slider, camera and scale modes, quality presets, exposure, supersampling, FXAA, atmosphere sample counts and the ephemeris mode itself — because a renderer you cannot inspect is a renderer you cannot debug.