Nemotron 3 Ultra (free)
by NVIDIAReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 1 min 16 s
- Cost
- $0
- Output tokens
- 6,473
- Spent thinking
- 0 tokens
- Speed
- 85.4 tok/s
- Console errors
- 0
- First token after
- 667 ms
- First visible text after
- 667 ms
- Prompt tokens
- 584
- Code size
- 21.1 KB
- Finish reason
- stop
- Served by
- Nvidia
- Model id
nvidia/nemotron-3-ultra-550b-a55b:free- Reasoning sent
{"effort":"none"}- Max output
- 32,000 tokens
- Generated
- Nov 9, 2026
What it was asked
The prompt
Build a low-poly 3D scene of a campfire in a forest clearing at night, with Three.js in a single HTML file. Load Three.js only through this import map (do not use any other URL or version): <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> Requirements: - A ground with a few low-poly rocks and logs around a campfire in the center. - At least 30 low-poly trees placed randomly around the clearing (not on the fire). - The campfire has animated flames and a warm point light that flickers and casts shadows. - Sparks rising from the fire as a simple particle system. - A dark night sky with stars and a moon, plus fog that fades the distant trees. - OrbitControls to look around, with limits so the camera stays above the ground. - The renderer fills the window and handles resizing correctly.
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 · 610 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Low Poly Campfire</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { overflow: hidden; background: #0a0a1a; font-family: sans-serif; }
canvas { display: block; }
#info {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
color: #fff;
text-align: center;
pointer-events: none;
text-shadow: 0 0 10px rgba(0,0,0,0.8);
z-index: 10;
}
#info h1 { font-size: 1.5rem; font-weight: 300; letter-spacing: 2px; margin-bottom: 5px; }
#info p { font-size: 0.85rem; color: #aaa; }
</style>
</head>
<body>
<div id="info">
<h1>Low Poly Campfire</h1>
<p>Drag to orbit • Scroll to zoom</p>
</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';
// Scene setup
const scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x0a0a1a, 15, 60);
// Renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.2;
document.body.appendChild(renderer.domElement);
// Camera
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 8, 12);
// Controls
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.enablePan = false;
controls.minDistance = 5;
controls.maxDistance = 30;
controls.maxPolarAngle = Math.PI / 2 - 0.05;
controls.minPolarAngle = 0.1;
controls.target.set(0, 1, 0);
// Materials
const groundMat = new THREE.MeshStandardMaterial({
color: 0x1a1510,
roughness: 0.9,
metalness: 0,
flatShading: true
});
const rockMat = new THREE.MeshStandardMaterial({
color: 0x3a3530,
roughness: 0.95,
metalness: 0,
flatShading: true
});
const logMat = new THREE.MeshStandardMaterial({
color: 0x2a1a0a,
roughness: 0.9,
metalness: 0,
flatShading: true
});
const trunkMat = new THREE.MeshStandardMaterial({
color: 0x2a1f15,
roughness: 0.95,
metalness: 0,
flatShading: true
});
const leafMat = new THREE.MeshStandardMaterial({
color: 0x1a3a1a,
roughness: 0.9,
metalness: 0,
flatShading: true
});
// Ground
const groundGeo = new THREE.CircleGeometry(50, 64);
const ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
// Campfire base - rocks in a circle
const fireRocks = new THREE.Group();
for (let i = 0; i < 12; i++) {
const angle = (i / 12) * Math.PI * 2;
const radius = 1.2 + Math.random() * 0.3;
const rockGeo = new THREE.DodecahedronGeometry(0.4 + Math.random() * 0.3, 0);
const rock = new THREE.Mesh(rockGeo, rockMat);
rock.position.set(
Math.cos(angle) * radius,
0.15 + Math.random() * 0.1,
Math.sin(angle) * radius
);
rock.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, Math.random() * Math.PI);
rock.scale.setScalar(0.7 + Math.random() * 0.5);
rock.castShadow = true;
rock.receiveShadow = true;
fireRocks.add(rock);
}
scene.add(fireRocks);
// Logs around fire
const logs = new THREE.Group();
for (let i = 0; i < 6; i++) {
const angle = (i / 6) * Math.PI * 2 + Math.random() * 0.3;
const radius = 1.0;
const logGeo = new THREE.CylinderGeometry(0.15, 0.18, 1.2, 6);
const log = new THREE.Mesh(logGeo, logMat);
log.position.set(
Math.cos(angle) * radius,
0.35,
Math.sin(angle) * radius
);
log.rotation.z = angle + Math.PI / 2 + (Math.random() - 0.5) * 0.4;
log.rotation.x = (Math.random() - 0.5) * 0.3;
log.castShadow = true;
log.receiveShadow = true;
logs.add(log);
}
// Cross logs
for (let i = 0; i < 3; i++) {
const angle = (i / 3) * Math.PI * 2;
const logGeo = new THREE.CylinderGeometry(0.12, 0.15, 1.5, 6);
const log = new THREE.Mesh(logGeo, logMat);
log.position.set(
Math.cos(angle) * 0.4,
0.65,
Math.sin(angle) * 0.4
);
log.rotation.z = angle + (Math.random() - 0.5) * 0.3;
log.rotation.x = (Math.random() - 0.5) * 0.4;
log.castShadow = true;
log.receiveShadow = true;
logs.add(log);
}
scene.add(logs);
// Fire light
const fireLight = new THREE.PointLight(0xff6600, 80, 25, 2);
fireLight.position.set(0, 1.5, 0);
fireLight.castShadow = true;
fireLight.shadow.mapSize.width = 512;
fireLight.shadow.mapSize.height = 512;
fireLight.shadow.camera.near = 0.5;
fireLight.shadow.camera.far = 25;
fireLight.shadow.bias = -0.0005;
scene.add(fireLight);
// Ambient moonlight
const moonLight = new THREE.DirectionalLight(0x6688aa, 0.3);
moonLight.position.set(10, 20, 10);
moonLight.castShadow = true;
moonLight.shadow.mapSize.width = 2048;
moonLight.shadow.mapSize.height = 2048;
moonLight.shadow.camera.left = -30;
moonLight.shadow.camera.right = 30;
moonLight.shadow.camera.top = 30;
moonLight.shadow.camera.bottom = -30;
moonLight.shadow.camera.near = 1;
moonLight.shadow.camera.far = 60;
moonLight.shadow.bias = -0.0002;
scene.add(moonLight);
// Hemisphere light for subtle fill
const hemiLight = new THREE.HemisphereLight(0x223344, 0x111122, 0.4);
scene.add(hemiLight);
// Flame geometry - using multiple cone layers with animated vertices
const flameGroup = new THREE.Group();
// Create flame layers
const flameGeometries = [];
const flameMeshes = [];
const baseFlamePositions = [];
for (let layer = 0; layer < 4; layer++) {
const height = 0.8 + layer * 0.5;
const radius = 0.4 - layer * 0.08;
const geo = new THREE.ConeGeometry(radius, height, 6, 1, true);
geo.translate(0, height / 2 + 0.3 + layer * 0.15, 0);
// Store base vertex positions for animation
const positions = geo.attributes.position.array;
const basePositions = new Float32Array(positions.length);
basePositions.set(positions);
baseFlamePositions.push(basePositions);
flameGeometries.push(geo);
const mat = new THREE.MeshBasicMaterial({
color: layer < 2 ? 0xff5500 : 0xffaa00,
transparent: true,
opacity: 0.7 - layer * 0.1,
depthWrite: false,
side: THREE.DoubleSide
});
const mesh = new THREE.Mesh(geo, mat);
flameMeshes.push(mesh);
flameGroup.add(mesh);
}
// Inner glow
const glowGeo = new THREE.SphereGeometry(0.5, 16, 16);
const glowMat = new THREE.MeshBasicMaterial({
color: 0xff4400,
transparent: true,
opacity: 0.4,
depthWrite: false
});
const glow = new THREE.Mesh(glowGeo, glowMat);
glow.position.y = 1.2;
glow.scale.set(1.2, 1.8, 1.2);
flameGroup.add(glow);
scene.add(flameGroup);
// Sparks particle system
const sparkCount = 150;
const sparkGeo = new THREE.BufferGeometry();
const sparkPositions = new Float32Array(sparkCount * 3);
const sparkVelocities = new Float32Array(sparkCount * 3);
const sparkLifetimes = new Float32Array(sparkCount);
const sparkSizes = new Float32Array(sparkCount);
const sparkColors = new Float32Array(sparkCount * 3);
for (let i = 0; i < sparkCount; i++) {
resetSpark(i);
}
function resetSpark(i) {
const angle = Math.random() * Math.PI * 2;
const radius = Math.random() * 0.3;
sparkPositions[i * 3] = Math.cos(angle) * radius;
sparkPositions[i * 3 + 1] = 0.5 + Math.random() * 0.5;
sparkPositions[i * 3 + 2] = Math.sin(angle) * radius;
sparkVelocities[i * 3] = (Math.random() - 0.5) * 0.02;
sparkVelocities[i * 3 + 1] = 0.05 + Math.random() * 0.1;
sparkVelocities[i * 3 + 2] = (Math.random() - 0.5) * 0.02;
sparkLifetimes[i] = 1.0;
sparkSizes[i] = 0.02 + Math.random() * 0.03;
const colorChoice = Math.random();
if (colorChoice < 0.5) {
sparkColors[i * 3] = 1;
sparkColors[i * 3 + 1] = 0.5 + Math.random() * 0.3;
sparkColors[i * 3 + 2] = 0.1;
} else if (colorChoice < 0.8) {
sparkColors[i * 3] = 1;
sparkColors[i * 3 + 1] = 0.8 + Math.random() * 0.2;
sparkColors[i * 3 + 2] = 0.2;
} else {
sparkColors[i * 3] = 1;
sparkColors[i * 3 + 1] = 1;
sparkColors[i * 3 + 2] = 0.6;
}
}
sparkGeo.setAttribute('position', new THREE.BufferAttribute(sparkPositions, 3));
sparkGeo.setAttribute('size', new THREE.BufferAttribute(sparkSizes, 1));
sparkGeo.setAttribute('color', new THREE.BufferAttribute(sparkColors, 3));
const sparkMat = new THREE.PointsMaterial({
size: 1,
vertexColors: true,
transparent: true,
opacity: 0.9,
depthWrite: false,
blending: THREE.AdditiveBlending,
sizeAttenuation: true
});
const sparks = new THREE.Points(sparkGeo, sparkMat);
scene.add(sparks);
// Trees
const trees = new THREE.Group();
const treePositions = [];
// Create tree template
function createTree() {
const tree = new THREE.Group();
// Trunk
const trunkHeight = 2 + Math.random() * 2;
const trunkGeo = new THREE.CylinderGeometry(0.15, 0.25, trunkHeight, 6);
const trunk = new THREE.Mesh(trunkGeo, trunkMat);
trunk.position.y = trunkHeight / 2;
trunk.castShadow = true;
trunk.receiveShadow = true;
tree.add(trunk);
// Foliage layers (low poly)
const layerCount = 3 + Math.floor(Math.random() * 3);
for (let i = 0; i < layerCount; i++) {
const layerHeight = 0.8 + Math.random() * 0.6;
const layerRadius = 1.0 - i * 0.18 + Math.random() * 0.3;
const leafGeo = new THREE.ConeGeometry(layerRadius, layerHeight, 6);
leafGeo.translate(0, layerHeight / 2, 0);
const leaves = new THREE.Mesh(leafGeo, leafMat);
leaves.position.y = trunkHeight * 0.5 + i * 0.8;
leaves.rotation.y = Math.random() * Math.PI * 2;
leaves.scale.y = 0.8 + Math.random() * 0.4;
leaves.castShadow = true;
leaves.receiveShadow = true;
tree.add(leaves);
}
// Color variation
const hueShift = (Math.random() - 0.5) * 0.1;
tree.traverse(child => {
if (child.isMesh && child.material.color) {
const color = child.material.color.clone();
color.offsetHSL(hueShift, 0, (Math.random() - 0.5) * 0.1);
child.material = child.material.clone();
child.material.color = color;
}
});
return tree;
}
// Place trees randomly around clearing
for (let i = 0; i < 35; i++) {
let x, z;
let attempts = 0;
do {
const angle = Math.random() * Math.PI * 2;
const radius = 8 + Math.random() * 25;
x = Math.cos(angle) * radius;
z = Math.sin(angle) * radius;
attempts++;
} while (x * x + z * z < 4 * 4 && attempts < 50); // Keep away from fire
const tree = createTree();
tree.position.set(x, 0, z);
tree.rotation.y = Math.random() * Math.PI * 2;
tree.scale.setScalar(0.7 + Math.random() * 0.6);
trees.add(tree);
treePositions.push({ x, z, tree });
}
scene.add(trees);
// Rocks and logs scattered around
const debris = new THREE.Group();
// Rocks
for (let i = 0; i < 20; i++) {
const angle = Math.random() * Math.PI * 2;
const radius = 4 + Math.random() * 22;
const x = Math.cos(angle) * radius;
const z = Math.sin(angle) * radius;
if (x * x + z * z < 3 * 3) continue;
const rockGeo = new THREE.DodecahedronGeometry(0.3 + Math.random() * 0.5, 0);
const rock = new THREE.Mesh(rockGeo, rockMat);
rock.position.set(x, 0.15, z);
rock.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, Math.random() * Math.PI);
rock.scale.setScalar(0.5 + Math.random() * 1.2);
rock.castShadow = true;
rock.receiveShadow = true;
debris.add(rock);
}
// Fallen logs
for (let i = 0; i < 12; i++) {
const angle = Math.random() * Math.PI * 2;
const radius = 5 + Math.random() * 20;
const x = Math.cos(angle) * radius;
const z = Math.sin(angle) * radius;
if (x * x + z * z < 3 * 3) continue;
const logGeo = new THREE.CylinderGeometry(0.12, 0.18, 1.5 + Math.random() * 1.5, 6);
const log = new THREE.Mesh(logGeo, logMat);
log.position.set(x, 0.15, z);
log.rotation.set(
(Math.random() - 0.5) * 0.3,
Math.random() * Math.PI * 2,
(Math.random() - 0.5) * 0.3
);
log.castShadow = true;
log.receiveShadow = true;
debris.add(log);
}
scene.add(debris);
// Sky dome with stars
const skyGeo = new THREE.SphereGeometry(80, 32, 32);
skyGeo.scale(-1, 1, 1); // Invert normals
const skyMat = new THREE.MeshBasicMaterial({
color: 0x050510,
fog: false
});
const sky = new THREE.Mesh(skyGeo, skyMat);
scene.add(sky);
// Stars as points
const starCount = 2000;
const starGeo = new THREE.BufferGeometry();
const starPositions = new Float32Array(starCount * 3);
const starSizes = new Float32Array(starCount);
const starAlphas = new Float32Array(starCount);
const starPhases = new Float32Array(starCount);
for (let i = 0; i < starCount; i++) {
const radius = 75;
const theta = Math.random() * Math.PI * 2;
const phi = Math.acos(2 * Math.random() - 1);
starPositions[i * 3] = radius * Math.sin(phi) * Math.cos(theta);
starPositions[i * 3 + 1] = radius * Math.sin(phi) * Math.sin(theta);
starPositions[i * 3 + 2] = radius * Math.cos(phi);
starSizes[i] = 0.5 + Math.random() * 1.5;
starAlphas[i] = 0.3 + Math.random() * 0.7;
starPhases[i] = Math.random() * Math.PI * 2;
}
starGeo.setAttribute('position', new THREE.BufferAttribute(starPositions, 3));
starGeo.setAttribute('size', new THREE.BufferAttribute(starSizes, 1));
starGeo.setAttribute('alpha', new THREE.BufferAttribute(starAlphas, 1));
starGeo.setAttribute('phase', new THREE.BufferAttribute(starPhases, 1));
const starMat = new THREE.PointsMaterial({
color: 0xffffff,
size: 1,
vertexColors: false,
transparent: true,
opacity: 1,
depthWrite: false,
sizeAttenuation: false,
blending: THREE.AdditiveBlending
});
// Custom shader for twinkling stars
starMat.onBeforeCompile = (shader) => {
shader.uniforms.uTime = { value: 0 };
shader.vertexShader = `
attribute float alpha;
attribute float phase;
uniform float uTime;
varying float vAlpha;
${shader.vertexShader}
`.replace(
'void main() {',
`void main() {
vAlpha = alpha * (0.7 + 0.3 * sin(uTime * 2.0 + phase * 10.0));
`
);
shader.fragmentShader = `
varying float vAlpha;
${shader.fragmentShader}
`.replace(
'gl_FragColor = vec4( outgoingLight, diffuseColor.a );',
`gl_FragColor = vec4( outgoingLight, vAlpha );`
);
};
const stars = new THREE.Points(starGeo, starMat);
scene.add(stars);
// Moon
const moonGeo = new THREE.SphereGeometry(3, 32, 32);
const moonMat = new THREE.MeshBasicMaterial({
color: 0xf0e8d8,
transparent: true,
opacity: 0.9,
depthWrite: false
});
const moon = new THREE.Mesh(moonGeo, moonMat);
moon.position.set(-25, 30, -20);
moon.scale.setScalar(1.5);
scene.add(moon);
// Moon glow
const moonGlowGeo = new THREE.SphereGeometry(4, 16, 16);
const moonGlowMat = new THREE.MeshBasicMaterial({
color: 0x88aacc,
transparent: true,
opacity: 0.08,
depthWrite: false,
side: THREE.BackSide
});
const moonGlow = new THREE.Mesh(moonGlowGeo, moonGlowMat);
moonGlow.position.copy(moon.position);
scene.add(moonGlow);
// Animation
let time = 0;
const clock = new THREE.Clock();
function animate() {
const dt = clock.getDelta();
time += dt;
// Flame animation
flameMeshes.forEach((mesh, layer) => {
const positions = mesh.geometry.attributes.position.array;
const basePositions = baseFlamePositions[layer];
for (let i = 0; i < positions.length; i += 3) {
const y = basePositions[i + 1];
const h = mesh.geometry.parameters.height;
const factor = Math.pow(y / h, 1.5);
const noiseX = Math.sin(time * 3 + y * 5 + i * 0.1) * 0.03 * factor;
const noiseZ = Math.cos(time * 2.5 + y * 5 + i * 0.1) * 0.03 * factor;
const noiseY = Math.sin(time * 4 + y * 3 + i * 0.05) * 0.02 * factor;
positions[i] = basePositions[i] + noiseX;
positions[i + 1] = basePositions[i + 1] + noiseY;
positions[i + 2] = basePositions[i + 2] + noiseZ;
}
mesh.geometry.attributes.position.needsUpdate = true;
mesh.geometry.computeVertexNormals();
// Rotate flames slightly
mesh.rotation.y = time * 0.3 * (layer % 2 === 0 ? 1 : -1);
// Pulse opacity
mesh.material.opacity = (0.7 - layer * 0.1) * (0.85 + 0.15 * Math.sin(time * 5 + layer));
});
// Glow pulse
glow.scale.y = 1.8 + Math.sin(time * 4) * 0.2;
glow.scale.x = glow.scale.z = 1.2 + Math.sin(time * 3.5) * 0.15;
glow.material.opacity = 0.35 + 0.1 * Math.sin(time * 3);
glow.rotation.y += dt * 0.5;
// Fire light flicker
fireLight.intensity = 60 + Math.sin(time * 4) * 15 + Math.sin(time * 7.3) * 8 + Math.random() * 5;
fireLight.color.setHSL(0.05, 1, 0.4 + Math.sin(time * 3) * 0.05);
fireLight.position.x = Math.sin(time * 1.7) * 0.1;
fireLight.position.z = Math.cos(time * 1.3) * 0.1;
// Sparks update
for (let i = 0; i < sparkCount; i++) {
sparkPositions[i * 3] += sparkVelocities[i * 3];
sparkPositions[i * 3 + 1] += sparkVelocities[i * 3 + 1];
sparkPositions[i * 3 + 2] += sparkVelocities[i * 3 + 2];
// Gravity and air resistance
sparkVelocities[i * 3 + 1] -= 0.0015;
sparkVelocities[i * 3] *= 0.995;
sparkVelocities[i * 3 + 2] *= 0.995;
sparkLifetimes[i] -= dt * 0.8;
if (sparkLifetimes[i] <= 0 || sparkPositions[i * 3 + 1] < 0.2) {
resetSpark(i);
}
}
sparkGeo.attributes.position.needsUpdate = true;
// Stars twinkle
if (starMat.uniforms) {
starMat.uniforms.uTime.value = time;
}
// Subtle camera drift
controls.target.x = Math.sin(time * 0.1) * 0.15;
controls.target.z = Math.cos(time * 0.1) * 0.15;
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
// Handle resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
animate();
</script>
</body>
</html>