All MicroEvals
Build a single, self-contained HTML file that renders an ani...
Create MicroEval

Build a single, self-contained HTML file that renders an ani...

Prompt

Build a single, self-contained HTML file that renders an animated mechanical orrery inside a glass dome, using Three.js. Output only the complete HTML file in one code block, with no explanation before or after. ## Technical constraints - Load Three.js r128 from https://cdnjs.cloudflare.com (`three.min.js`). Do not use ES module imports, import maps, or any other CDN. - Do not load any external textures, models, or fonts. Generate every texture procedurally with CanvasTexture, DataTexture, or shaders. - Use a seeded PRNG (mulberry32, seed 1337) for all randomness so the output is identical on every run. - Animation must be frame-rate independent: drive all motion from elapsed time, not frame count. - Handle window resize, including devicePixelRatio (cap at 2). - Use no external controls libraries. Implement orbit controls yourself: left-drag rotates, wheel zooms, with clamped polar angle. ## Scene requirements **1. Central sun and planetary system** - A sun at the origin with an emissive, animated surface made by a custom ShaderMaterial. It should show procedural noise-based granulation that scrolls over time. - Six planets on elliptical orbits, each with a different inclination. Orbital speeds must follow Kepler's third law: period ∝ a^1.5, with the inner planet at 2 seconds per orbit. - Each planet has a procedurally generated canvas texture (craters for one, bands for another, ice caps for another, and so on) and a MeshStandardMaterial with roughness and metalness maps derived from the same canvas. - One planet has a rim-lit atmosphere: a second, slightly larger sphere with a custom fresnel shader using additive blending and no depth writing. - One planet has a ring system built from a RingGeometry whose UVs map a procedural radial stripe texture with alpha. **2. Asteroid belt** - Between the 3rd and 4th planets, render 8,000 asteroids using InstancedMesh with a single icosahedron geometry deformed by seeded noise. Each instance has a random scale, rotation, and orbital phase. Update instance matrices on the CPU each frame (or in a vertex shader; either is acceptable, but document which one in a comment). - Asteroids use vertex colors for variation, and their orbital motion must follow the same Kepler scaling as the planets. **3. Mechanical gear train (the hard part)** - Under the dome base, build a visible gear train of at least 5 meshing gears. Gears are ExtrudeGeometry from a Shape with real teeth (parametric involute or trapezoidal teeth, correct tooth count). - Gear rotation ratios must match tooth counts. Compute angular velocity from the gear ratios, and link the gear train to the sun's rotation so the whole mechanism stays in sync. - Add a piston or lever linkage driven by one gear through a crank: a slider-crank whose endpoint position is computed analytically each frame. **4. Lighting and shadows** - One DirectionalLight casts shadows (PCFSoftShadowMap, 2048Γ—2048, tuned shadow camera bounds so nothing is clipped). - One PointLight at the sun with decay 2, and a hemisphere light for fill. - Set physically correct light intensities. Tone mapping must be ACESFilmic with exposure 1.1. **5. Environment and reflections** - Generate an environment map at runtime: render a small procedural scene (gradient sky plus a few emissive panels) into a WebGLCubeRenderTarget, then run it through PMREMGenerator and assign the result to scene.environment. Glass and metal materials must visibly reflect it. **6. Glass dome** - The dome is a SphereGeometry (upper hemisphere only) with MeshPhysicalMaterial using transmission β‰ˆ 1, thickness β‰ˆ 0.5, roughness β‰ˆ 0.05, and ior β‰ˆ 1.5. - Render the dome with transparent: true and renderOrder set so the interior is correctly visible through it. **7. Cross-section clipping** - A global clipping plane controlled by a UI slider (HTML range input, positioned top-left, labeled "Section"). Moving the slider cuts the scene along the Y axis. Apply clipping to all materials, and render a visible cap or outline at the cut so the cut is readable. **8. Picking and highlighting** - Clicking a planet or asteroid raycasts to the nearest object. The clicked planet gets an emissive pulse animation and a 2D label showing its name and orbital period. The label must track the planet's projected screen position every frame. - For InstancedMesh, use the instance ID from the intersection to highlight only that asteroid. **9. Post-processing** - Implement a bloom pass manually using EffectComposer-free render targets: render the scene to a HalfFloat target, extract bright pixels with a shader, apply a separable Gaussian blur at two scales, and composite additively. Don't use the examples/ addons. ## Verification hooks (required) Expose these on `window` so an automated grader can test the scene: - `window.__ready`: set to `true` only after the first full frame including shadows and the PMREM environment has rendered. - `window.__stats`: an object updated every frame with `{ fps, drawCalls, triangles, instanceCount, planetCount, gearCount, sunRotation, planetPositions: [{name, x, y, z}] }`. Use `renderer.info` for draw calls and triangles. - `window.__setTime(t)`: sets the simulation clock to t seconds, freezes the real clock, and renders one frame. This lets graders compare states deterministically. - `window.__pick(ndcX, ndcY)`: runs the same raycast as a click and returns `{hit: boolean, name: string|null, instanceId: number|null}`. ## Quality bar - No console errors or WebGL warnings. Dispose geometries and textures when rebuilding anything at runtime. - Keep the code organized into clearly labeled sections (Setup, Textures, Planets, Asteroids, Gears, Lighting, Environment, Dome, Clipping, Picking, Post, Loop, Hooks). - The file should run at 60 fps on a mid-range laptop GPU. Explain any intentional performance trade-off in a short comment in the code.

A system prompt was added to support web rendering

Response not available

Drag to resize
Drag to resize
Drag to resize
Drag to resize
Drag to resize