Solar System: Updated with an N-Body Physics Model

Throwing my hat in the ring for a Three.js solar system. Pretty simple scene, so I’d appreciate any feedback.

Demo Here

Planets are 10 times larger than they should be. This was done because it helps reduce the orbit lines shaking around too much. ¯_(ツ)_/¯

Time is scaled by 100x (faster). Maybe wait 3.65 days and Earth will do a full orbit

I think it’s decently accurate, loading the planet data and then solving the n-body simulation with a rk4 propagation model.


Also - another space model I’ve been working on…
Demo2 Here

4 Likes

This simulation is inaccurate. Don’t believe me? See you in a few hundred million years! (or if another body introduce itself)

1 Like

lol - you had me going for a second :laughing:

1 Like

Added it to GitHub in case anyone wants to see how Python gets the data

1 Like

This is quite lovely. Very cool.

1 Like

How do we show real position of stars and constellation in space?

Skyfield, the Python I’m using for astrodynamics, provides star positions.

Once you get the stars in whatever reference frame they come in, I would think transforming them to your needed reference frame would be easy. Skyfield does a good job of that, imho.

https://rhodesmill.org/skyfield/stars.html

1 Like

Really nice work. Would be amazing to see Saturn casting shadow onto its rings.

1 Like

Great idea! Tried a few things. This was the only one that worked for me, and I think it’s the best way to do it.

const satringMat = new ShaderMaterial({
    uniforms: {
        ringTexture: { value: textureLoader.load(satring) },
        sunDirection: { value: new Vector3() },
        saturnRadius: { value: saturn.r }
    },

vertexShader: `
    varying vec2 vUv;
    varying vec3 vWorldPosition;
    varying vec3 vSaturnCenter;
    void main() {
        vUv = uv;
        vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;
        vSaturnCenter = (modelMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
`,
fragmentShader: `
    uniform sampler2D ringTexture;
    uniform vec3 sunDirection;
    uniform float saturnRadius;
    varying vec2 vUv;
    varying vec3 vWorldPosition;
    varying vec3 vSaturnCenter;
    void main() {
        vec4 ringColor = texture2D(ringTexture, vUv);
        vec3 sunDir = normalize(sunDirection);
        vec3 saturnToRing = vWorldPosition - vSaturnCenter;
        float projection = dot(saturnToRing, sunDir);
        float shadowFactor = 1.0;
        if (projection < 0.0) {
            vec3 perpendicular = saturnToRing - projection * sunDir;
            float distance = length(perpendicular);
            shadowFactor = smoothstep(saturnRadius * 0.9, saturnRadius * 1.1, distance);
        }
        vec3 finalColor = mix(ringColor.rgb * 0.2, ringColor.rgb, shadowFactor);
        gl_FragColor = vec4(finalColor, ringColor.a);
    }
`,
    side: DoubleSide,
    transparent: true
});

and in the animation

    saturnRing.material.uniforms.sunDirection.value.copy(saturn.sunvect);


1 Like

Added some updates. You can see what the planets looked like on your birthday (or any date).

Just add a date in the format ?birthday=YYYY-MM-DD to the end of the link:

To check it works, I found a future date when a bunch of planets are supposed to be visible. On 2025-08-10 there’ll be an almost full moon and six planets in the sky. Kinda hard to see with my simulation, but I hope you can see the similarity from Earth’s perspective.
link to planets on 2025-08-10



also added saturn’s shadow onto the rings
github

3 Likes