Perfil Servicios Gadgets IA Blog Contactar
Inicio/Blog/Solar System Pro
Cómo construí un Sistema Solar 3D con 8.087 líneas de Three.js

Cómo construí un Sistema Solar 3D con 8.087 líneas de Three.js

El gadget más complejo de mi portfolio: mecánica orbital de Kepler, texturas NASA reales, 95+ lunas, Pale Blue Dot, tracking de sondas interestelares en tiempo real, y datos de lanzamientos en vivo. Este es el desglose técnico completo de la v7.0.

Respuesta rápida

¿Cómo se hace un sistema solar 3D con Three.js?

Un sistema solar 3D en Three.js se construye con mecánica orbital real de Kepler (semieje, excentricidad, inclinación de la NASA), un motor que resuelve la ecuación M = E − e·sin(E) por Newton-Raphson, y técnicas de rendimiento como frustum culling y LOD para mantener 60fps con planetas, 95+ lunas y 200.000 estrellas. El mío tiene 8.087 líneas en un solo archivo, sin bundler ni frameworks, solo Three.js r128.

Por qué un Sistema Solar

Cuando decidí que mi portfolio necesitaba gadgets interactivos que fueran más allá de un CRUD, quise algo que combinase complejidad técnica visible con wow factor inmediato. Un simulador astronómico cumple ambas: el usuario ve planetas orbitando en 3D y puede interactuar con ellos, mientras por debajo corre mecánica orbital real, shaders personalizados y un sistema de gestión de estado complejo.

El resultado: 8.087 líneas de JavaScript puro en un solo archivo (solar-system-pro.js), sin bundler, sin React, sin TypeScript. Solo Three.js r128, Launch Library 2 API, y mucha trigonometría.

Arquitectura General

El archivo se organiza en bloques funcionales claros:

BloqueLíneasFunción
Datos NASA~800Constantes orbitales de planetas, lunas y NEOs
Scene Setup~400Renderer, cámara, luces, post-processing
Planet Factory~600Generación procedural de texturas y geometrías
Moon System~50095+ lunas con órbitas independientes
Orbit Engine~700Kepler + interpolación temporal
UI/Controls~900Panel de control, sliders, teclado
Interstellar Mode~400Skybox, 200K estrellas, nebulosas
Missions & NEOs~350Trayectorias de Voyager, Cassini, etc.
Info Panels~500HUD con datos de cada cuerpo celeste
Constellations~30088 constelaciones con líneas y nombres

Mecánica Orbital de Kepler

El corazón del simulador es la implementación de las leyes de Kepler. Cada planeta tiene datos orbitales reales de la NASA: semieje mayor, excentricidad, inclinación, longitud del nodo ascendente, argumento del periastro y anomalía media en J2000.

La Ecuación de Kepler

El problema fundamental es convertir el tiempo en una posición. Kepler lo resuelve con la anomalía excéntrica (E), que se calcula iterativamente:

// Resolver ecuación de Kepler: M = E - e·sin(E)
function solveKepler(M, e, tolerance = 1e-8) {
    let E = M; // Aproximación inicial
    for (let i = 0; i < 50; i++) {
        const dE = (E - e * Math.sin(E) - M) / (1 - e * Math.cos(E));
        E -= dE;
        if (Math.abs(dE) < tolerance) break;
    }
    return E;
}

// De anomalía excéntrica a coordenadas 3D
function keplerToCartesian(a, e, i, omega, Omega, E) {
    const cosE = Math.cos(E), sinE = Math.sin(E);
    const r = a * (1 - e * cosE); // Distancia al Sol
    const v = Math.atan2(
        Math.sqrt(1 - e*e) * sinE,
        cosE - e
    ); // Anomalía verdadera

    // Rotación al plano eclíptico
    const cosV = Math.cos(v + omega);
    const sinV = Math.sin(v + omega);
    const cosO = Math.cos(Omega);
    const sinO = Math.sin(Omega);
    const cosI = Math.cos(i);
    const sinI = Math.sin(i);

    return new THREE.Vector3(
        r * (cosO * cosV - sinO * sinV * cosI),
        r * sinV * sinI,
        r * (sinO * cosV + cosO * sinV * cosI)
    );
}

Este método Newton-Raphson converge en 3-5 iteraciones para órbitas planetarias. Para cometas con alta excentricidad (e > 0.9), necesita más iteraciones — pero funciona.

Control Temporal

El usuario puede acelerar el tiempo desde 1x (tiempo real) hasta 1.000.000x. A 100.000x, Mercurio orbita en ~7 segundos. El sistema mantiene un julianDate que avanza según el multiplicador:

const dt = clock.getDelta() * timeMultiplier;
julianDate += dt / 86400; // Convertir a días julianos
planets.forEach(p => p.updatePosition(julianDate));

95+ Lunas con Órbitas Independientes

Cada luna tiene su propia órbita alrededor de su planeta padre, con datos reales: Io, Europa, Ganímedes, Calisto, Titán, Encélado... 95 en total. El truco de rendimiento es que las lunas de planetas no visibles (fuera de cámara) no se calculan:

// Frustum culling para lunas
const frustum = new THREE.Frustum();
frustum.setFromProjectionMatrix(
    new THREE.Matrix4().multiplyMatrices(
        camera.projectionMatrix,
        camera.matrixWorldInverse
    )
);

moons.forEach(moon => {
    const parentVisible = frustum.containsPoint(moon.parent.position);
    moon.mesh.visible = parentVisible;
    if (parentVisible) moon.updateOrbit(julianDate);
});

El Modo Interestelar

Al activar el modo interestelar, la cámara sale del sistema solar y aparece un campo de 200.000 estrellas generadas proceduralmente con THREE.Points y un shader personalizado que controla brillo y color por temperatura estelar:

// Distribución de estrellas con aspecto de Vía Láctea
for (let i = 0; i < 200000; i++) {
    const theta = Math.random() * Math.PI * 2;
    const r = Math.pow(Math.random(), 0.5) * 500; // Disco galáctico
    const h = (Math.random() - 0.5) * 20 * Math.exp(-r / 100);

    positions.push(r * Math.cos(theta), h, r * Math.sin(theta));
    // Color por temperatura: azul (caliente) → blanco → rojo (fría)
    const temp = Math.random();
    colors.push(
        0.5 + temp * 0.5,        // R
        0.5 + temp * 0.3,        // G
        0.8 + (1-temp) * 0.2     // B
    );
}

Rendimiento: 60fps con Todo Encendido

El mayor desafío fue mantener 60fps con planetas + lunas + estrellas + anillos + órbitas + etiquetas + partículas. Las técnicas clave:

v7.0: 6 Experiencias Que Nadie Más Tiene

Con la base técnica sólida, me propuse crear features que ningún otro simulador de portfolio ofrece. La idea: competir en ingenio, no en fuerza bruta. No puedo igualar a NASA Eyes con su equipo de JPL, pero sí puedo crear experiencias que ellos no han pensado hacer.

Y aquí es importante ser transparente: yo no soy un programador experto en Three.js. Este proyecto lo construí íntegramente apoyándome en Claude de Anthropic (modelos Opus 4.5 y 4.6) como mi pair programmer. Yo aporté la visión de producto, las decisiones de diseño y el criterio para validar cada resultado. Claude aportó el conocimiento técnico profundo: mecánica orbital, shaders, optimización WebGL, integración de APIs. Cada línea de código fue una conversación entre los dos. Es la demostración práctica de que una persona con criterio y una IA potente pueden competir con equipos enteros.

Pale Blue Dot (tecla B) — La cámara viaja hasta Voyager 1 a 23,5 mil millones de km. La Tierra se convierte en un punto de 0.12 píxeles. Aparece el texto de Carl Sagan con fade progresivo. Es puro storytelling cinemático en Three.js: animación de cámara interpolada, el planeta se encoge en tiempo real, y el efecto emocional es inmediato.

Humanity's Reach (tecla U) — Seguimiento en tiempo real de las 5 sondas más lejanas de la humanidad. Los datos de referencia vienen de NASA JPL Horizons (posición y velocidad en fecha conocida), y la distancia se extrapola segundo a segundo: distAU = refDist + velocity × elapsed. Voyager 1 está a ~165 AU y se aleja 3.6 AU/año.

Space Race (tecla L) — Dashboard con el ranking de lanzamientos 2024 (SpaceX: 131, China: 68...) renderizado con Canvas 2D, y un panel de próximos lanzamientos que se alimenta en vivo de Launch Library 2 API (lldev.thespacedevs.com) con countdown T-minus actualizándose cada segundo. Si la API no responde, cae a un donut chart de distribución orbital como fallback.

Light-Time — Selecciona un planeta, pulsa "Enviar señal": un pulso de luz viaja de la Tierra al destino en la escena 3D, con countdown del tiempo real de la luz (4.3 min a Marte, 5.5 horas a Plutón) comprimido a una animación de 2-12s. Factoids contextuales rotan cada 3s: "En 43 minutos podrías cocinar un plato completo".

Lo Que Aprendí

Construir este simulador me enseñó más sobre gestión de complejidad que cualquier curso:

Si puedes simular el sistema solar con mecánica orbital real en un navegador, puedes construir cualquier dashboard interactivo que te pidan en producción.

El código completo está en el portfolio en cristiancorrales.com. Abre Solar System Pro y dale a "OBSERVATORIO" para la experiencia completa. Prueba las teclas B, U, Y, L para las experiencias exclusivas.

{label}

¿Tu web no trae clientes?

Diseño webs que cargan rápido y convierten, para negocios de Tarragona y alrededores. Precios claros desde el primer día.

Ver el servicio de diseño web →

¿Quieres una cifra orientativa ya? Configura tu web y ve el precio al instante →

¿Quieres ver casos reales de IA en pymes?

Te escribo solo cuando tengo un caso con costes y resultados reales, o una herramienta que merece la pena. Sin humo, sin spam y baja en un clic.

Comparte este artículo

Cristian Corrales

Cristian Corrales

+20 años en tecnología. SEO, automatización e IA aplicada a negocios reales desde Calafell, Tarragona.