Solar System Simulator

Project Type: Personal Project
Engine: Unity 6 (6000.4.5f1)
Frameworks: Unity DOTS (Entities, Burst, Jobs), URP 17.4
Languages: C#, HLSL
Role: Sole Developer
Status: In Development
Solar System Simulator

About

A real-time solar system simulation built in Unity 6 using the Data-Oriented Technology Stack (DOTS/ECS). The simulation models a star, all major planets, and a dense asteroid belt of 100,000+ bodies, all governed by Keplerian orbital mechanics and rendered with fully procedural shaders. No pre-baked textures: the sun, skybox, and planet surfaces are generated entirely in HLSL at runtime.

Role

Sole Developer

I designed and built every aspect of the project: ECS architecture, Kepler orbital solver, floating-origin precision system, all three procedural HLSL shaders (Sun, Skybox, Planet), and the GPU-instanced rendering pipeline.

Technical Details

Orbital mechanics use a dominant-attractor gravity model. Each body orbits exactly one parent, keeping simulation complexity O(N) and viable at asteroid-belt scale. Integration uses semi-implicit (symplectic) Euler for long-term orbit stability.

Positions are solved analytically each frame via a Kepler solver with Newton-Raphson iteration (8 steps) on the eccentric anomaly, then projected to world space. Units are physically grounded: 1 unit = 1 AU, 1 time unit = 1 day, mass stored as GM (gravitational parameter μ). Time is scaled ×10 for playback speed.

A floating-origin system rebases entity positions relative to the camera each frame, eliminating float32 precision loss at solar-system scales.

The simulation is built entirely on Unity's Baker pattern and Burst-compiled parallel jobs:

  • AuthoringBaker<T> converts MonoBehaviour components to IComponentData at subscene bake time, with zero runtime overhead from authoring data.
  • Per-entity workISystem + IJobEntity, Burst-compiled and fully parallelised across all orbital bodies each frame.
  • Cross-entity readsIJobChunk + ComponentLookup<T> for moon-to-planet parent lookups.
  • Asteroid spawningEntityCommandBuffer for deferred runtime entity creation.
  • Orbit trailsDynamicBuffer<T> per entity, updated in jobs.
  • Spatial queriesUniform grid via NativeParallelMultiHashMap.
  • Precisionfloat32 + floating origin rebasing for solar-system-scale distances.

An animated stellar surface driven entirely by procedural noise, with no textures. Four layers of simplex noise at different scales (22, 77, 52, 272) are combined into a single "heat" value, which is mapped through a four-stop color ramp: dark core → orange → yellow → hot white.

Domain warping displaces the noise lookup before sampling, eliminating tiling artifacts. A configurable Fresnel term produces a glowing corona rim. DOTS instancing is enabled for per-entity color variation across GPU-instanced draw calls.

A fully procedural three-layer skybox rendered in a single fragment pass:

  • StarsThree scale-layered populations with randomised size, color temperature (cool blue ↔ warm orange), and time-driven twinkling. Bright stars receive a soft halo.
  • NebulaDomain-warped FBM noise (5 octaves) blended across three tunable colors, with independent contrast and coverage controls.
  • Galaxy bandA Gaussian falloff along a configurable axis brightens both stars and nebula, simulating a Milky-Way-style galactic core.

Planets receive light exclusively from the Sun via a custom forward-rendering shader. The light loop iterates URP's additional-light list, picks the dominant contribution per pixel, and applies per-pixel shadow attenuation, giving physically plausible day/night terminator lines with no baked lightmaps.

DOTS instancing allows per-entity color variation across the same GPU-instanced draw call. The shader runs 4 passes: UniversalForward, ShadowCaster, DepthOnly, and DepthNormals.

Source Code