This was a thin matchup on paper, but Kimi K3 still comes out ahead on the numbers. The catch: the only judged task showed enough order sensitivity that this result reads as a lean, not a rout.
Kimi K3 takes this head-to-head on the aggregate, **8.6 to 4.2**, and the statistical read backs that up with a **75% confidence lean**. That is enough to put it in front, but not enough to pretend this was a demolition. With only one scored task and no ties, the margin looks cleaner than the evidence really is.
On the actual prompt — *"A forgotten vending machine in..."* — Kimi K3 got the official task win because it more clearly assembled the requested scene: moonlit forest, readable vending machine, glowing fireflies, raccoons, and visible animated activity. The key advantage was legibility. It made the environment and motion readable instead of burying them in darkness.
But the order-swapped judge pass matters here, and it muddies any triumphalism. In that pass, **Grok 4.5** was preferred for stronger composition and richer lighting, while Kimi K3 was described as too dark and sparse. That kind of reversal is a warning sign: the matchup did not expose a stable, overwhelming quality gap so much as a narrow edge that depended on which rendering better surfaced the prompt details.
So the editorial verdict is straightforward: Kimi K3 was the better performer in this test, mostly because it was more successful at making the scene readable and complete. Grok 4.5 did not put up enough on the board to challenge the aggregate result, but the evidence is still thin and a bit noisy.
**Final call: Kimi K3 wins — deservedly, but only as a lean.**
A forgotten vending machine in
A forgotten vending machine in a moonlit forest dispensing glowing fireflies as curious raccoons gather around it.
Kimi K3: const TAU = Math.PI * 2;
function mulberry32(a){return function(){a|=0;a=a+0x6D2B79F5|0;var t=Math.imul(a^a>>>15,1|a);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296;};}
const rng = mulberry32(20260719);
const RR = (a,b)=>a+(b-a)*rng();
function glowTexture(){
const c=document.createElement('canvas');c.width=64;c.height=64;
const x=c.getContext('2d');
const g=x.createRadialGradient(32,32,0,32,32,32);
g.addColorStop(0,'rgba(255,255,255,1)');
g.addColorStop(0.3,'rgba(255,255,255,0.55)');
g.addColorStop(1,'rgba(255,255,255,0)');
x.fillStyle=g;x.fillRect(0,0,64,64);
return new THREE.CanvasTexture(c);
}
const glowTex = glowTexture();
scene.background = new THREE.Color(0x050a13);
scene.fog = new THREE.Fog(0x050a13, 9, 30);
scene.add(new THREE.HemisphereLight(0x33465e, 0x0a0f0c, 0.55));
scene.add(new THREE.AmbientLight(0x1a2433, 0.6));
const moonLight = new THREE.DirectionalLight(0xa9c6ff, 1.35);
moonLight.position.set(-5.5,6.5,-8);
scene.add(moonLight);
const fill = new THREE.PointLight(0x3d5a7a, 6, 0, 2);
fill.position.set(2.5,3.5,5);
scene.add(fill);
// Moon + halo
const moon = new THREE.Mesh(new THREE.SphereGeometry(1.05,32,24), new THREE.MeshBasicMaterial({color:0xeaf2ff, fog:false}));
moon.position.set(-5.4,6.3,-11);
scene.add(moon);
const moonGlow1 = new THREE.Sprite(new THREE.SpriteMaterial({map:glowTex,color:0x9db8e8,transparent:true,opacity:0.55,blending:THREE.AdditiveBlending,depthWrite:false,fog:false}));
moonGlow1.scale.set(7,7,1); moonGlow1.position.copy(moon.position); scene.add(moonGlow1);
const moonGlow2 = new THREE.Sprite(new THREE.SpriteMaterial({map:glowTex,color:0x7e97c4,transparent:true,opacity:0.16,blending:THREE.AdditiveBlending,depthWrite:false,fog:false}));
moonGlow2.scale.set(13,13,1); moonGlow2.position.copy(moon.position); scene.add(moonGlow2);
// Stars
const starGeo = new THREE.BufferGeometry();
const starPos = new Float32Array(160*3);
for(let i=0;i<160;i++){
const a=RR(0,TAU), e=RR(0.08,1.4), r=36;
starPos[i*3]=Math.cos(a)*Math.cos(e)*r;
starPos[i*3+1]=Math.sin(e)*r*0.6+2;
starPos[i*3+2]=Math.sin(a)*Math.cos(e)*r;
}
starGeo.setAttribute('position', new THREE.BufferAttribute(starPos,3));
const starMat = new THREE.PointsMaterial({color:0xcdd9ee,size:1.6,sizeAttenuation:false,transparent:true,opacity:0.8,fog:false});
scene.add(new THREE.Points(starGeo, starMat));
// Ground + moonlit patch
const ground = new THREE.Mesh(new THREE.CircleGeometry(34,48), new THREE.MeshStandardMaterial({color:0x101f16,roughness:1}));
ground.rotation.x=-Math.PI/2;
scene.add(ground);
const moonPatch = new THREE.Mesh(new THREE.CircleGeometry(4.5,32), new THREE.MeshBasicMaterial({color:0x28405a,transparent:true,opacity:0.2,blending:THREE.AdditiveBlending,depthWrite:false}));
moonPatch.rotation.x=-Math.PI/2; moonPatch.position.set(-1.6,0.015,-1.2);
scene.add(moonPatch);
// Forest ring
const trees=[];
const trunkMat=new THREE.MeshStandardMaterial({color:0x241b12,roughness:1});
const leafMats=[0x0d1f16,0x11261b,0x0a1a12].map(c=>new THREE.MeshStandardMaterial({color:c,roughness:1}));
let placed=0;
while(placed<16){
const a=RR(0,TAU), r=RR(6.5,14);
const x=Math.cos(a)*r, z=Math.sin(a)*r;
if(z>1.5 && Math.abs(x)<5) continue;
const h=RR(3,6.2);
const tree=new THREE.Group();
const trunk=new THREE.Mesh(new THREE.CylinderGeometry(0.09,0.16,h*0.5,7),trunkMat);
trunk.position.y=h*0.25; tree.add(trunk);
const lm=leafMats[placed%3];
for(let j=0;j<3;j++){
const cone=new THREE.Mesh(new THREE.ConeGeometry(h*0.22*(1-j*0.22),h*0.34,8),lm);
cone.position.y=h*(0.42+j*0.22); tree.add(cone);
}
tree.position.set(x,0,z);
tree.rotation.y=RR(0,TAU);
tree.userData.ph=RR(0,TAU);
scene.add(tree); trees.push(tree); placed++;
}
// Two dark framing trees behind machine
[[-3.1,-2.8,5.2],[3.4,-3.4,5.8]].forEach(([x,z,h])=>{
const t=new THREE.Group();
const tr=new THREE.Mesh(new THREE.CylinderGeometry(0.12,0.22,h*0.5,7),trunkMat);
tr.position.y=h*0.25; t.add(tr);
const lm=leafMats[2];
for(let j=0;j<3;j++){
const c=new THREE.Mesh(new THREE.ConeGeometry(h*0.2*(1-j*0.2),h*0.32,8),lm);
c.position.y=h*(0.45+j*0.2); t.add(c);
}
t.position.set(x,0,z); t.userData.ph=RR(0,TAU);
scene.add(t); trees.push(t);
});
// Grass tufts
const grassMat=new THREE.MeshStandardMaterial({color:0x1a3020,roughness:1});
for(let i=0;i<26;i++){
const a=RR(0,TAU), r=RR(1.3,5.5);
const gx=Math.cos(a)*r, gz=Math.sin(a)*r;
if(gz>3) continue;
const c=new THREE.Mesh(new THREE.ConeGeometry(RR(0.03,0.07),RR(0.15,0.4),5),grassMat);
c.position.set(gx,0.1,gz);
c.rotation.z=RR(-0.2,0.2);
scene.add(c);
}
// Glowing mushrooms
const mushStem=new THREE.MeshStandardMaterial({color:0xb9c4c9,roughness:0.8});
const mushCaps=[];
for(let i=0;i<5;i++){
const a=RR(0,TAU), r=RR(1.1,2.3);
const mx=Math.cos(a)*r, mz=Math.sin(a)*r*0.7+0.6;
const stem=new THREE.Mesh(new THREE.CylinderGeometry(0.025,0.035,0.12,6),mushStem);
stem.position.set(mx,0.06,mz); scene.add(stem);
const capMat=new THREE.MeshStandardMaterial({color:0x1c3a33,emissive:i%2?0x54ffd2:0x9fe870,emissiveIntensity:0.5,roughness:0.6});
const cap=new THREE.Mesh(new THREE.SphereGeometry(0.07,10,8,0,TAU,0,Math.PI/2),capMat);
cap.position.set(mx,0.12,mz); scene.add(cap);
mushCaps.push({m:capMat,ph:RR(0,TAU)});
}
// ---- Forgotten vending machine ----
const machine=new THREE.Group();
machine.rotation.set(0,-0.16,0.035);
scene.add(machine);
const machBody=new THREE.Mesh(new THREE.BoxGeometry(1.5,2.5,1.1), new THREE.MeshStandardMaterial({color:0x7d4438,roughness:0.75,metalness:0.3}));
machBody.position.y=1.25; machine.add(machBody);
const stripe=new THREE.Mesh(new THREE.BoxGeometry(1.52,0.18,1.12), new THREE.MeshStandardMaterial({color:0xcfd6cf,roughness:0.6,metalness:0.2}));
stripe.position.y=2.08; machine.add(stripe);
const panelMat=new THREE.MeshStandardMaterial({color:0x0a2028,emissive:0x6fc8ef,emissiveIntensity:0.5,roughness:0.35});
const panel=new THREE.Mesh(new THREE.PlaneGeometry(1.02,1.42),panelMat);
panel.position.set(-0.12,1.62,0.556); machine.add(panel);
const jarMats=[];
for(let r=0;r<3;r++)for(let c=0;c<4;c++){
const jm=new THREE.MeshStandardMaterial({color:0x0f1a12,emissive:new THREE.Color().setHSL(0.24+rng()*0.12,0.9,0.55),emissiveIntensity:0.8,roughness:0.5});
const jar=new THREE.Mesh(new THREE.CircleGeometry(0.075,12),jm);
jar.position.set(-0.47+c*0.24,1.98-r*0.36,0.561);
machine.add(jar);
jarMats.push({m:jm,ph:RR(0,TAU),k:1+Math.floor(RR(0,3))});
}
const btnMats=[];
for(let i=0;i<4;i++){
const bm=new THREE.MeshStandardMaterial({color:0x2a2118,emissive:0xffb35c,emissiveIntensity:0.7,roughness:0.5});
const b=new THREE.Mesh(new THREE.BoxGeometry(0.09,0.09,0.05),bm);
b.position.set(0.52,1.95-i*0.22,0.57);
machine.add(b); btnMats.push(bm);
}
const slotFrame=new THREE.Mesh(new THREE.BoxGeometry(0.86,0.4,0.08), new THREE.MeshStandardMaterial({color:0x3a2a22,roughness:0.8,metalness:0.3}));
slotFrame.position.set(0,0.55,0.56); machine.add(slotFrame);
const slotGlowMat=new THREE.MeshStandardMaterial({color:0x0a0f08,emissive:0xa8ff70,emissiveIntensity:0.4,roughness:0.7});
const slotGlow=new THREE.Mesh(new THREE.PlaneGeometry(0.7,0.26),slotGlowMat);
slotGlow.position.set(0,0.55,0.605); machine.add(slotGlow);
const signMat=new THREE.MeshStandardMaterial({color:0x081418,emissive:0x58e0d8,emissiveIntensity:0.6,roughness:0.4});
const sign=new THREE.Mesh(new THREE.PlaneGeometry(1.2,0.3),signMat);
sign.position.set(0,2.34,0.556); machine.add(sign);
const mossMat=new THREE.MeshStandardMaterial({color:0x2c4a24,roughness:1});
for(let i=0;i<6;i++){
const m=new THREE.Mesh(new THREE.SphereGeometry(RR(0.08,0.18),8,6),mossMat);
m.scale.y=0.45; m.position.set(RR(-0.65,0.65),2.5,RR(-0.45,0.45));
machine.add(m);
}
for(let i=0;i<3;i++){
const m=new THREE.Mesh(new THREE.SphereGeometry(RR(0.06,0.12),8,6),mossMat);
m.scale.y=0.4; m.position.set(0.76,RR(0.4,1.8),RR(-0.3,0.3));
machine.add(m);
}
// Machine lights
const machLight=new THREE.PointLight(0x8fdcff,9,9,2);
machLight.position.set(0,1.6,1.3);
scene.add(machLight);
machine.updateMatrixWorld(true);
const slotWorld=new THREE.Vector3(0,0.55,0.62);
machine.localToWorld(slotWorld);
const slotLight=new THREE.PointLight(0xb6ff7a,0,4,2);
slotLight.position.copy(slotWorld).add(new THREE.Vector3(0,0,0.25));
scene.add(slotLight);
const flyLight=new THREE.PointLight(0xa8ff70,3,7,2);
scene.add(flyLight);
// ---- Raccoons ----
function buildRaccoon(){
const fur=new THREE.MeshStandardMaterial({color:0x868c96,roughness:0.95});
const dark=new THREE.MeshStandardMaterial({color:0x26292e,roughness:0.9});
const lite=new THREE.MeshStandardMaterial({color:0xd6d9dd,roughness:0.9});
const g=new THREE.Group();
const body=new THREE.Mesh(new THREE.SphereGeometry(0.5,20,16),fur);
body.scale.set(1,0.82,1.25); body.position.set(0,0.42,0);
g.add(body);
const chest=new THREE.Mesh(new THREE.SphereGeometry(0.34,16,12),lite);
chest.scale.set(0.85,0.75,0.9); chest.position.set(0,0.38,0.32);
g.add(chest);
const headG=new THREE.Group(); headG.position.set(0,0.84,0.42);
headG.add(new THREE.Mesh(new THREE.SphereGeometry(0.3,20,16),fur));
const mask=new THREE.Mesh(new THREE.SphereGeometry(0.302,20,16),dark);
mask.scale.set(1.02,0.6,1.02); mask.position.set(0,0.02,0.05);
headG.add(mask);
for(const s of[-1,1]){
const ear=new THREE.Mesh(new THREE.ConeGeometry(0.1,0.17,10),dark);
ear.position.set(0.18*s,0.27,-0.02); ear.rotation.z=-0.3*s;
headG.add(ear);
const eye=new THREE.Mesh(new THREE.SphereGeometry(0.042,10,8),new THREE.MeshStandardMaterial({color:0x101010,emissive:0xffdf9e,emissiveIntensity:0.9,roughness:0.3}));
eye.position.set(0.11*s,0.05,0.30);
headG.add(eye);
}
const snout=new THREE.Mesh(new THREE.SphereGeometry(0.13,12,10),lite);
snout.scale.set(1,0.78,1); snout.position.set(0,-0.1,0.25);
headG.add(snout);
const nose=new THREE.Mesh(new THREE.SphereGeometry(0.045,8,8),dark);
nose.position.set(0,-0.06,0.36);
headG.add(nose);
g.add(headG);
for(const s of[-1,1]){
const h=new THREE.Mesh(new THREE.SphereGeometry(0.23,14,10),fur);
h.scale.set(0.95,1,1.15); h.position.set(0.3*s,0.25,-0.12);
g.add(h);
}
const pawPivots=[];
for(const s of[-1,1]){
const pv=new THREE.Group(); pv.position.set(0.19*s,0.55,0.35);
const paw=new THREE.Mesh(new THREE.CylinderGeometry(0.06,0.075,0.42,8),fur);
paw.position.y=-0.18; pv.add(paw);
const tip=new THREE.Mesh(new THREE.SphereGeometry(0.07,8,8),dark);
tip.position.y=-0.4; pv.add(tip);
pv.rotation.x=0.25;
g.add(pv); pawPivots.push(pv);
}
const tailG=new THREE.Group(); tailG.position.set(0,0.42,-0.58);
let pivot=tailG;
for(let i=0;i<6;i++){
const p=new THREE.Group();
p.position.set(0,0,i===0?0:-0.15);
const seg=new THREE.Mesh(new THREE.SphereGeometry(0.15-i*0.013,10,8),i%2?dark:fur);
seg.position.z=-0.08;
p.add(seg);
p.rotation.x=0.42;
pivot.add(p); pivot=p;
}
g.add(tailG);
return {g,headG,tailG,pawPivots,body};
}
const rA=buildRaccoon();
rA.g.position.set(1.5,0,1.45);
rA.g.rotation.y=Math.atan2(-1.5,0.3-1.45);
scene.add(rA.g);
const rB=buildRaccoon();
rB.g.position.set(-1.5,0,0.9);
rB.g.rotation.y=Math.atan2(1.5,0.3-0.9);
rB.g.rotation.x=-0.52;
scene.add(rB.g);
const rC=buildRaccoon();
rC.g.position.set(0.35,0,2.5);
rC.g.rotation.y=Math.atan2(-0.35,0.3-2.5);
scene.add(rC.g);
// ---- Fireflies ----
const flies=[];
const flyCols=[0xcfff6a,0xa8ff8a,0xfff29a];
for(let i=0;i<52;i++){
const mat=new THREE.SpriteMaterial({map:glowTex,color:flyCols[i%3],transparent:true,opacity:0.8,blending:THREE.AdditiveBlending,depthWrite:false,fog:false});
const s=new THREE.Sprite(mat);
scene.add(s);
flies.push({
s,mat,
cx:RR(-2.4,2.4),cy:RR(0.5,3.0),cz:RR(-0.8,2.8),
rx:RR(0.3,1.2),ry:RR(0.15,0.6),rz:RR(0.3,1.1),
k1:1+Math.floor(RR(0,3)),k2:1+Math.floor(RR(0,3)),k3:1+Math.floor(RR(0,3)),
p1:RR(0,TAU),p2:RR(0,TAU),p3:RR(0,TAU),
kb:2+Math.floor(RR(0,4)),pb:RR(0,TAU),bs:RR(0.09,0.2)
});
}
// Newly dispensed fireflies escaping the slot
const specials=[];
for(let i=0;i<3;i++){
const mat=new THREE.SpriteMaterial({map:glowTex,color:0xffe58a,transparent:true,opacity:0,blending:THREE.AdditiveBlending,depthWrite:false,fog:false});
const s=new THREE.Sprite(mat);
scene.add(s);
specials.push({s,mat,off:i/3});
}
// Ground mist
const mists=[];
for(let i=0;i<5;i++){
const mat=new THREE.SpriteMaterial({map:glowTex,color:0x8fa5c8,transparent:true,opacity:0.07,depthWrite:false});
const s=new THREE.Sprite(mat);
s.scale.set(RR(6,10),RR(2,3.2),1);
const bx=RR(-4,4);
s.position.set(bx,RR(0.4,1.0),RR(-3,3));
scene.add(s);
mists.push({s,bx,ph:RR(0,TAU),k:1+Math.floor(RR(0,2))});
}
// Firefly glow pooling on the ground
const flyPatch=new THREE.Mesh(new THREE.CircleGeometry(2.4,24), new THREE.MeshBasicMaterial({color:0x9fff70,transparent:true,opacity:0.05,blending:THREE.AdditiveBlending,depthWrite:false}));
flyPatch.rotation.x=-Math.PI/2; flyPatch.position.set(0,0.02,1.1);
scene.add(flyPatch);
camera.fov=40;
camera.updateProjectionMatrix();
__update = (t) => {
const u=t/DURATION, th=u*TAU;
// Dispensed fireflies (computed first: drives slot glow + machine jiggle)
let disp=0;
for(const sp of specials){
const ph=(u+sp.off)%1;
const op=Math.sin(ph*Math.PI);
sp.mat.opacity=op*0.95;
const sc=0.14+0.18*op;
sp.s.scale.set(sc,sc,1);
sp.s.position.set(
slotWorld.x+0.28*Math.sin(ph*TAU*2+sp.off*9),
slotWorld.y+ph*1.8,
slotWorld.z+0.1+ph*1.5+0.25*Math.sin(ph*TAU+sp.off*5)
);
disp=Math.max(disp,op);
}
slotGlowMat.emissiveIntensity=0.35+1.6*disp;
slotLight.intensity=5*disp;
machine.rotation.z=0.035+0.004*Math.sin(40*th)*disp;
// Camera drift
camera.position.set(0.75*Math.sin(th), 1.95+0.18*Math.sin(2*th+1.3), 5.7+0.35*Math.cos(th));
camera.lookAt(0,1.2,0.2);
// Machine flicker
const fl=0.5+0.14*Math.sin(6*th)+0.08*Math.sin(13*th+1.7);
panelMat.emissiveIntensity=fl;
signMat.emissiveIntensity=(0.5+0.25*Math.sin(7*th+2))*(Math.sin(11*th)>0.88?0.15:1);
machLight.intensity=7+3*fl+1.2*Math.sin(13*th+1.7);
for(const j of jarMats) j.m.emissiveIntensity=0.55+0.45*Math.sin(j.k*th+j.ph);
btnMats.forEach((b,i)=>{b.emissiveIntensity=0.4+0.5*Math.max(0,Math.sin(3*th+i*1.3));});
for(const mc of mushCaps) mc.m.emissiveIntensity=0.35+0.25*Math.sin(2*th+mc.ph);
// Firefly swarm
let fx=0,fy=0,fz=0;
for(const f of flies){
const b=0.5+0.5*Math.sin(f.kb*th+f.pb);
f.mat.opacity=0.2+0.8*b;
const sc=f.bs*(0.65+0.7*b);
f.s.scale.set(sc,sc,1);
const x=f.cx+f.rx*Math.sin(f.k1*th+f.p1);
const y=f.cy+f.ry*Math.sin(f.k2*th+f.p2);
const z=f.cz+f.rz*Math.cos(f.k3*th+f.p3);
f.s.position.set(x,y,z);
fx+=x;fy+=y;fz+=z;
}
flyLight.position.set(fx/flies.length,fy/flies.length,fz/flies.length);
flyLight.intensity=2.2+1.2*Math.sin(2*th);
flyPatch.material.opacity=0.04+0.035*(0.5+0.5*Math.sin(2*th));
// Environment life
for(const tr of trees){tr.rotation.z=0.016*Math.sin(th+tr.userData.ph);tr.rotation.x=0.01*Math.cos(th+tr.userData.ph);}
for(const m of mists){m.s.position.x=m.bx+0.8*Math.sin(m.k*th+m.ph);m.s.material.opacity=0.05+0.03*Math.sin(th+m.ph);}
starMat.opacity=0.65+0.25*Math.sin(2*th+0.7);
moonGlow1.material.opacity=0.5+0.08*Math.sin(2*th);
// Raccoon A: sitting, curious head tilts, tail wag
rA.headG.rotation.z=0.22*Math.sin(th+0.4);
rA.headG.rotation.y=0.35*Math.sin(2*th+1.1);
rA.tailG.rotation.y=0.45*Math.sin(2*th);
rA.body.scale.y=0.82*(1+0.035*Math.sin(2*th+2));
// Raccoon B: reared up, pawing at the machine
rB.headG.rotation.y=0.25*Math.sin(th+2);
rB.headG.rotation.z=0.12*Math.sin(2*th+0.7);
rB.pawPivots[1].rotation.x=-1.7+0.45*Math.sin(3*th);
rB.pawPivots[0].rotation.x=-0.6+0.2*Math.sin(3*th+Math.PI);
rB.tailG.rotation.y=0.35*Math.sin(2*th+1);
rB.g.rotation.x=-0.52+0.05*Math.sin(3*th+0.5);
// Raccoon C: excitable little hops up front
rC.g.position.y=0.08*Math.max(0,Math.sin(3*th+1));
rC.headG.rotation.z=0.3*Math.sin(2*th+2.5);
rC.headG.rotation.x=0.15*Math.sin(3*th);
rC.tailG.rotation.y=0.5*Math.sin(3*th+2);
rC.pawPivots[0].rotation.x=0.25+0.3*Math.sin(3*th+1);
};
xAI: Grok 4.5: const hemi = new THREE.HemisphereLight(0xaabbee, 0x112211, 0.35);
scene.add(hemi);
const sun = new THREE.DirectionalLight(0xccddee, 0.85);
sun.position.set(5, 11, -7);
scene.add(sun);
const rim = new THREE.DirectionalLight(0x445566, 0.35);
rim.position.set(-7, 4, 6);
scene.add(rim);
const moonGeo = new THREE.SphereGeometry(0.85, 18, 12);
const moonMat = new THREE.MeshBasicMaterial({ color: 0xddddff });
const moon = new THREE.Mesh(moonGeo, moonMat);
moon.position.set(-4.8, 8.2, -6.5);
scene.add(moon);
const groundGeo = new THREE.PlaneGeometry(17, 17, 24, 24);
const groundMat = new THREE.MeshLambertMaterial({ color: 0x0b1a0b, flatShading: true });
const ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -0.02;
const gpos = ground.geometry.attributes.position;
for (let i = 0; i < gpos.count; i++) {
const vx = gpos.getX(i);
const vz = gpos.getZ(i);
const h = Math.sin(vx * 0.75) * 0.07 + Math.cos(vz * 0.55) * 0.055 + Math.sin((vx + vz) * 1.1) * 0.035;
gpos.setY(i, h);
}
ground.geometry.computeVertexNormals();
scene.add(ground);
scene.fog = new THREE.Fog(0x0a160f, 7.5, 20);
function createTree(x, z, s, r) {
const grp = new THREE.Group();
grp.position.set(x, 0, z);
grp.rotation.y = r;
const trunkH = 2.65 * s;
const trunk = new THREE.Mesh(
new THREE.CylinderGeometry(0.13 * s, 0.17 * s, trunkH, 5),
new THREE.MeshLambertMaterial({ color: 0x2a2119, flatShading: true })
);
trunk.position.y = trunkH * 0.5;
grp.add(trunk);
const folMat = new THREE.MeshLambertMaterial({ color: 0x0a2a0a, flatShading: true });
const folMat2 = new THREE.MeshLambertMaterial({ color: 0x132a13, flatShading: true });
const layers = [
{ y: 1.85 * s, rad: 1.28 * s, h: 1.95 * s },
{ y: 3.15 * s, rad: 1.05 * s, h: 1.55 * s },
{ y: 4.25 * s, rad: 0.82 * s, h: 1.25 * s },
{ y: 5.15 * s, rad: 0.52 * s, h: 0.95 * s }
];
layers.forEach((l, idx) => {
const c = new THREE.Mesh(
new THREE.ConeGeometry(l.rad, l.h, 6),
idx % 2 === 0 ? folMat : folMat2
);
c.position.set(Math.sin(idx) * 0.08 * s, l.y + l.h * 0.5, Math.cos(idx * 1.2) * 0.07 * s);
grp.add(c);
});
return grp;
}
const treeData = [
[-6.8, -5.8, 0.92, 0.3], [-4.1, -7.3, 1.08, -0.6], [-1.3, -6.9, 0.82, 1.1],
[2.0, -7.4, 0.98, -1.7], [4.8, -5.6, 0.88, 0.65], [6.5, -3.8, 0.72, -0.35],
[-7.2, -2.2, 0.68, 2.0], [5.3, -2.4, 0.78, -2.3], [-3.2, -4.2, 0.58, 0.45]
];
treeData.forEach(p => scene.add(createTree(p[0], p[2], p[1], p[3])));
const vend = new THREE.Group();
vend.position.set(0, 0, 0);
scene.add(vend);
const cab = new THREE.Mesh(
new THREE.BoxGeometry(1.32, 2.12, 0.82),
new THREE.MeshPhongMaterial({ color: 0x3f4a3f, shininess: 9, specular: 0x222222 })
);
cab.position.y = 1.06;
vend.add(cab);
const glass = new THREE.Mesh(
new THREE.BoxGeometry(1.12, 1.38, 0.04),
new THREE.MeshPhongMaterial({ color: 0x1a2a3a, shininess: 22, specular: 0x555555, transparent: true, opacity: 0.72 })
);
glass.position.set(0, 1.32, 0.44);
vend.add(glass);
const btnBack = new THREE.Mesh(
new THREE.BoxGeometry(0.24, 1.08, 0.07),
new THREE.MeshLambertMaterial({ color: 0x252525 })
);
btnBack.position.set(0.54, 1.22, 0.46);
vend.add(btnBack);
let buttons = [];
const btnCols = [0x7a3535, 0x356a85, 0x458545, 0x856a35, 0x553585, 0x358575];
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 2; col++) {
const b = new THREE.Mesh(
new THREE.BoxGeometry(0.115, 0.115, 0.055),
new THREE.MeshPhongMaterial({ color: btnCols[(row * 2 + col) % 6], emissive: 0x000000, shininess: 6 })
);
b.position.set(0.47 + col * 0.17, 1.52 - row * 0.27, 0.505);
vend.add(b);
buttons.push(b);
}
}
const coin = new THREE.Mesh(
new THREE.BoxGeometry(0.17, 0.055, 0.09),
new THREE.MeshLambertMaterial({ color: 0x1f1f1f })
);
coin.position.set(-0.46, 1.82, 0.48);
vend.add(coin);
const slotBox = new THREE.Mesh(
new THREE.BoxGeometry(0.68, 0.24, 0.14),
new THREE.MeshLambertMaterial({ color: 0x181818 })
);
slotBox.position.set(0, 0.36, 0.49);
vend.add(slotBox);
let vendFlap;
const flapPivot = new THREE.Group();
flapPivot.position.set(0, 0.40, 0.58);
const flapMesh = new THREE.Mesh(
new THREE.PlaneGeometry(0.54, 0.17),
new THREE.MeshLambertMaterial({ color: 0x353535, side: THREE.DoubleSide })
);
flapMesh.position.y = -0.085;
flapPivot.add(flapMesh);
vend.add(flapPivot);
vendFlap = flapPivot;
function createRaccoon() {
const g = new THREE.Group();
const bodyMat = new THREE.MeshLambertMaterial({ color: 0x484848, flatShading: true });
const body = new THREE.Mesh(new THREE.SphereGeometry(0.41, 10, 8), bodyMat);
body.scale.set(1.12, 0.64, 1.22);
body.position.y = 0.47;
body.name = 'body';
g.add(body);
const head = new THREE.Mesh(new THREE.SphereGeometry(0.27, 9, 7), new THREE.MeshLambertMaterial({ color: 0x555555, flatShading: true }));
head.position.set(0, 0.71, 0.56);
head.name = 'head';
g.add(head);
const earMat = new THREE.MeshLambertMaterial({ color: 0x2f2f2f });
const earL = new THREE.Mesh(new THREE.ConeGeometry(0.095, 0.21, 4), earMat);
earL.position.set(-0.17, 0.93, 0.50);
earL.rotation.set(0.55, 0, -0.48);
earL.name = 'earL';
g.add(earL);
const earR = earL.clone();
earR.position.x = 0.17;
earR.rotation.z = 0.48;
earR.name = 'earR';
g.add(earR);
const snout = new THREE.Mesh(new THREE.SphereGeometry(0.115, 5, 4), new THREE.MeshLambertMaterial({ color: 0x222222 }));
snout.position.set(0, 0.60, 0.80);
snout.scale.set(1, 0.78, 1.25);
snout.name = 'snout';
g.add(snout);
const mask = new THREE.Mesh(new THREE.BoxGeometry(0.46, 0.13, 0.30), new THREE.MeshLambertMaterial({ color: 0x0a0a0a }));
mask.position.set(0, 0.72, 0.60);
mask.name = 'mask';
g.add(mask);
const eyeMat = new THREE.MeshLambertMaterial({ color: 0x111111 });
const eyeL = new THREE.Mesh(new THREE.SphereGeometry(0.042, 5, 4), eyeMat);
eyeL.position.set(-0.125, 0.72, 0.76);
g.add(eyeL);
const eyeR = eyeL.clone();
eyeR.position.x = 0.125;
g.add(eyeR);
const tail = new THREE.Group();
tail.position.set(0, 0.44, -0.52);
tail.name = 'tail';
const ringCols = [0x282828, 0x626262, 0x282828, 0x626262, 0x282828];
let tz = 0;
for (let i = 0; i < 5; i++) {
const rr = 0.092 - i * 0.007;
const seg = new THREE.Mesh(
new THREE.CylinderGeometry(rr, rr * 0.82, 0.30, 5),
new THREE.MeshLambertMaterial({ color: ringCols[i] })
);
seg.rotation.x = Math.PI / 2;
seg.position.z = tz - 0.15;
tail.add(seg);
tz -= 0.26;
}
g.add(tail);
const legMat = new THREE.MeshLambertMaterial({ color: 0x2f2f2f, flatShading: true });
const legGeo = new THREE.CylinderGeometry(0.052, 0.038, 0.36, 4);
const legFL = new THREE.Mesh(legGeo, legMat);
legFL.position.set(-0.21, 0.21, 0.26);
legFL.rotation.set(0.22, 0, 0.12);
legFL.name = 'legFL';
g.add(legFL);
const legFR = new THREE.Mesh(legGeo, legMat);
legFR.position.set(0.21, 0.21, 0.26);
legFR.rotation.set(0.22, 0, -0.12);
legFR.name = 'legFR';
g.add(legFR);
const legBL = new THREE.Mesh(legGeo, legMat);
legBL.position.set(-0.21, 0.21, -0.33);
legBL.rotation.set(-0.08, 0, 0.08);
legBL.name = 'legBL';
g.add(legBL);
const legBR = new THREE.Mesh(legGeo, legMat);
legBR.position.set(0.21, 0.21, -0.33);
legBR.rotation.set(-0.08, 0, -0.08);
legBR.name = 'legBR';
g.add(legBR);
return g;
}
const raccoonData = [];
const racTemplate = createRaccoon();
const rac1 = racTemplate.clone();
rac1.position.set(-1.55, 0, 1.35);
rac1.rotation.y = 0.85;
scene.add(rac1);
raccoonData.push({ group: rac1, phase: 0 });
const rac2 = racTemplate.clone();
rac2.position.set(0.25, 0, 2.05);
rac2.rotation.y = -0.08;
scene.add(rac2);
raccoonData.push({ group: rac2, phase: 1.7 });
const legFR2 = rac2.getObjectByName('legFR');
if (legFR2) legFR2.rotation.x = 0.85;
const rac3 = racTemplate.clone();
rac3.position.set(1.65, 0, 1.55);
rac3.rotation.y = -1.05;
scene.add(rac3);
raccoonData.push({ group: rac3, phase: 3.5 });
const fireflies = [];
const ffCoreMat = new THREE.MeshPhongMaterial({ color: 0x99ff66, emissive: 0x55cc22, shininess: 35, transparent: true, opacity: 0.92 });
const ffHaloMat = new THREE.MeshBasicMaterial({ color: 0xaaff77, transparent: true, opacity: 0.22 });
for (let i = 0; i < 6; i++) {
const ff = new THREE.Group();
const core = new THREE.Mesh(new THREE.SphereGeometry(0.055, 6, 5), ffCoreMat);
ff.add(core);
const halo = new THREE.Mesh(new THREE.SphereGeometry(0.12, 6, 5), ffHaloMat);
ff.add(halo);
const lgt = new THREE.PointLight(0xaaff66, 0.32, 2.8);
ff.add(lgt);
ff.userData = { phase: i * 0.92 + 0.3, spd: 0.82 + (i % 3) * 0.09 };
scene.add(ff);
fireflies.push(ff);
}
__update = (t) => {
const norm = t / DURATION;
const camR = 5.7;
const camA = 2 * Math.PI * norm * 0.14 + 0.75;
camera.position.x = Math.sin(camA) * camR + 1.2;
camera.position.z = Math.cos(camA) * camR * 0.72 + 2.3;
camera.position.y = 2.15 + Math.sin(2 * Math.PI * norm * 0.6) * 0.12;
camera.lookAt(0.15, 0.95, 0.25);
if (vendFlap) {
const flapAng = (Math.sin(2 * Math.PI * t / 2.8) * 0.55 + 0.08) * (Math.PI * 0.55);
vendFlap.rotation.x = flapAng;
}
if (buttons && buttons.length) {
const act = Math.floor((t * 1.6) % buttons.length);
buttons.forEach((b, i) => {
if (i === act) {
b.material.emissive.setHex(0xffaa22);
} else {
b.material.emissive.setHex(0x000000);
}
});
}
raccoonData.forEach((d, idx) => {
const rac = d.group;
const ph = d.phase;
const lt = t + ph;
const body = rac.getObjectByName('body');
if (body) {
const br = Math.sin(2 * Math.PI * lt / 2.1) * 0.014;
body.position.y = 0.47 + br;
body.scale.y = 0.64 * (1 + br * 1.8);
}
const head = rac.getObjectByName('head');
if (head) {
head.rotation.y = Math.sin(2 * Math.PI * lt / 4.2 + idx * 0.6) * 0.38;
head.rotation.x = Math.sin(2 * Math.PI * lt / 5.8) * 0.09;
}
const tail = rac.getObjectByName('tail');
if (tail) {
tail.rotation.y = Math.sin(2 * Math.PI * lt / 1.55 + ph) * 0.65;
tail.rotation.x = Math.sin(2 * Math.PI * lt / 3.1) * 0.18;
}
if (idx === 1) {
const lfr = rac.getObjectByName('legFR');
if (lfr) {
const paw = Math.max(0, Math.sin(2 * Math.PI * lt / 2.6)) * 0.55;
lfr.rotation.x = 0.85 + paw * 0.35;
}
}
});
fireflies.forEach((ff, i) => {
const ud = ff.userData;
const ph = ud.phase || (i * 1.1);
const spd = ud.spd || 1;
const lt = (t * spd + ph) % DURATION;
const p = lt / DURATION;
const cx = Math.sin(p * Math.PI * 2 * 0.55 + i * 1.1) * 0.75;
const cz = Math.cos(p * Math.PI * 2 * 0.55 + i * 0.7) * 0.85 - 0.25;
const cy = 1.15 + Math.sin(p * Math.PI * 3.8) * 0.38;
let x = cx + Math.sin(p * Math.PI * 2 * 1.65 + i * 2.2) * 0.58 + Math.cos(p * Math.PI * 2.9) * 0.22;
let y = cy + Math.sin(p * Math.PI * 2 * 2.4 + ph * 1.3) * 0.22;
let z = cz + Math.cos(p * Math.PI * 2 * 1.85 + i) * 0.52 + Math.sin(p * Math.PI * 4.1) * 0.18;
const appr = Math.pow(Math.sin(p * Math.PI * 2 * 0.48 + i * 0.4) * 0.5 + 0.5, 1.6);
if (appr > 0.58) {
const m = (appr - 0.58) / 0.42;
const sx = 0.0, sy = 0.37, sz = 0.60;
x = x * (1 - m) + sx * m;
y = y * (1 - m) + (sy + 0.08) * m;
z = z * (1 - m) + sz * m;
}
x += Math.sin(p * 13.2 + i) * 0.028;
z += Math.cos(p * 10.8 + i * 1.6) * 0.028;
ff.position.set(x, y, z);
const pulse = Math.sin(p * Math.PI * 2 * 3.6 + ph * 1.7) * 0.5 + 0.5;
const core = ff.children[0];
if (core) {
core.scale.setScalar(0.055 * (0.72 + pulse * 0.55));
if (core.material.opacity !== undefined) core.material.opacity = 0.72 + pulse * 0.28;
}
const halo = ff.children[1];
if (halo) {
halo.scale.setScalar(0.12 * (0.75 + pulse * 1.15));
if (halo.material.opacity !== undefined) halo.material.opacity = 0.14 + pulse * 0.18;
}
const lgt = ff.children.find(c => c.isPointLight);
if (lgt) lgt.intensity = 0.22 + pulse * 0.38;
});
};
Model A clearly delivers the moonlit forest setting, readable vending machine, glowing fireflies, and raccoons with appealing composition and visible animated activity. Model B includes the core objects but is so underlit and sparse that the forest, fireflies, and motion are barely legible, reducing both thematic clarity and polish. (Order-swapped judge pass: Model B clearly delivers the moonlit forest setting, readable vending machine, glowing fireflies, and raccoons with stronger composition and richer lighting. Model A matches parts of the prompt but is extremely dark and sparse, making the scene and motion harder to read despite having raccoon-like figures around a glowing machine.)