Models 44

Nemotron 3.5 Super VL (free)

by NVIDIAReasoningClean
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
37.1 s
Cost
$0
Output tokens
4,451
Spent thinking
0 tokens
Speed
121.2 tok/s
Console errors
0
First token after
356 ms
First visible text after
356 ms
Prompt tokens
448
Code size
13.5 KB
Finish reason
stop
Served by
Nvidia
Model id
nvidia/nemotron-3.5-super-vl:free
Reasoning sent
{"effort":"none"}
Max output
32,000 tokens
Generated
Nov 9, 2026

What it was asked

The prompt
“a 3D aquarium with Three.js where the fish swim away when I move the mouse near them (Load Three.js only through this import map: <script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"}}</script>)”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task.

Output rules:
- Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block.
- Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task.
- Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw.
- The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar.
- Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction.
- Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session.
- Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing.
- The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message.
- The code must run with zero errors in the console of the latest Chrome.

Code run-1.html · 463 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Aquarium - Mouse Repellent Fish</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { overflow: hidden; background: #050510; font-family: system-ui, sans-serif; }

#canvas {
  position: absolute;
  top: 0; left: 0;
  width: 100vw; height: 100vh;
  display: block;
}

#ui {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: white;
  text-align: center;
  z-index: 10;
}

#hint {
  background: rgba(10, 20, 40, 0.75);
  padding: 1rem 1.5rem;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  box-shadow: 0 8px 32px rgba(0,0,0,0.4);
}

#hint h1 { font-size: 1.6rem; margin-bottom: 0.25rem; font-weight: 600; letter-spacing: 0.5px; }
#hint p { font-size: 0.9rem; opacity: 0.85; line-height: 1.4; }

#stat {
  position: absolute;
  top: 12px; left: 12px;
  color: rgba(255,255,255,0.7);
  font-size: 0.85rem;
  pointer-events: none;
  z-index: 10;
}
</style>
</head>
<body>
<div id="canvas"></div>
<div id="ui">
  <div id="hint">
    <h1>3D Aquarium</h1>
    <p>Move your mouse near the fish to scare them away</p>
  </div>
</div>
<div id="stat">Fish: <span id="fishCount">12</span></div>

<script type="importmap">
{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"}}
</script>

<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

// Resize-safe container
const container = document.getElementById('canvas');
const hint = document.getElementById('hint');
const hintTitle = hint.querySelector('h1');
const hintText = hint.querySelector('p');

// Scene setup
const scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x050510, 0.018);

const camera = new THREE.PerspectiveCamera(55, innerWidth / innerHeight, 0.1, 100);
camera.position.set(0, 2, 8);

const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(innerWidth, innerHeight);
renderer.setClearColor(0x050510, 1);
container.appendChild(renderer.domElement);

// Controls (subtle)
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.enableZoom = false;
controls.enablePan = false;
controls.autoRotate = true;
controls.autoRotateSpeed = 0.4;
controls.minPolarAngle = Math.PI / 2 - 1.2;
controls.maxPolarAngle = Math.PI / 2 + 0.6;

// Lights
const ambient = new THREE.AmbientLight(0xffffff, 0.35);
scene.add(ambient);

const dirLight = new THREE.DirectionalLight(0xffffff, 1.0);
dirLight.position.set(5, 10, 7);
scene.add(dirLight);

const pointLight = new THREE.PointLight(0x00ffff, 1.5, 12);
pointLight.position.set(0, 0, 0);
scene.add(pointLight);

// Bubbles helper
function createBubbles(count, range) {
  const geo = new THREE.SphereGeometry(0.02, 6, 6);
  const mat = new THREE.MeshStandardMaterial({ color: 0xffffff, transparent: true, opacity: 0.6 });
  const group = new THREE.Group();
  for (let i = 0; i < count; i++) {
    const m = new THREE.Mesh(geo, mat);
    m.position.set(
      (Math.random() - 0.5) * range * 2,
      Math.random() * range,
      (Math.random() - 0.5) * range * 2
    );
    m.userData = { speed: 0.01 + Math.random() * 0.02, yRange: range };
    group.add(m);
  }
  scene.add(group);
  return group;
}

const bubbleGroup = createBubbles(40, 6);

// Floor
const floorGeo = new THREE.PlaneGeometry(30, 30);
const floorMat = new THREE.MeshStandardMaterial({
  color: 0x0a1426,
  roughness: 0.8,
  metalness: 0.1,
  transparent: true,
  opacity: 0.5
});
const floor = new THREE.Mesh(floorGeo, floorMat);
floor.rotation.x = -Math.PI / 2;
floor.position.y = -4;
scene.add(floor);

// Tank decoration: coral-ish simple torus
function addCoral(x, z, color) {
  const geo = new THREE.TorusKnotGeometry(0.15, 0.04, 60, 16);
  const mat = new THREE.MeshStandardMaterial({ color, roughness: 0.7 });
  const m = new THREE.Mesh(geo, mat);
  m.position.set(x, -3.6, z);
  m.scale.set(0.6, 0.6, 0.6);
  scene.add(m);
}
addCoral(-6, -4, 0xff3366);
addCoral(6, -4, 0x33ff99);
addCoral(-4, 4, 0x3399ff);
addCoral(4, 4, 0xffcc00);

// Fish class
class Fish {
  constructor() {
    // Build fish geometry (body + tail + fins)
    const group = new THREE.Group();

    // Body: stretched sphere
    const bodyGeo = new THREE.SphereGeometry(0.25, 16, 16);
    const bodyMat = new THREE.MeshStandardMaterial({
      color: new THREE.Color().setHSL(Math.random(), 0.7, 0.5),
      roughness: 0.4,
      metalness: 0.1
    });
    this.body = new THREE.Mesh(bodyGeo, bodyMat);
    this.body.scale.set(1.4, 0.8, 0.6);
    group.add(this.body);

    // Tail
    const tailGeo = new THREE.ConeGeometry(0.15, 0.5, 4);
    const tailMat = new THREE.MeshStandardMaterial({ color: this.body.material.color, transparent: true, opacity: 0.8 });
    this.tail = new THREE.Mesh(tailGeo, tailMat);
    this.tail.position.set(-0.35, 0, 0);
    this.tail.rotation.z = Math.PI / 2;
    group.add(this.tail);

    // Top fin
    const finGeo = new THREE.ConeGeometry(0.1, 0.3, 4);
    const finMat = new THREE.MeshStandardMaterial({ color: 0x222222, transparent: true, opacity: 0.6 });
    this.fin = new THREE.Mesh(finGeo, finMat);
    this.fin.position.set(0, 0.15, 0);
    this.fin.rotation.x = -Math.PI / 4;
    group.add(this.fin);

    // Eye
    const eyeGeo = new THREE.SphereGeometry(0.04, 8, 8);
    const eyeMat = new THREE.MeshBasicMaterial({ color: 0xffffff });
    this.eye = new THREE.Mesh(eyeGeo, eyeMat);
    this.eye.position.set(0.25, 0.08, 0.22);
    group.add(this.eye);

    scene.add(group);
    this.mesh = group;

    // State
    this.position = new THREE.Vector3(
      (Math.random() - 0.5) * 12,
      (Math.random() - 0.5) * 4,
      (Math.random() - 0.5) * 12
    );
    this.velocity = new THREE.Vector3();
    this.acceleration = new THREE.Vector3();
    this.maxSpeed = 0.06 + Math.random() * 0.04;
    this.maxForce = 0.002;
    this.neighborRadius = 2;
    this.desiredSeparation = 1.2;

    // Facing
    const angle = Math.random() * Math.PI * 2;
    this.velocity.set(Math.cos(angle), 0, Math.sin(angle)).normalize().multiplyScalar(this.maxSpeed * 0.5);
    this.mesh.position.copy(this.position);
    this.updateOrientation();
  }

  updateOrientation() {
    if (this.velocity.lengthSq() > 0.0001) {
      this.mesh.lookAt(this.position.clone().add(this.velocity));
      // Roll based on turn
      this.mesh.rotateX(Math.PI / 2); // fish model faces -Z by default? adjust
    }
  }

  applyBehaviors(fishies, mousePos, repelRange) {
    const sep = this.separate(fishies);
    const ali = this.align(fishies);
    const coh = this.cohesion(fishies);
    const flee = this.flee(mousePos, repelRange);

    sep.multiplyScalar(1.5);
    ali.multiplyScalar(1.0);
    coh.multiplyScalar(1.0);
    flee.multiplyScalar(2.0);

    this.applyForce(sep);
    this.applyForce(ali);
    this.applyForce(coh);
    this.applyForce(flee);

    // Boundary soft steer
    const boundary = 10;
    const steer = new THREE.Vector3();
    if (Math.abs(this.position.x) > boundary) steer.x = -Math.sign(this.position.x) * 0.003;
    if (Math.abs(this.position.z) > boundary) steer.z = -Math.sign(this.position.z) * 0.003;
    if (this.position.y > 2.5) steer.y = -0.003;
    if (this.position.y < -5.5) steer.y = 0.003;
    this.applyForce(steer);

    // Random wander jitter
    if (Math.random() < 0.02) {
      this.applyForce(new THREE.Vector3(
        (Math.random() - 0.5) * 0.001,
        (Math.random() - 0.5) * 0.001,
        (Math.random() - 0.5) * 0.001
      ));
    }

    this.velocity.add(this.acceleration);
    const speed = this.velocity.length();
    if (speed > this.maxSpeed) this.velocity.setLength(this.maxSpeed);
    this.position.add(this.velocity);
    this.acceleration.set(0, 0, 0);

    // Keep within bounds
    this.position.x = Math.max(-11, Math.min(11, this.position.x));
    this.position.z = Math.max(-11, Math.min(11, this.position.z));
    this.position.y = Math.max(-5.8, Math.min(2.8, this.position.y));

    this.mesh.position.copy(this.position);
    this.updateOrientation();

    // Animate tail/body swim based on speed
    const swim = speed * 20;
    this.tail.rotation.z = Math.PI / 2 + Math.sin(Date.now() * 0.015 * swim) * 0.3;
    this.body.scale.y = 0.8 + Math.sin(Date.now() * 0.015 * swim) * 0.05;
  }

  applyForce(force) {
    this.acceleration.add(force);
  }

  separate(fishies) {
    const steer = new THREE.Vector3();
    let count = 0;
    for (let other of fishies) {
      const d = this.position.distanceTo(other.position);
      if (d > 0 && d < this.desiredSeparation) {
        const diff = new THREE.Vector3().subVectors(this.position, other.position).normalize().divideScalar(d);
        steer.add(diff);
        count++;
      }
    }
    if (count > 0) {
      steer.divideScalar(count);
      if (steer.lengthSq() > 0) {
        steer.normalize().multiplyScalar(this.maxSpeed).sub(this.velocity).clampLength(0, this.maxForce);
      }
    }
    return steer;
  }

  align(fishies) {
    const steer = new THREE.Vector3();
    let count = 0;
    for (let other of fishies) {
      const d = this.position.distanceTo(other.position);
      if (d > 0 && d < this.neighborRadius) {
        steer.add(other.velocity);
        count++;
      }
    }
    if (count > 0) {
      steer.divideScalar(count);
      steer.normalize().multiplyScalar(this.maxSpeed).sub(this.velocity).clampLength(0, this.maxForce);
    }
    return steer;
  }

  cohesion(fishies) {
    const steer = new THREE.Vector3();
    let count = 0;
    for (let other of fishies) {
      const d = this.position.distanceTo(other.position);
      if (d > 0 && d < this.neighborRadius) {
        steer.add(other.position);
        count++;
      }
    }
    if (count > 0) {
      steer.divideScalar(count);
      steer.sub(this.position);
      if (steer.lengthSq() > 0) {
        steer.normalize().multiplyScalar(this.maxSpeed).sub(this.velocity).clampLength(0, this.maxForce);
      }
    }
    return steer;
  }

  flee(mousePos, range) {
    const steer = new THREE.Vector3();
    const d = this.position.distanceTo(mousePos);
    if (d > 0 && d < range) {
      const diff = new THREE.Vector3().subVectors(this.position, mousePos).normalize().divideScalar(d);
      steer.add(diff);
      steer.normalize().multiplyScalar(this.maxSpeed * 1.5).sub(this.velocity).clampLength(0, this.maxForce * 2);
    }
    return steer;
  }
}

// Init fish
const fishCount = 14;
const fishies = [];
for (let i = 0; i < fishCount; i++) fishies.push(new Fish());
document.getElementById('fishCount').textContent = fishCount;

// Mouse state
const mouse = new THREE.Vector2(-100, -100); // start off-screen
const mouse3D = new THREE.Vector3(-100, 0, -100);
const repelRange = 3.5;

let pointerActive = false;

window.addEventListener('mousemove', (e) => {
  pointerActive = true;
  hint.style.opacity = '0';
  setTimeout(() => { hint.style.display = 'none'; }, 400);

  // Normalize mouse to -1..1
  mouse.x = (e.clientX / innerWidth) * 2 - 1;
  mouse.y = -(e.clientY / innerHeight) * 2 + 1;

  // Unproject to world plane at y=0 roughly
  mouse3D.set(mouse.x, mouse.y, 0.5);
  mouse3D.unproject(camera);
  // Project onto y=0 plane from camera
  const dir = new THREE.Vector3().subVectors(mouse3D, camera.position).normalize();
  const dist = -camera.position.y / dir.y;
  mouse3D.copy(camera.position).addScaledVector(dir, dist);
  mouse3D.y = 0;
});

// Touch support
window.addEventListener('touchmove', (e) => {
  if (e.touches.length === 0) return;
  pointerActive = true;
  hint.style.opacity = '0';
  setTimeout(() => { hint.style.display = 'none'; }, 400);
  const t = e.touches[0];
  mouse.x = (t.clientX / innerWidth) * 2 - 1;
  mouse.y = -(t.clientY / innerHeight) * 2 + 1;
  mouse3D.set(mouse.x, mouse.y, 0.5);
  mouse3D.unproject(camera);
  const dir = new THREE.Vector3().subVectors(mouse3D, camera.position).normalize();
  const dist = -camera.position.y / dir.y;
  mouse3D.copy(camera.position).addScaledVector(dir, dist);
  mouse3D.y = 0;
}, { passive: true });

// Hide hint after a few seconds even without interaction
setTimeout(() => {
  if (!pointerActive) {
    hint.style.transition = 'opacity 0.5s';
    hint.style.opacity = '0';
    setTimeout(() => { hint.style.display = 'none'; }, 500);
  }
}, 4000);

// Animation loop
const clock = new THREE.Clock();

function animate() {
  requestAnimationFrame(animate);

  const dt = clock.getDelta();
  const time = clock.getElapsedTime();

  // Subtle camera breathing
  camera.position.y = 2 + Math.sin(time * 0.3) * 0.3;
  camera.lookAt(0, -0.5, 0);

  controls.update();

  // Bubbles rise
  bubbleGroup.children.forEach(b => {
    b.position.y += b.userData.speed;
    b.position.x += Math.sin(time + b.position.y) * 0.002;
    b.position.z += Math.cos(time * 0.7 + b.position.z) * 0.002;
    if (b.position.y > 7) b.position.y = -4;
    b.material.opacity = 0.3 + Math.sin(time * 2 + b.position.y) * 0.2;
  });

  // Point light drift
  pointLight.position.set(Math.sin(time * 0.5) * 4, 2 + Math.sin(time * 0.7) * 1, Math.cos(time * 0.5) * 4);

  // Fish
  fishies.forEach(f => f.applyBehaviors(fishies, mouse3D, repelRange));

  renderer.render(scene, camera);
}

// Resize
window.addEventListener('resize', () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
});

// Start
animate();
</script>
</body>
</html>