oneshotlm
Compare all models on this prompt →

3D solar system · deepseek-r1-0528

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.

⚠ no runnable output

This one-shot run produced no runnable artifact.

agent produced no index.html

The transcript below shows what the model did — read it to see why the one shot fell short.

transcript · 2 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
We are going to create a single-page web app that includes:
  - A 3D solar system with the sun and several planets (e.g., Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune) with varied sizes and orbital speeds.
  - A starfield in the background.
  - Orbit-drag camera controls for the user to move the camera.

We will use the THREE.js library that is provided (three.min.js) and write the entire code in one index.html file.

Structure of index.html:
  - HTML: minimal structure, a <div> to contain the canvas and a <script> tag to load three.min.js, then our own <script> for the app.
  - CSS: in a <style> tag to set body margin to 0 and the canvas to fullscreen.
  - JS: Our main script that:
      1. Sets up the scene, camera, renderer.
      2. Creates a starfield (using a large number of small particles).
      3. Creates the sun (a light source and a sphere) and planets (each planet as a sphere with its own texture, size, orbit radius, speed).
      4. Adds orbit controls (we'll use the THREE.OrbitControls).
      5. Animates the scene (update planet positions and render).

We note that the three.min.js file is already in the current directory. So we load it with:
  <script src="three.min.js"></script>

Since we are using OrbitControls, we must note that OrbitControls are part of the THREE.js examples. However, we are using the minified THREE.js which might not include OrbitControls. Alternatively, we can include the OrbitControls from the examples directory? But note the requirement: no external resources. Therefore, we must either:
  a) Find that the OrbitalControls is included in three.min.js? Probably not because three.min.js is the core.
  b) We are allowed to use the file already present? But we only have three.min.js.

Given the constraint, let's check the project: the user said "pre-provided three.min.js". We don't know if it includes OrbitControls. To be safe, we assume it does not. Therefore, we should provide OrbitControls as a separate file? But the instructions say: "These library file(s) are ALREADY present in the current directory" and we only have three.min.js.

So we must either:
  1. Use the core THREE without OrbitControls? Then we have to write our own? But that's complex.
  2. Include the OrbitControls from a separate file? But the user didn't provide it.

Wait, the instructions say: "These library file(s) are ALREADY present ... : three.min.js." meaning only one file. Therefore, we cannot assume OrbitControls is present.

Alternative: Since we cannot load external resources, we might have to rely on what is in three.min.js. However, the core THREE does not include OrbitControls. Therefore, we must not use OrbitControls? But the task requires orbit-drag camera controls.

Solution: We can write a simple version of orbit controls? Or maybe we find a minimal OrbitControls implementation that we can inline? But that would make the code long.

However, note: the user said "pre-provided three.min.js", and we are in the current directory. We have read access to the current directory? Yes. But we are to write an index.html that uses the provided three.min.js. We cannot assume any other library file. Therefore, we must either:

  - Write a very simple orbit control (using mouse events to rotate the camera) if we don't have OrbitControls.

But let me check: maybe OrbitControls is included in the core build? According to THREE.js documentation, OrbitControls is part of the examples. So it is not in the core.

Given the constraints (no external resources and only three.min.js provided), we have two options:

  Option A: Implement our own simple OrbitControls. We can do this by:
      - Listening to mousedown, mousemove, mouseup events to rotate the camera when the mouse is dragged.
      - Using TrackballControls? Not, we don't have it.

  Option B: We decide to not use any controls? But the requirement says "orbit-drag camera controls".

Since we have to meet the requirements and we cannot load an external file for OrbitControls, we must implement our own.

Simplified Orbit Controls:
  - We'll store the state of whether the mouse is down and the previous mouse position.
  - On mousedown, set a flag and record the current mouse position.
  - On mousemove (if mouse down), calculate the movement and use it to rotate the camera (in the same way as OrbitControls: horizontal movement rotates around the vertical axis, vertical movement rotates around a horizontal axis). We can use spherical coordinates for the camera.

Alternatively, we can set the camera to be a child of a pivot object at the scene center. Then when dragging, we rotate the pivot.

Let's do:

  Create a pivot object:
      const pivot = new THREE.Object3D();
      scene.add(pivot);
      pivot.add(camera);
      camera.position.set(0, 0, 50);

  Then on mousemove (with mouse down) we do:
      pivot.rotation.y += movementX * 0.01;
      pivot.rotation.x += movementY * 0.01;

But note: rotation around x axis might go upside down? We can limit the x rotation to -PI/2 to PI/2.

Or we can use spherical coordinates:

      let spherical = new THREE.Spherical();
      spherical.setFromVector3(camera.position);

      Then on drag:
          spherical.theta -= movementX * 0.01;
          spherical.phi -= movementY * 0.01;   // but note: phi is [0, PI], we should clamp to [0.1, PI-0.1] to avoid flip
          camera.position.setFromSpherical(spherical);

But without a pivot, we have to adjust the lookAt. We can set camera.lookAt(scene.position).

We choose the spherical approach because it is straightforward and doesn't require an extra pivot.

So our own simple orbit control:

  Variables:
      let isDragging = false;
      let previousMousePosition = { x: 0, y: 0 };

  Events:
      canvas.addEventListener('mousedown', (e) => {
          isDragging = true;
          previousMousePosition = { x: e.clientX, y: e.clientY };
      });

      canvas.addEventListener('mousemove', (e) => {
          if (!isDragging) return;

          const deltaX = e.clientX - previousMousePosition.x;
          const deltaY = e.clientY - previousMousePosition.y;

          // Update the spherical angles for the camera
          // We assume the camera is looking at the origin (0,0,0) and is at (0,0,distance) initially? But we are using a variable distance.

          // We can represent the camera position in spherical coordinates relative to the origin.
          let spherical = new THREE.Spherical().setFromVector3(camera.position);

          spherical.theta -= deltaX * 0.01;
          spherical.phi -= deltaY * 0.01;

          // Clamp phi to avoid flipping at the poles
          spherical.phi = Math.max(0.1, Math.min(Math.PI - 0.1, spherical.phi));

          const cameraPos = new THREE.Vector3().setFromSpherical(spherical);
          camera.position.copy(cameraPos);
          camera.lookAt(0, 0, 0);

          previousMousePosition = { x: e.clientX, y: e.clientY };
      });

      canvas.addEventListener('mouseup', () => {
          isDragging = false;
      });

  We also need to adjust the up vector? But for simplicity, we can leave it.

  Note: We are not handling zoom? The requirement says "orbit-drag", so maybe only rotation. We can skip zoom.

  Also, we don't have mouse wheel? Then we skip.

But note: the initial camera position might be set in a way that the spherical coordinates are not what we think? Let me set the initial camera to be at (0, 0, 50) -> then spherical is (50, PI/2, 0) for (r, phi, theta)? Actually, when the camera is at (0,0,50) and looking at (0,0,0), the spherical coordinates: 
  r=50, phi=0? Actually, no: in THREE.Spherical, phi is the angle from the positive y-axis? Actually, the documentation says:
      radius -> the radial distance from the origin.
      phi -> the polar angle in radians from the positive y-axis (down). Actually, note: in three.js, the coordinate system is y up? Then phi is from the positive y-axis? 
  But by convention, in OrbitControls they use the "up" vector as (0,1,0) and the camera moves in the xz plane? Actually, we'll adjust.

  How about we set the initial camera to (0, 20, 50) and lookAt(0,0,0)? Then the spherical coordinates will work.

  Alternatively, we can set the camera at (0,0,50) and in the spherical coordinates, phi=PI/2 (which is 90 degrees) which is pointing to the positive z? Then when we move along theta, we change the longitude? and phi changes the latitude.

  We'll set the initial camera at (0,0,50) and use lookAt(0,0,0). That is along the z axis. Then theta=0, phi=PI/2? Because from the y-axis, we are at 90 degrees? Actually, if we set the initial camera at (0,0,50), which is the point (x=0,y=0,z=50) then:

      spherical.radius = sqrt(x^2+y^2+z^2) = 50
      spherical.phi = acos(y / r) = acos(0) = PI/2? But note: the definition in THREE.Spherical: 
          phi: angle from the positive y-axis to the vector. So it's 0 at the positive y-axis, increases to PI at negative y-axis.

      Actually: 
          z = r * sin(phi) * sin(theta) ??? 
      Let me check the three.js documentation: 
          new THREE.Vector3().setFromSpherical(spherical) does:
          x = r * sin(phi) * cos(theta)
          y = r * cos(phi)
          z = r * sin(phi) * sin(theta)

      For our initial camera at (0,0,50):
          x=0, y=0, z=50 -> 
          We get:
            y = r * cos(phi) = 0 -> then cos(phi)=0 -> phi = PI/2.

          Then: 
            x = r * sin(phi) * cos(theta) = 50 * 1 * cos(theta) = 0 -> so cos(theta)=0 -> theta = PI/2 or 3*PI/2?
            z = r * sin(phi) * sin(theta) = 50 * 1 * sin(theta) = 50 -> then sin(theta)=1 -> theta = PI/2.

      So initial theta=PI/2, phi=PI/2.

      Then when we drag horizontally (deltaX), we change theta. When vertically, we change phi.

      But note: phi has to be in (0, PI). We clamp to (0.1, PI-0.1) to avoid the poles.

  So in our event handler, we do:
      spherical.theta -= deltaX * 0.01;   // because moving right should turn to the right -> which in the coordinate system would be increasing theta? Actually, our current position is at (0,0,50) which is along the z-axis, and moving the mouse right should rotate the camera to the right? That would show the scene rotating left? Actually, it is relative.

  We'll try and adjust the signs if needed.

Plan:

  We'll create an index.html file with:

  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>3D Solar System</title>
      <style>
          body { margin: 0; }
          canvas { display: block; }
      </style>
  </head>
  <body>
      <div id="container"></div>
      <script src="three.min.js"></script>
      <script>
          ... All our JavaScript code here ...
      </script>
  </body>
  </html>

Now the JavaScript code:

  Steps:
      1. Set up scene, camera, renderer.
      2. Add a starfield.
      3. Add the sun (with a light and a sphere).
      4. Add planets (each with attributes: name, radius, orbit_radius, orbit_speed, texture? but we don't have textures, so we use colors).
      5. We create a function that creates a planet: with a sphere geometry, a material of MeshPhongMaterial with a color, and then we position it at (orbit_radius,0,0) initially? Then we rotate it around the sun? We'll put each planet in a parent group so that we can rotate the group around the sun.

      For each planet:
          const planetGroup = new THREE.Group();
          scene.add(planetGroup);
          const planet = new THREE.Mesh(geometry, material);
          planet.position.x = orbit_radius;
          planetGroup.add(planet);

          Then in the animation loop:
              planetGroup.rotation.y += planet_speed * delta;

      6. We create the starfield: we'll create a bunch of random points in a sphere (or just in a cube) around the scene. We use a points system.

      7. We add a light source (the sun) and also the sun should emit light.

      8. We add the orbit-drag controls as described.

      9. Animation loop.

Planet Data:

  We'll define an array of planet data:

      const planets = [
          { name: 'Mercury', radius: 0.4, orbitRadius: 5, orbitSpeed: 0.01, color: 0xaaaaaa },
          { name: 'Venus', radius: 0.9, orbitRadius: 8, orbitSpeed: 0.007, color: 0xffcc66 },
          { name: 'Earth', radius: 1.0, orbitRadius: 11, orbitSpeed: 0.005, color: 0x6699ff },
          { name: 'Mars', radius: 0.5, orbitRadius: 14, orbitSpeed: 0.004, color: 0xff6633 },
          { name: 'Jupiter', radius: 2.5, orbitRadius: 20, orbitSpeed: 0.003, color: 0xffb366 },
          { name: 'Saturn', radius: 2.2, orbitRadius: 30, orbitSpeed: 0.002, color: 0xffcc99 },
          { name: 'Uranus', radius: 1.8, orbitRadius: 40, orbitSpeed: 0.001, color: 0x99ccff },
          { name: 'Neptune', radius: 1.8, orbitRadius: 50, orbitSpeed: 0.0009, color: 0x3366ff }
      ];

  The sun will be at the center.

Starfield:

  We create 10000 points randomly in a sphere of radius 1000.

  const starGeometry = new THREE.BufferGeometry();
  const starVertices = [];
  for (let i = 0; i < 10000; i++) {
      const x = THREE.MathUtils.randFloatSpread(2000); // spread over 2000 units in all directions
      const y = THREE.MathUtils.randFloatSpread(2000);
      const z = THREE.MathUtils.randFloatSpread(2000);
      starVertices.push(x, y, z);
  }
  starGeometry.setAttribute('position', new THREE.Float32BufferAttribute(starVertices, 3));
  const starMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 1 });
  const stars = new THREE.Points(starGeometry, starMaterial);
  scene.add(stars);

Lights:

  Ambient light: maybe a little.
  Then the sun: we'll add a point light at the center (the sun mesh) with intensity.

      const sunLight = new THREE.PointLight(0xffffff, 1, 300);
      scene.add(sunLight);

  And then the sun mesh:

      const sunGeometry = new THREE.SphereGeometry(4, 32, 32);
      const sunMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
      const sun = new THREE.Mesh(sunGeometry, sunMaterial);
      scene.add(sun);

  But note: the sun is at the center and very bright, so we can use MeshPhongMaterial for the planets? We need to set a light that illuminates the planets. The sun light will be the main light.

Camera:

  We set a perspective camera at (0,0,50). Then we look at the center.

  And we add the orbit controls via mouse.

  We also have to set the camera aspect ratio when the window resizes.

Animation Loop:

  We update the planet rotations and then render.

Code Structure:

  We wrap the code in a main function and call it.

Because the code is long, we write it step by step.

Let me write the entire index.html content.

Note: We are using THREE.MathUtils which is in three.min.js (if we are using r128 or above). We assume that.

We write:

I'll create an interactive 3D solar system with planets, star background, and camera controls. Here's the self-contained index.html: html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D Solar System</title> <script src="three.min.js"></script> <style> body { margin: 0; overflow: hidden; background: black; } canvas { display: block; } #info { position: absolute; top: 10px; left: 10px; color: white; font-family: Arial, sans-serif; font-size: 13px; user-select: none; opacity: 0.7; } </style> </head> <body> <div id="info">Drag to rotate view · Scroll to zoom</div> <script> // Scene setup const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // Camera position camera.position.z = 50; // Create stars background function createStars() { const starsGeometry = new THREE.BufferGeometry(); const starsMaterial = new THREE.PointsMaterial({ color: 0xFFFFFF, size: 0.15, sizeAttenuation: true }); const starPositions = []; for (let i = 0; i < 10000; i++) { const x = THREE.MathUtils.randFloatSpread(2000); const y = THREE.MathUtils.randFloatSpread(2000); const z = THREE.MathUtils.randFloatSpread(2000); starPositions.push(x, y, z); } starsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(starPositions, 3)); const starField = new THREE.Points(starsGeometry, starsMaterial); scene.add(starField); } // Create rotating planet function createPlanet(size, color, distance, speed, name = "") { const group = new THREE.Group(); const geometry = new THREE.SphereGeometry(size, 32, 32); const material = new THREE.MeshLambertMaterial({ color: color }); const planet = new THREE.Mesh(geometry, material); // Position planet at orbital distance planet.position.x = distance; group.add(planet); scene.add(group); return { group: group, mesh: planet, speed: speed, name: name }; } // Create sun function createSun() { const geometry = new THREE.SphereGeometry(5, 32, 32); const material = new THREE.MeshBasicMaterial({ color: 0xffffff, }); const sun = new THREE.Mesh(geometry, material); // Add glow effect using point light const sunLight = new THREE.PointLight(0xffee88, 1.5, 300, 2); sunLight.position.set(0, 0, 0); scene.add(sunLight); scene.add(sun); return sun; } // Mouse controls function setupControls() { const state = { mouseX: 0, mouseY: 0, targetRotationX: 0, targetRotationY: 0, targetZoom: 50, rotationX: 0, rotationY: 0, isDragging: false, prevX: 0, prevY: 0 }; // Mouse movement tracking document.addEventListener('mousedown', (e) => { state.isDragging = true; state.prevX = e.clientX; state.prevY = e.clientY; }); document.addEventListener('mousemove', (e) => { if (!state.isDragging) return; const deltaX = e.clientX - state.prevX; const deltaY = e.clientY - state.prevY; state.targetRotationY += deltaX * 0.01; state.targetRotationX += deltaY * 0.01; state.prevX = e.clientX; state.prevY = e.clientY; }); document.addEventListener('mouseup', () => { state.isDragging = false; }); document.addEventListener('mouseleave', () => { state.isDragging = false; }); // Zoom with scroll wheel document.addEventListener('wheel', (e) => { state.targetZoom += e.deltaY * 0.1; state.targetZoom = Math.min(Math.max(state.targetZoom, 20), 100); }); return state; } // Create celestial bodies createStars(); createSun(); // Planets data: name, size, color, distance, speed const planets = [ ["Mercury", 0.8, 0xAAAAAA, 10, 0.015], ["Venus", 1.2, 0xFFC68C, 15, 0.012], ["Earth", 1.3, 0x6B93D6, 21, 0.01], ["Mars", 1.1, 0xC1440E, 27, 0.008], ["Jupiter", 2.5, 0xC88B3A, 35, 0.005], ["Saturn", 2.2, 0xE3E0C0, 45, 0.003], ["Uranus", 1.8, 0x95B3DE, 54, 0.002], ["Neptune", 1.8, 0x366896, 62, 0.001] ]; const planetObjects = planets.map(data => createPlanet(...data) ); // Add Saturn's rings function addSaturnRings() { const ringGeometry = new THREE.RingGeometry(2.5, 3.5, 64); const ringMaterial = new THREE.MeshLambertMaterial({ color: 0xC8C8A9, side: THREE.DoubleSide }); const rings = new THREE.Mesh(ringGeometry, ringMaterial); rings.rotation.x = Math.PI / 2; // Flatten the rings planetObjects[5].mesh.add(rings); } addSaturnRings(); const controlsState = setupControls(); // Handle window resize window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // Animation loop function animate(time) { requestAnimationFrame(animate); // Smooth camera rotation controlsState.rotationX += (controlsState.targetRotationX - controlsState.rotationX) * 0.1; controlsState.rotationY += (controlsState.targetRotationY - controlsState.rotationY) * 0.1; camera.position.z += (controlsState.targetZoom - camera.position.z) * 0.1; const rotation = new THREE.Euler( controlsState.rotationX, controlsState.rotationY, 0, 'YXZ' ); const dir = new THREE.Vector3(0, 0, 1).applyEuler(rotation); camera.position.copy(dir.multiplyScalar(camera.position.z)); camera.lookAt(scene.position); // Rotate planets planetObjects.forEach(planet => { planet.group.rotation.y += planet.speed; }); renderer.render(scene, camera); } animate(); </script> </body> </html> This self-contained file includes: 1. Interactive 3D solar system with Sun and 8 planets (Mercury to Neptune) 2. Planet-specific characteristics: - Varying sizes scaled relatively - Unique colors - Different orbital distances and speeds - Saturn with visible rings 3. Camera controls: - Drag to rotate view around the solar system - Scroll wheel to zoom in/out - Smooth camera transitions 4. Background features: - 10,000 randomly placed stars - Sun with glowing light effect 5. Responsive design that adapts to window size 6. Simple UI information panel All code is contained within a single HTML file with no external dependencies except the provided three.min.js library.

TAKE IT TO CODE

This run produced no artifact — reuse the prompt with a different model or your own pi-agent run.

RUN

modeldeepseek-r1-0528
vendorDeepSeek
harnesspi-agent
generated2026-08-01

METRICS

runtime280.0s
tokens in1.5k
tokens out5.9k
cached0
cost / run$0.0133