oneshotlm
Compare all models on this prompt →

3D solar system · deepseek-v4-pro

Using the pre-provided three.min.js (global THREE), build a 3D solar system with the sun and orbiting planets at varied speeds and sizes, orbit-drag camera controls, and a starfield.

⛨ sandboxed Open in new tab ↗
transcript · 8 messages
user

Using the pre-provided three.min.js (global THREE), build a 3D solar system with the sun and orbiting planets at varied speeds and sizes, orbit-drag camera controls, and a starfield.

assistant
thinking
The user wants me to build a 3D solar system single-page web app using Three.js (three.min.js) that's already in the current directory. Let me first check what files are available.
bash {"command":"ls -la /workspace/"}
toolResult

total 644 drwxrwxrwx 3 node node 96 Jul 8 00:47 . drwxr-xr-x 1 root root 4096 Jul 8 00:47 .. -rw-r--r-- 1 node node 603445 Jul 8 00:47 three.min.js

assistant
thinking
Great, three.min.js is present. Now I need to build a comprehensive 3D solar system with:

1. Sun with glow effect
2. Planets orbiting at varied speeds and sizes
3. Orbit-drag camera controls (dragging rotates the camera around the system)
4. Starfield background

Let me plan the implementation:

- **Sun**: Large sphere with emissive material, point light, and a glow sprite
- **Planets**: Mercury, Venus, Earth, Mars, Jupiter, Saturn (with rings), Uranus, Neptune - all with different sizes, distances, colors, and orbital speeds
- **Orbit lines**: Thin rings showing orbital paths
- **Starfield**: Particle system with random stars in a large sphere
- **Camera**: PerspectiveCamera with orbit controls (drag to rotate, scroll to zoom)
- **Lighting**: Point light at the sun, ambient light

For the orbit-drag camera controls, I'll implement manual orbit controls using mouse events:
- Mouse drag: rotate around the sun (orbit)
- Mouse wheel: zoom in/out
- Touch support too

Let me build this all into one index.html file.

I'll use THREE.OrbitControls-style behavior but hand-rolled for the drag controls. Actually, since we only have three.min.js and no OrbitControls addon, I'll implement spherical coordinate camera controls manually.

Let me think about the implementation:

1. Set up scene, camera, renderer
2. Create starfield (BufferGeometry with random points)
3. Create sun (sphere + point light + glow sprite)
4. Create planet data array
5. For each planet: create sphere at distance, add orbit ring, set speed
6. Animation loop: update planet positions
7. Mouse/touch controls: spherical coordinates, drag to rotate, wheel to zoom

For the sun glow, I can use a sprite with a radial gradient texture created via canvas.

Let me code this up carefully.

For planet data:
- Mercury: small, close, fast
- Venus: medium, medium distance, medium speed
- Earth: medium, with moon
- Mars: small, reddish
- Jupiter: large, with bands (using procedural texture)
- Saturn: with rings
- Uranus: blue-green
- Neptune: blue

I'll create a canvas-based texture for some planets to give them interesting appearances.

Let me write the complete HTML file now.

For the orbit controls:
- Track mouse down/up/move
- Convert to spherical coordinates
- Drag changes theta (azimuthal) and phi (polar) angles
- Scroll changes radius
- The camera always looks at the sun/origin

I'll make it so dragging orbits around the center point.

Let me think about the starfield. I'll use a Points object with many random positions on a large sphere.

For the sun glow, I'll create a canvas with a radial gradient and use it as a sprite texture.

Let me structure the code:

```javascript
// Scene setup
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });

// Starfield
// Sun with glow
// Planets
// Animation
// Controls
```

I need to be careful with the camera controls. Let me implement smooth orbiting:

- spherical coords: theta (horizontal angle), phi (vertical angle), radius
- Mouse drag changes theta and phi
- Scroll changes radius
- Camera position: from spherical to cartesian, looking at origin

For the planets, each will be in a pivot group that rotates around the Y axis at different speeds. This is simpler than computing positions manually.

Actually, let me use a parent Object3D that rotates. Each planet gets its own parent that I rotate at different speeds. The planet is positioned at (distance, 0, 0) in its parent's local space, and the parent rotates around Y.

Let me also add some nice touches:
- Saturn's rings using RingGeometry or a flat torus
- Earth with a slight blue tint
- Maybe a subtle particle trail or just the orbit rings

For orbit rings, I'll use a thin torus or a line loop. Line might be simpler.

Actually, I'll use `THREE.RingGeometry` is for flat rings... wait, that's for flat rings in XY plane. For orbit lines, I'll create circles using `THREE.BufferGeometry` with points along a circle.

Or even simpler: use `THREE.TorusGeometry` with a very small tube radius for thin orbit rings. Or I can use a `Line` with a `RingGeometry`-like set of points.

Let me use `THREE.RingGeometry` - no, that creates a filled ring. For orbit lines, I'll create circular line geometries.

Actually, the simplest approach for orbit lines: create a `THREE.BufferGeometry`, compute points on a circle, and use `THREE.Line` with `THREE.LineBasicMaterial`.

Let me also consider the planet textures. I'll create simple canvas textures for:
- Sun: bright yellow/orange gradient
- Jupiter: bands of orange/brown
- Earth: blue with some green
- Saturn: pale yellow
- etc.

OK let me write this all out now. I'll make it quite polished.

For the glow effect on the sun, I'll:
1. Create a large transparent sprite with a radial gradient
2. Place it at the sun's position
3. It creates a nice atmospheric glow

Let me also add a subtle bloom-like effect by having multiple glow layers.

Now for camera controls, let me think about the math:

```
// Initial spherical coords
let theta = 0; // horizontal angle
let phi = Math.PI / 3; // vertical angle (from top)
let radius = 30;
let target = new THREE.Vector3(0, 0, 0);

// Convert to cartesian
camera.position.x = radius * Math.sin(phi) * Math.cos(theta);
camera.position.y = radius * Math.cos(phi);
camera.position.z = radius * Math.sin(phi) * Math.sin(theta);
camera.lookAt(target);
```

On mouse drag:
- deltaX changes theta
- deltaY changes phi (clamped to avoid flipping)

On scroll:
- radius changes (clamped)

I should also add some damping for smooth movement.

Let me also add touch support for mobile.

Now let me write the complete HTML file. I'll make it really nice.

Actually, for planet textures, let me use simple canvas-based textures. Each planet will have a small canvas with some procedural patterns.

For Jupiter, I'll draw horizontal bands.
For Earth, I'll do blue with green patches (very simplified).
For Sun, bright yellow/orange.
For Mars, reddish.
For Saturn, pale yellow/tan.
For Venus, yellowish white.
For Mercury, gray.
For Uranus, light blue/cyan.
For Neptune, deep blue.

Let me create these efficiently.

Actually, to keep it simpler but still nice, I'll use MeshPhongMaterial or MeshStandardMaterial with different colors, and maybe canvas textures for just the sun and a couple key planets.

For the sun, I definitely want a canvas texture with some noise/granulation.

OK, I think I've planned enough. Let me write the code.

One more thing: for Saturn's rings, I'll use a `THREE.RingGeometry` (which creates a flat ring in the XY plane). I'll rotate it to be slightly tilted (like real Saturn's rings). Then parent it to Saturn's orbital pivot so it moves with Saturn.

Actually, `THREE.RingGeometry(innerRadius, outerRadius, segments)` creates a filled ring. I'll use that with a semi-transparent material.

Wait, I need to check if RingGeometry is flat. Yes, it creates vertices in the XY plane. Saturn's rings are in Saturn's equatorial plane, which is tilted. I can create the ring and rotate it.

Let me also make the ring have some color variation - maybe a gradient using a canvas texture.

OK, writing the code now. Let me make it comprehensive but clean.

Here's my plan for the file structure:

```
<!DOCTYPE html>
<html>
<head>
  <title>3D Solar System</title>
  <style>
    /* Full screen canvas, no margins, dark background */
    /* Info overlay */
  </style>
</head>
<body>
  <script src="three.min.js"></script>
  <script>
    // All JS code
  </script>
</body>
</html>
```

Let me code it all out now. I want to be thorough.

For the starfield, I'll create ~2000 stars using `THREE.Points` with random positions in a large sphere (or on the surface of a large sphere). I'll use a small circle sprite texture (created via canvas) for each star, with varying sizes.

Let me write the complete implementation now.

One consideration: I need to handle window resize properly.

Also, I want smooth camera transitions. When the user drags, the camera orbits. When the user releases, there could be some momentum (optional - adds a nice feel).

Let me include momentum on drag release for smoother feel.

For the planet data, I'll store:
- name
- distance from sun
- radius (size of sphere)
- color
- orbital speed
- optional ring data
- texture type

Here's my planet data:

```javascript
const planetData = [
  { name: 'Mercury', distance: 4, radius: 0.3, color: 0xaaaaaa, speed: 4.0 },
  { name: 'Venus', distance: 6, radius: 0.7, color: 0xffcc88, speed: 3.0 },
  { name: 'Earth', distance: 8, radius: 0.75, color: 0x4488ff, speed: 2.5 },
  { name: 'Mars', distance: 10, radius: 0.5, color: 0xcc6644, speed: 2.0 },
  { name: 'Jupiter', distance: 14, radius: 2.0, color: 0xddaa77, speed: 1.2 },
  { name: 'Saturn', distance: 18, radius: 1.6, color: 0xeedd99, speed: 0.9, hasRings: true },
  { name: 'Uranus', distance: 22, radius: 1.2, color: 0x88ccdd, speed: 0.6 },
  { name: 'Neptune', distance: 26, radius: 1.1, color: 0x4455dd, speed: 0.5 },
];
```

For the sun, I'll make it at position (0,0,0) with radius ~2.5 and a glow sprite.

Now let me think about orbit rings. I'll create a `THREE.Line` for each planet's orbit. The line will be a circle at the planet's distance.

To create a circle line:
```javascript
const points = [];
const segments = 128;
for (let i = 0; i <= segments; i++) {
  const angle = (i / segments) * Math.PI * 2;
  points.push(new THREE.Vector3(Math.cos(angle) * distance, 0, Math.sin(angle) * distance));
}
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const line = new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: 0x333344, transparent: true, opacity: 0.3 }));
```

OK, I think I have enough planned. Let me write it all out now as a single HTML file.

One thing about the camera drag: I need to handle the case where the user clicks on a planet vs drags on empty space. For simplicity, I'll make any drag orbit the camera. Only scrolling and clicking on empty space triggers orbit. Since we're not using a raycaster to detect clicks on planets, all drags will orbit.

Actually, let me also add the ability to click on a planet to focus on it. But that might be complex. Let me keep it simple: orbit-drag anywhere, scroll to zoom.

Let me finalize and write the code.

I also want to add some subtle effects:
- The sun should have a point light (already planned)
- Ambient light so the dark side of planets isn't completely black
- Maybe a subtle bloom on the sun using multiple overlapping sprites

For the sun glow, I'll create a canvas with a radial gradient from white center to transparent edge, then use it as a sprite texture. I'll make the sprite quite large relative to the sun sphere.

Let me write the final code now.
write /workspace/index.html (25013 bytes)
toolResult

Successfully wrote 25013 bytes to /workspace/index.html

assistant
thinking
The file was written. Let me verify it looks good by reading it back, and also verify the three.min.js is still there and index.html is present.

Let me also double-check the file for any issues.
bash {"command":"ls -la /workspace/index.html /workspace/three.min.js"}
toolResult

-rw-r--r-- 1 node node 26887 Jul 8 00:50 /workspace/index.html -rw-r--r-- 1 node node 603445 Jul 8 00:47 /workspace/three.min.js

assistant
thinking
Both files are present. Let me verify the HTML is valid by checking the structure briefly.

The `index.html` is built and ready. Here's what it includes: **Solar System** - **Sun** at center with procedural canvas texture, granular surface noise, bright spots, and 3 additive glow sprites with subtle pulsation - **8 planets** (Mercury → Neptune) with realistic relative sizes, distances, and orbital speeds — each with a unique procedurally generated texture (Jupiter gets bands + Great Red Spot, Earth gets oceans/continents/clouds, Saturn gets cloud bands) - **Saturn's rings** with a textured banded ring including Cassini-like gaps, tilted at an angle - **Earth's Moon** orbiting around Earth - **Asteroid belt** (1,200 particles) between Mars and Jupiter - **Orbit guide lines** (semi-transparent rings) for every planet **Controls** - **Drag** anywhere to orbit the camera around the system (mouse or touch) - **Scroll** (or pinch on touch devices) to zoom in/out (clamped 5–80 units) - **Momentum** on drag release — the view glides with smooth friction damping - **Speed slider** (top right) to change orbital speed from paused to 3× - Info hint fades after 6 seconds, reappears on interaction **Visuals** - **Starfield**: 2,500 stars on a large sphere with color variation and slight rotation - **Lighting**: Point light from the sun with shadows + ambient fill + secondary warm point light - **Post-processing**: ACES filmic tone mapping, antialiasing, responsive to window resize Just open `index.html` in a browser — no server needed, no network requests.

TAKE IT TO CODE

A single self-contained HTML file — copy it and open in any browser, or reuse the prompt with your own pi-agent run.

RUN

modeldeepseek-v4-pro
vendorDeepSeek
harnesspi-agent
generated2026-07-08

EVALUATION

4/5 working

Animated 3D solar system with sun, orbiting planets, rings, starfield; wheel zoom and drag orbit both work well.

Vision grade · anthropic/claude-sonnet-5

MEASUREMENTS

Raw readings from the capture, not a verdict — the grade above is the only judgement. Percentages are how much of the screen changed; the measure under-reports sparse motion on a dark background.

idle motion9.0%
on click7.1%
on drag7.1%
on wheel36.3%
on enter + space8.1%
on arrow keys9.6%
on w/a/s/d9.7%
frame spread52.1 / 255
console errors0
js errors none

METRICS

runtime186.2s
tokens in15k
tokens out12k
cached15k
cost / run$0.0166