GLM 5.3: A Great Model, With a Possible Dealbreaker
Z.ai has finally released GLM 5.3, an incredible model accessible on ZCode. We test its SVG origami crane, procedural 3D globe, wizard floating isles game, and neon runner code generations.
Mohid Mirza
Co-Founder & Lead Programmer of AcceleratedLogic AI
Crane:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Glass Sphere with Origami Crane</title>
<style>
html,body{margin:0;height:100%;display:flex;align-items:center;justify-content:center;background:radial-gradient(ellipse at 50% 35%,#3a4a5f 0%,#1a2230 55%,#0c1018 100%);}
</style>
</head>
<body>
<svg width="800" height="800" viewBox="0 0 800 800" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- Glass body -->
<radialGradient id="glass" cx="38%" cy="32%" r="75%">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.35"/>
<stop offset="55%" stop-color="#bcd8ee" stop-opacity="0.16"/>
<stop offset="85%" stop-color="#7aa8cc" stop-opacity="0.28"/>
<stop offset="100%" stop-color="#e8f6ff" stop-opacity="0.65"/>
</radialGradient>
<radialGradient id="innerShadow" cx="50%" cy="50%" r="50%">
<stop offset="80%" stop-color="#000" stop-opacity="0"/>
<stop offset="100%" stop-color="#0a2035" stop-opacity="0.55"/>
</radialGradient>
<linearGradient id="rim" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.9"/>
<stop offset="40%" stop-color="#9cc4e0" stop-opacity="0.15"/>
<stop offset="75%" stop-color="#ffffff" stop-opacity="0.55"/>
<stop offset="100%" stop-color="#6d94b8" stop-opacity="0.3"/>
</linearGradient>
<linearGradient id="specular" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.95"/>
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
</linearGradient>
<!-- Origami paper folds -->
<linearGradient id="fold1" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#ff9db8"/><stop offset="100%" stop-color="#d9557f"/>
</linearGradient>
<linearGradient id="fold2" x1="1" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#ffc2d4"/><stop offset="100%" stop-color="#e8749a"/>
</linearGradient>
<linearGradient id="fold3" x1="0" y1="1" x2="1" y2="0">
<stop offset="0%" stop-color="#f77fa5"/><stop offset="100%" stop-color="#c34a72"/>
</linearGradient>
<linearGradient id="fold4" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#ffd3e0"/><stop offset="100%" stop-color="#ea87a6"/>
</linearGradient>
<filter id="softShadow" x="-40%" y="-40%" width="180%" height="180%">
<feDropShadow dx="0" dy="14" stdDeviation="18" flood-color="#04101d" flood-opacity="0.6"/>
</filter>
<filter id="craneShadow" x="-40%" y="-40%" width="180%" height="180%">
<feDropShadow dx="-8" dy="10" stdDeviation="6" flood-color="#2a0f1c" flood-opacity="0.45"/>
</filter>
<clipPath id="sphereClip"><circle cx="400" cy="400" r="290"/></clipPath>
<!-- Caustic light patch under the crane -->
<radialGradient id="caustic" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#fff0f5" stop-opacity="0.55"/>
<stop offset="100%" stop-color="#fff0f5" stop-opacity="0"/>
</radialGradient>
<radialGradient id="floorGlow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#8fc4ee" stop-opacity="0.35"/>
<stop offset="100%" stop-color="#8fc4ee" stop-opacity="0"/>
</radialGradient>
</defs>
<!-- Ground shadow -->
<ellipse cx="400" cy="715" rx="230" ry="42" fill="#020810" opacity="0.7" filter="url(#softShadow)"/>
<ellipse cx="400" cy="705" rx="150" ry="24" fill="url(#floorGlow)"/>
<!-- Glass sphere base -->
<circle cx="400" cy="400" r="290" fill="url(#glass)" filter="url(#softShadow)"/>
<!-- Interior: refraction environment -->
<g clip-path="url(#sphereClip)">
<!-- refracted light band -->
<ellipse cx="300" cy="220" rx="180" ry="90" fill="#dff2ff" opacity="0.25" transform="rotate(-25 300 220)"/>
<ellipse cx="520" cy="600" rx="200" ry="80" fill="#aee0ff" opacity="0.18" transform="rotate(20 520 600)"/>
<!-- caustic from crane -->
<ellipse cx="430" cy="590" rx="130" ry="45" fill="url(#caustic)" transform="rotate(-8 430 590)"/>
<!-- ===== ORIGAMI CRANE ===== -->
<g filter="url(#craneShadow)" transform="translate(400,395) rotate(-6) scale(1.05)">
<!-- tail feathers -->
<path d="M0,0 L175,-95 L60,-18 Z" fill="url(#fold1)" stroke="#a63d63" stroke-width="1.2"/>
<path d="M0,0 L170,-55 L55,-8 Z" fill="url(#fold2)" stroke="#a63d63" stroke-width="0.8" opacity="0.9"/>
<!-- back wing (raised) -->
<path d="M-5,-15 L-70,-150 L-125,-185 L-60,-95 L-10,-25 Z" fill="url(#fold3)" stroke="#9c3a60" stroke-width="1.4"/>
<path d="M-8,-18 L-78,-120 L-115,-170" fill="none" stroke="#8d2f54" stroke-width="1" opacity="0.7"/>
<!-- body -->
<path d="M10,10 L-15,-10 L-60,15 L-20,32 L25,25 Z" fill="url(#fold1)" stroke="#a63d63" stroke-width="1.3"/>
<!-- neck -->
<path d="M20,15 L95,-60 L112,-118 L100,-58 L38,28 Z" fill="url(#fold2)" stroke="#a63d63" stroke-width="1.2"/>
<!-- head + beak -->
<path d="M108,-122 q14,-8 12,4 q-2,10 -14,10 Z" fill="#d9557f" stroke="#a63d63" stroke-width="1"/>
<path d="M118,-118 L152,-112 L119,-108 Z" fill="#f2b23f" stroke="#b57a17" stroke-width="0.8"/>
<circle cx="110" cy="-116" r="2.4" fill="#3a1020"/>
<!-- front wing (raised, nearer viewer) -->
<path d="M5,-8 L55,-145 L95,-195 L45,-90 L12,-15 Z" fill="url(#fold4)" stroke="#a63d63" stroke-width="1.4"/>
<path d="M8,-10 L60,-120 L90,-185" fill="none" stroke="#c95e85" stroke-width="1" opacity="0.7"/>
<!-- fold creases on body -->
<path d="M10,10 L-20,-2 M-15,-10 L-20,32" fill="none" stroke="#a63d63" stroke-width="0.7" opacity="0.6"/>
<!-- inner glass reflection sweeping over the crane -->
<path d="M-140,-200 Q0,-260 140,-180 L60,180 Q0,220 -60,180 Z" fill="#eaf7ff" opacity="0.10"/>
</g>
</g>
<!-- Inner rim shadow for depth -->
<circle cx="400" cy="400" r="290" fill="url(#innerShadow)"/>
<!-- Outer rim / edge highlight -->
<circle cx="400" cy="400" r="290" fill="none" stroke="url(#rim)" stroke-width="5"/>
<circle cx="400" cy="400" r="286" fill="none" stroke="#ffffff" stroke-width="1.2" opacity="0.35"/>
<!-- Specular highlights -->
<ellipse cx="300" cy="215" rx="95" ry="55" fill="url(#specular)" transform="rotate(-32 300 215)"/>
<ellipse cx="270" cy="190" rx="45" ry="22" fill="#ffffff" opacity="0.85" transform="rotate(-32 270 190)"/>
<!-- refracted bright crescent bottom-right -->
<path d="M560,560 A250,250 0 0 0 640,440 A270,270 0 0 1 560,560 Z" fill="#ffffff" opacity="0.28"/>
<path d="M590,540 A220,220 0 0 0 630,470 A235,235 0 0 1 590,540 Z" fill="#dff2ff" opacity="0.4"/>
<!-- small bounce light -->
<ellipse cx="505" cy="200" rx="26" ry="14" fill="#ffffff" opacity="0.35" transform="rotate(30 505 200)"/>
<!-- Top touch highlight -->
<ellipse cx="400" cy="128" rx="60" ry="18" fill="#ffffff" opacity="0.25" transform="rotate(-8 400 128)"/>
</svg>
</body>
</html>
Globe:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Procedural 3D Globe</title>
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#04060d;font-family:system-ui,sans-serif}
#ui{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:rgba(10,18,32,.75);padding:14px 22px;border-radius:12px;color:#cfe6ff;backdrop-filter:blur(6px);border:1px solid rgba(120,180,255,.25)}
#ui label{display:flex;align-items:center;gap:12px;font-size:14px}
input[type=range]{width:240px;accent-color:#5aa2ff}
#val{min-width:52px;text-align:right;font-variant-numeric:tabular-nums}
</style>
</head>
<body>
<div id="ui">
<label>Rotation Speed <input id="speed" type="range" min="0" max="2" step="0.01" value="0.4"> <span id="val">0.40</span></label>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script>
(function(){
// ---- Scene ----
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, innerWidth/innerHeight, 0.1, 100);
camera.position.set(0, 1.2, 4.2);
const renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(innerWidth, innerHeight);
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
scene.add(new THREE.AmbientLight(0x334466, 1.2));
const sun = new THREE.DirectionalLight(0xfff2e0, 2.2);
sun.position.set(5, 2, 3);
scene.add(sun);
const R = 1;
// ---- Procedural continent texture (value-noise on canvas) ----
function makeEarthTexture(size){
const cv = document.createElement('canvas'); cv.width = cv.height = size;
const ctx = cv.getContext('2d');
const g = ctx.createLinearGradient(0,0,0,size);
g.addColorStop(0,'#0b2d55'); g.addColorStop(.5,'#10508f'); g.addColorStop(1,'#0b2d55');
ctx.fillStyle = g; ctx.fillRect(0,0,size,size);
// deterministic hash-based value noise with fBm
const P = new Uint8Array(512);
let seed = 1337;
const rand = () => (seed = (seed*16807)%2147483647)/2147483647;
for(let i=0;i<256;i++) P[i]=i;
for(let i=255;i>0;i--){const j=(rand()*(i+1))|0;const t=P[i];P[i]=P[j];P[j]=t;}
for(let i=256;i<256;i++) P[256+i]=P[i];
const fade = t => t*t*(3-2*t);
const grad2 = (h,x,y) => ((h&1)?-x:x) + ((h&2)?-y:y);
function noise(x,y){
const X=Math.floor(x)&255, Y=Math.floor(y)&255;
x-=Math.floor(x); y-=Math.floor(y);
const u=fade(x), v=fade(y);
const a=P[X]+Y, b=P[X+1]+Y;
return THREE.MathUtils.lerp(
THREE.MathUtils.lerp(grad2(P[a],x,y), grad2(P[b],x-1,y), u),
THREE.MathUtils.lerp(grad2(P[a+1],x,y-1),grad2(P[b+1],x-1,y-1), u), v);
}
function fbm(x,y){
let v=0,a=.5,f=1;
for(let o=0;o<5;o++){ v+=a*noise(x*f,y*f); f*=2; a*=.5; }
return v;
}
const img = ctx.getImageData(0,0,size,size);
const d = img.data;
const scale = 5.5;
for(let py=0;py<size;py++){
const lat = py/size*Math.PI;
for(let px=0;px<size;px++){
// sample noise on cylinder to avoid seam
const ang = px/size*Math.PI*2;
const nx = Math.cos(ang)*scale, ny = Math.sin(ang)*scale, nz = lat/Math.PI*scale*2;
let h = fbm(nx+nz*1.7, ny+nz*0.9) + fbm(nz*2.3, nx+ny)*0.5;
h += 0.15*Math.sin(lat*6+fbm(nx,ny)*3); // banding
const i = (py*size+px)*4;
if(h > 0.28){
// land: green -> mountain -> snow by height & latitude
const t = (h-0.28)/0.7;
let r=42+90*t, gg=110-20*t, b=52+30*t;
const polar = Math.abs(py/size-0.5)*2;
if(polar>0.82 || t>0.75){ r=235;gg=240;b=245; } // ice caps / peaks
else if(t>0.5){ r=120+80*(t-.5)/.5; gg=105; b=70; } // mountains
d[i]=r; d[i+1]=gg; d[i+2]=b;
} else if(h > 0.22){
d[i]=218; d[i+1]=205; d[i+2]=160; // beach
}
}
}
ctx.putImageData(img,0,0);
// subtle cloud speckle
ctx.globalAlpha = 0.10;
for(let i=0;i<900;i++){
ctx.fillStyle = '#fff';
const x=rand()*size, y=rand()*size;
ctx.beginPath(); ctx.ellipse(x,y,rand()*30+8,rand()*8+3,rand()*3,0,7); ctx.fill();
}
ctx.globalAlpha = 1;
const tex = new THREE.CanvasTexture(cv);
return tex;
}
const earthTex = makeEarthTexture(1024);
const globe = new THREE.Mesh(
new THREE.SphereGeometry(R, 64, 64),
new THREE.MeshStandardMaterial({map:earthTex, roughness:0.85, metalness:0.05})
);
scene.add(globe);
// ---- Atmospheric glow ----
const atmo = new THREE.Mesh(
new THREE.SphereGeometry(R*1.18, 48, 48),
new THREE.ShaderMaterial({
transparent:true, side:THREE.BackSide, blending:THREE.AdditiveBlending, depthWrite:false,
vertexShader:`varying vec3 vN; void main(){ vN = normalize(normalMatrix*normal); gl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0); }`,
fragmentShader:`varying vec3 vN; void main(){ float i = pow(0.72 - dot(vN, vec3(0.,0.,1.)), 3.0); gl_FragColor = vec4(0.3,0.6,1.0,1.0)*i; }`
})
);
scene.add(atmo);
// ---- Orbiting particle ring ----
const COUNT = 1500;
const pos = new Float32Array(COUNT*3);
const phases = new Float32Array(COUNT), radii = new Float32Array(COUNT), heights = new Float32Array(COUNT);
for(let i=0;i<COUNT;i++){
phases[i] = Math.random()*Math.PI*2;
radii[i] = R*1.35 + Math.random()*R*0.5;
heights[i]= (Math.random()-0.5)*0.25;
}
const pGeo = new THREE.BufferGeometry();
pGeo.setAttribute('position', new THREE.BufferAttribute(pos,3));
const ring = new THREE.Points(pGeo, new THREE.PointsMaterial({
color:0x9fd0ff, size:0.02, transparent:true, opacity:0.9, blending:THREE.AdditiveBlending, depthWrite:false
}));
ring.rotation.z = 0.35;
scene.add(ring);
// ---- Controls: drag rotate + wheel zoom ----
let dragging=false, px=0, py=0;
let rotX = 0.25, rotY = 0, spin = 0.4;
const el = renderer.domElement;
el.addEventListener('pointerdown', e=>{dragging=true;px=e.clientX;py=e.clientY;el.setPointerCapture(e.pointerId);});
el.addEventListener('pointermove', e=>{
if(!dragging) return;
rotY += (e.clientX-px)*0.005;
rotX = THREE.MathUtils.clamp(rotX + (e.clientY-py)*0.005, -1.3, 1.3);
px=e.clientX; py=e.clientY;
});
el.addEventListener('pointerup', ()=>dragging=false);
let zoom = 4.2;
el.addEventListener('wheel', e=>{
e.preventDefault();
zoom = THREE.MathUtils.clamp(zoom + e.deltaY*0.002, 2.2, 8);
}, {passive:false});
const slider = document.getElementById('speed');
const valEl = document.getElementById('val');
slider.addEventListener('input', ()=>{ spin = +slider.value; valEl.textContent = spin.toFixed(2); });
addEventListener('resize', ()=>{
camera.aspect = innerWidth/innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
// ---- Animate ----
const clock = new THREE.Clock();
function animate(){
requestAnimationFrame(animate);
const t = clock.getElapsedTime();
globe.rotation.y += spin*0.01;
globe.rotation.x = rotX*0.4;
// particles orbit
for(let i=0;i<COUNT;i++){
const a = phases[i] + t*(0.25 + 0.35/radii[i]);
pos[i*3] = Math.cos(a)*radii[i];
pos[i*3+1] = heights[i]*Math.sin(a*2+phases[i]);
pos[i*3+2] = Math.sin(a)*radii[i];
}
pGeo.attributes.position.needsUpdate = true;
camera.position.x = Math.sin(rotY)*zoom*Math.cos(rotX);
camera.position.y = Math.sin(rotX)*zoom;
camera.position.z = Math.cos(rotY)*zoom*Math.cos(rotX);
camera.lookAt(0,0,0);
renderer.render(scene, camera);
}
animate();
})();
</script>
</body>
</html>
Wizard:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Wizard of the Floating Isles</title>
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#aee7ff;font-family:system-ui,sans-serif;user-select:none}
canvas{display:block}
#hud{position:fixed;top:16px;left:16px;color:#fff;text-shadow:0 2px 4px rgba(0,0,0,.4);font-size:18px;line-height:1.5}
#hpbar{width:220px;height:14px;background:rgba(0,0,0,.35);border-radius:8px;overflow:hidden;margin-top:4px}
#hpfill{height:100%;width:100%;background:linear-gradient(90deg,#7dffa0,#2ecc71);transition:width .2s}
#msg{position:fixed;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(10,20,40,.55);color:#fff;text-align:center}
#msg h1{font-size:44px;margin:0 0 12px}
#msg p{font-size:18px;margin:6px}
button{font-size:20px;padding:12px 32px;border-radius:10px;border:none;cursor:pointer;background:#ffd166;color:#4a3000;margin-top:16px}
.hidden{display:none!important}
</style>
</head>
<body>
<div id="hud">
Score: <span id="score">0</span> / 10<br>
Health
<div id="hpbar"><div id="hpfill"></div></div>
</div>
<div id="msg">
<h1 id="title">Wizard of the Floating Isles</h1>
<p id="subtitle">WASD to move · SPACE to jump · drag mouse to look<br>Collect 10 crystal artifacts — dodge the elemental turrets!</p>
<button id="startBtn">Start</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script>
(function(){
const W = () => innerWidth, H = () => innerHeight;
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x9fd8f5);
scene.fog = new THREE.Fog(0x9fd8f5, 30, 120);
const camera = new THREE.PerspectiveCamera(60, W()/H(), .1, 300);
const renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(W(), H());
renderer.setPixelRatio(Math.min(devicePixelRatio,2));
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
// ---------- Lights / day-night ----------
const hemi = new THREE.HemisphereLight(0xbfe8ff, 0xffd9e8, 0.8); scene.add(hemi);
const sun = new THREE.DirectionalLight(0xfff3d6, 1.6);
sun.castShadow = true;
sun.shadow.mapSize.set(1024,1024);
Object.assign(sun.shadow.camera,{left:-40,right:40,top:40,bottom:-40,far:120});
scene.add(sun);
// ---------- World: floating islands ----------
const islands = []; // {mesh, x,z,r} for collision
const pastel = [0xffc1d9, 0xc7b8ff, 0xbaf0c4, 0xffe3a3, 0xa8dced, 0xf8b7d4];
function makeIsland(x, y, z, r){
const g = new THREE.Group();
const top = new THREE.Mesh(new THREE.CylinderGeometry(r, r*0.75, 1.6, 12),
new THREE.MeshStandardMaterial({color: pastel[(Math.random()*pastel.length)|0], flatShading:true, roughness:.9}));
top.position.y = -0.8;
top.castShadow = top.receiveShadow = true;
g.add(top);
const rock = new THREE.Mesh(new THREE.ConeGeometry(r*0.75, r*1.6, 8),
new THREE.MeshStandardMaterial({color:0x9c8fb5, flatShading:true}));
rock.position.y = -2.2; rock.rotation.x = Math.PI;
g.add(rock);
// decorative trees
const nT = 1 + (Math.random()*3|0);
for(let i=0;i<nT;i++){
const tr = new THREE.Group();
const a = Math.random()*Math.PI*2, d = Math.random()*r*0.6;
tr.position.set(Math.cos(a)*d, 0, Math.sin(a)*d);
const trunk = new THREE.Mesh(new THREE.CylinderGeometry(.12,.16,.7,6), new THREE.MeshStandardMaterial({color:0xb5836b}));
trunk.position.y=.35; tr.add(trunk);
const leaf = new THREE.Mesh(new THREE.ConeGeometry(.55,1.2,7), new THREE.MeshStandardMaterial({color: pastel[(Math.random()*pastel.length)|0], flatShading:true}));
leaf.position.y=1.2; leaf.castShadow=true; tr.add(leaf);
g.add(tr);
}
g.position.set(x,y,z);
scene.add(g);
islands.push({x, y, z, r, group:g});
return g;
}
const layout = [[0,0,7],[14,-1,5],[-13,-2,5],[8,-8,4.5],[-8,-9,4.5],[22,-4,4],[-21,-6,4],[3,-16,4],[-4,-18,3.5]];
layout.forEach(l=>makeIsland(l[0],l[1],l[2],l[1+0]===undefined?0:l[1]));
// fix y usage: layout is [x, y, z] already handled above? ensure:
islands.length = 0; scene.clear(); scene.add(hemi); scene.add(sun);
layout.forEach(l=>makeIsland(l[0], l[1], l[2]));
// bridges (visual)
layout.slice(1).forEach(l=>{
const from = layout[0];
const mid = new THREE.Mesh(new THREE.BoxGeometry(Math.hypot(l[0]-from[0],l[2]-from[2])*0.5, .3, 1.4),
new THREE.MeshStandardMaterial({color:0xf5d9b8}));
mid.position.set((l[0]+from[0])/2, Math.min(l[1],from[1])+0.1, (l[2]+from[2])/2);
mid.rotation.y = -Math.atan2(l[2]-from[2], l[0]-from[0]);
scene.add(mid);
});
// ---------- Wizard ----------
const wiz = new THREE.Group();
const robe = new THREE.Mesh(new THREE.ConeGeometry(.45,1.1,8), new THREE.MeshStandardMaterial({color:0x8f7bff, flatShading:true}));
robe.position.y=.55; robe.castShadow=true; wiz.add(robe);
const head = new THREE.Mesh(new THREE.SphereGeometry(.24,10,10), new THREE.MeshStandardMaterial({color:0xffe0c2}));
head.position.y=1.3; wiz.add(head);
const hat = new THREE.Mesh(new THREE.ConeGeometry(.34,.75,8), new THREE.MeshStandardMaterial({color:0x5b48d8, flatShading:true}));
hat.position.y=1.75; hat.castShadow=true; wiz.add(hat);
const staff = new THREE.Mesh(new THREE.CylinderGeometry(.05,.05,1.6,6), new THREE.MeshStandardMaterial({color:0x8a5a3a}));
staff.position.set(.5,.8,0); wiz.add(staff);
const orb = new THREE.Mesh(new THREE.SphereGeometry(.11,8,8), new THREE.MeshStandardMaterial({color:0x7dffe0, emissive:0x35ffc0, emissiveIntensity:2}));
orb.position.set(.5,1.62,0); wiz.add(orb);
scene.add(wiz);
const player = {pos:new THREE.Vector3(0,1.5,0), vel:new THREE.Vector3(), onGround:false, hp:100, score:0, yaw:0};
// ---------- Crystals ----------
const crystals = [];
layout.forEach((l,i)=>{
const c = new THREE.Mesh(new THREE.OctahedronGeometry(.45),
new THREE.MeshStandardMaterial({color:0xff7de9, emissive:0xff4fd0, emissiveIntensity:1.4, metalness:.3, roughness:.2}));
const a = Math.random()*Math.PI*2, d = Math.random()*l[2]*0.4;
c.position.set(l[0]+Math.cos(a)*d, l[1]+1.4, l[2]+Math.sin(a)*d);
scene.add(c); crystals.push(c);
});
// ---------- Turrets ----------
const turrets = [];
[[14,-1,5],[8,-8,4.5],[22,-4,4],[-4,-18,3.5]].forEach(l=>{
const t = new THREE.Group();
const base = new THREE.Mesh(new THREE.CylinderGeometry(.5,.65,.8,8), new THREE.MeshStandardMaterial({color:0xff9a6b, flatShading:true}));
base.position.y=.4; t.add(base);
const eye = new THREE.Mesh(new THREE.SphereGeometry(.22,8,8), new THREE.MeshStandardMaterial({color:0xff3b3b, emissive:0xff2222, emissiveIntensity:1.5}));
eye.position.y=.95; t.add(eye);
t.position.set(l[0], l[1], l[2]);
scene.add(t);
turrets.push({group:t, eye, cd:Math.random()*2, isle:l});
});
const projectiles = [];
// ---------- Particles (ambient sparkles) ----------
const pCount = 300, pPos = new Float32Array(pCount*3);
for(let i=0;i<pCount;i++){ pPos[i*3]=(Math.random()-.5)*60; pPos[i*3+1]=Math.random()*20-5; pPos[i*3+2]=(Math.random()-.5)*60; }
const pGeo = new THREE.BufferGeometry();
pGeo.setAttribute('position', new THREE.BufferAttribute(pPos,3));
scene.add(new THREE.Points(pGeo, new THREE.PointsMaterial({color:0xffffff, size:.12, transparent:true, opacity:.7})));
// ---------- Clouds ----------
for(let i=0;i<14;i++){
const cl = new THREE.Mesh(new THREE.SphereGeometry(2+Math.random()*2,8,8),
new THREE.MeshStandardMaterial({color:0xffffff, transparent:true, opacity:.85, flatShading:true}));
cl.scale.y=.4;
cl.position.set((Math.random()-.5)*90, 6+Math.random()*8, (Math.random()-.5)*90);
scene.add(cl);
}
// ---------- Audio ----------
let AC=null;
function audio(){ if(!AC) AC = new (window.AudioContext||window.webkitAudioContext)(); return AC; }
function beep(f, dur, type, vol){
try{
const ac = audio(), o = ac.createOscillator(), g = ac.createGain();
o.type = type||'sine'; o.frequency.value = f;
g.gain.setValueAtTime(vol||.2, ac.currentTime);
g.gain.exponentialRampToValueAtTime(.001, ac.currentTime+dur);
o.connect(g); g.connect(ac.destination);
o.start(); o.stop(ac.currentTime+dur);
}catch(e){ /* audio init not supported; ignore */ }
}
// ---------- Input ----------
const keys = {};
addEventListener('keydown', e=>{ keys[e.code]=true; if(e.code==='Space') e.preventDefault(); });
addEventListener('keyup', e=>keys[e.code]=false);
let camYaw=0, camPitch=.35, dragging=false, mx=0, my=0;
renderer.domElement.addEventListener('pointerdown', e=>{dragging=true;mx=e.clientX;my=e.clientY;});
addEventListener('pointerup', ()=>dragging=false);
addEventListener('pointermove', e=>{
if(!dragging) return;
camYaw -= (e.clientX-mx)*.005;
camPitch = THREE.MathUtils.clamp(camPitch+(e.clientY-my)*.004, -.1, 1.2);
mx=e.clientX; my=e.clientY;
});
// ---------- Game state ----------
const msg=document.getElementById('msg'), title=document.getElementById('title'),
sub=document.getElementById('subtitle'), btn=document.getElementById('startBtn'),
scoreEl=document.getElementById('score'), hpfill=document.getElementById('hpfill');
let running=false, gameOver=false;
const clock = new THREE.Clock();
function endGame(win){
running=false; gameOver=true;
title.textContent = win ? 'You Win! 🪄' : 'Game Over';
sub.textContent = `Final score: ${player.score} artifacts`;
btn.textContent = 'Restart';
msg.classList.remove('hidden');
beep(win?880:140, .5, win?'triangle':'sawtooth', .25);
}
function reset(){
player.pos.set(0,1.5,0); player.vel.set(0,0,0); player.hp=100; player.score=0;
projectiles.forEach(p=>scene.remove(p.mesh)); projectiles.length=0;
crystals.forEach(c=>c.visible=true);
scoreEl.textContent=0; hpfill.style.width='100%';
gameOver=false;
}
btn.addEventListener('click', ()=>{
audio();
if(gameOver) reset();
msg.classList.add('hidden');
running=true;
});
function groundAt(x, z){
// returns island surface y if standing on one, else -Infinity
let best = -Infinity;
for(const isl of islands){
const d = Math.hypot(x-isl.x, z-isl.z);
if(d < isl.r) best = Math.max(best, isl.y + 0.05);
}
return best;
}
function animate(){
requestAnimationFrame(animate);
const dt = Math.min(clock.getDelta(), .05);
const t = clock.elapsedTime;
// day-night cycle
const dayPhase = (Math.sin(t*.08)+1)/2;
sun.intensity = .4 + 1.4*dayPhase;
sun.position.set(Math.cos(t*.08)*40, 20+20*dayPhase, 20);
const skyDay = new THREE.Color(0x9fd8f5), skyNight = new THREE.Color(0x1a2550);
scene.background.copy(skyNight).lerp(skyDay, dayPhase);
scene.fog.color.copy(scene.background);
hemi.intensity = .3 + .6*dayPhase;
crystals.forEach(c=>{ c.rotation.y += dt*2; c.position.y += Math.sin(t*3+c.id)*.002; });
pGeo.attributes.position.needsUpdate = true;
if(running){
// movement
const fwd = new THREE.Vector3(-Math.sin(camYaw),0,-Math.cos(camYaw));
const right = new THREE.Vector3(-fwd.z,0,fwd.x);
const mv = new THREE.Vector3();
if(keys.KeyW) mv.add(fwd); if(keys.KeyS) mv.sub(fwd);
if(keys.KeyD) mv.add(right); if(keys.KeyA) mv.sub(right);
if(mv.lengthSq()>0){ mv.normalize(); player.yaw = Math.atan2(mv.x,mv.z); }
player.pos.addScaledVector(mv, 6*dt);
if(keys.Space && player.onGround){ player.vel.y = 8; player.onGround=false; beep(500,.15,'square',.12); }
// gravity + landing
player.vel.y -= 22*dt;
player.pos.y += player.vel.y*dt;
const gy = groundAt(player.pos.x, player.pos.z);
if(player.pos.y <= gy+1.4 && gy > -Infinity && player.vel.y<=0){
player.pos.y = gy+1.4; player.vel.y=0; player.onGround=true;
} else player.onGround=false;
// fell off
if(player.pos.y < -25){ player.hp = 0; }
wiz.position.copy(player.pos);
wiz.rotation.y = player.yaw;
// crystals pickup
crystals.forEach(c=>{
if(c.visible && c.position.distanceTo(player.pos) < 1.2){
c.visible=false; player.score++;
scoreEl.textContent = player.score;
beep(880+player.score*60,.2,'triangle',.2);
if(player.score>=10) endGame(true);
}
});
// turrets shoot
turrets.forEach(tr=>{
tr.group.rotation.y = t;
tr.cd -= dt;
const d = tr.group.position.distanceTo(player.pos);
if(d < 18 && tr.cd<=0){
tr.cd = 2.2;
const m = new THREE.Mesh(new THREE.SphereGeometry(.18,8,8),
new THREE.MeshStandardMaterial({color:0xff6b4b, emissive:0xff4422, emissiveIntensity:2}));
m.position.copy(tr.eye.getWorldPosition(new THREE.Vector3()));
const dir = player.pos.clone().add(new THREE.Vector3(0,1,0)).sub(m.position).normalize();
scene.add(m);
projectiles.push({mesh:m, vel:dir.multiplyScalar(11), life:4});
beep(180,.12,'sawtooth',.08);
}
});
for(let i=projectiles.length-1;i>=0;i--){
const p = projectiles[i];
p.mesh.position.addScaledVector(p.vel, dt);
p.life -= dt;
if(p.mesh.position.distanceTo(player.pos) < .9){
player.hp -= 15; hpfill.style.width = Math.max(0,player.hp)+'%';
beep(120,.25,'sawtooth',.2);
scene.remove(p.mesh); projectiles.splice(i,1);
if(player.hp<=0) endGame(false);
} else if(p.life<=0){ scene.remove(p.mesh); projectiles.splice(i,1); }
}
} else {
wiz.position.copy(player.pos);
}
// camera follow with damping
const camTarget = new THREE.Vector3(
player.pos.x + Math.sin(camYaw)*7*Math.cos(camPitch),
player.pos.y + 2 + 7*Math.sin(camPitch),
player.pos.z + Math.cos(camYaw)*7*Math.cos(camPitch));
camera.position.lerp(camTarget, .08);
camera.lookAt(player.pos.x, player.pos.y+1.2, player.pos.z);
renderer.render(scene, camera);
}
animate();
addEventListener('resize', ()=>{
camera.aspect=W()/H(); camera.updateProjectionMatrix();
renderer.setSize(W(),H());
});
})();
</script>
</body>
</html>
Neon Runner:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>NEON RUNNER</title>
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#07030f;font-family:'Segoe UI',system-ui,sans-serif;user-select:none}
canvas{display:block}
.ui{position:fixed;color:#fff;text-shadow:0 0 12px #ff2fd6}
#hud{top:16px;left:16px;font-size:20px;line-height:1.6}
#mult{top:16px;right:16px;font-size:28px;color:#2ffcff;text-shadow:0 0 14px #2ffcff}
#menu{inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(5,0,15,.82);backdrop-filter:blur(4px)}
#menu h1{font-size:64px;margin:0;letter-spacing:8px;background:linear-gradient(90deg,#ff2fd6,#2ffcff);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
#menu p{color:#b9a8e8;margin:8px 0 2px;font-size:16px}
#board{margin-top:18px;color:#2ffcff;font-size:15px;text-align:center;line-height:1.7}
button{font-size:22px;padding:14px 44px;border-radius:999px;border:2px solid #2ffcff;background:transparent;color:#2ffcff;cursor:pointer;letter-spacing:4px;margin-top:22px;box-shadow:0 0 18px #2ffcff66, inset 0 0 18px #2ffcff33;transition:.2s}
button:hover{background:#2ffcff22;box-shadow:0 0 30px #2ffcff}
.hidden{display:none!important}
#touch{bottom:0;left:0;right:0;height:35%;display:none}
</style>
</head>
<body>
<div id="hud" class="ui">Score <span id="score">0</span><br>Speed <span id="spd">0</span></div>
<div id="mult" class="ui">x1</div>
<div id="menu" class="ui">
<h1>NEON RUNNER</h1>
<p>A / D or ← / → or touch to steer · dodge lasers & rocks · grab boosts</p>
<div id="board">HIGH SCORES</div>
<button id="start">START</button>
</div>
<div id="touch" class="ui"></div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script>
(function(){
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0a0418);
scene.fog = new THREE.Fog(0x0a0418, 30, 140);
const camera = new THREE.PerspectiveCamera(70, innerWidth/innerHeight, .1, 300);
const renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(innerWidth, innerHeight);
renderer.setPixelRatio(Math.min(devicePixelRatio,2));
document.body.appendChild(renderer.domElement);
scene.add(new THREE.AmbientLight(0x331166, 1.4));
const magenta = new THREE.PointLight(0xff2fd6, 3, 60); scene.add(magenta);
const cyan = new THREE.PointLight(0x2ffcff, 3, 60); scene.add(cyan);
// ---------- Canyon walls ----------
const wallMatA = new THREE.MeshStandardMaterial({color:0x1a0b33, emissive:0x330066, roughness:.6});
const neonMatA = new THREE.MeshBasicMaterial({color:0xff2fd6});
const neonMatB = new THREE.MeshBasicMaterial({color:0x2ffcff});
const WALL_X = 11, SEG_LEN = 20, SEG_COUNT = 12;
const walls = [];
function buildSegment(z){
const g = new THREE.Group();
for(const side of [-1,1]){
const h = 6 + Math.random()*8;
const w = new THREE.Mesh(new THREE.BoxGeometry(3, h, SEG_LEN*.96), wallMatA);
w.position.set(side*(WALL_X+1.5), h/2-2, 0);
g.add(w);
// neon strips
for(let i=0;i<3;i++){
const s = new THREE.Mesh(new THREE.BoxGeometry(.2,.2,SEG_LEN*.9), Math.random()<.5?neonMatA:neonMatB);
s.position.set(side*(WALL_X-.35), .5+Math.random()*7, 0);
g.add(s);
}
// pylons
const p = new THREE.Mesh(new THREE.BoxGeometry(.6,10+Math.random()*6,.6), neonMatA);
p.position.set(side*(WALL_X+2), 3, -SEG_LEN/2);
g.add(p);
}
// floor glow grid
for(let i=0;i<6;i++){
const f = new THREE.Mesh(new THREE.BoxGeometry(WALL_X*2,.05,.15), neonMatB);
f.position.set(0,-1.4, -SEG_LEN/2 + i*SEG_LEN/6);
g.add(f);
}
g.position.z = z;
scene.add(g);
return g;
}
for(let i=0;i<SEG_COUNT;i++) walls.push(buildSegment(-i*SEG_LEN));
// ---------- Player hover-car ----------
const car = new THREE.Group();
const bodyMat = new THREE.MeshStandardMaterial({color:0x2ffcff, emissive:0x0e6677, metalness:.7, roughness:.3});
const body = new THREE.Mesh(new THREE.BoxGeometry(1.6,.5,3), bodyMat);
body.position.y=.2; car.add(body);
const nose = new THREE.Mesh(new THREE.ConeGeometry(.7,1.4,4), bodyMat);
nose.rotation.x = -Math.PI/2; nose.rotation.y = Math.PI/4; nose.position.set(0,.2,2); car.add(nose);
for(const s of [-1,1]){
const wing = new THREE.Mesh(new THREE.BoxGeometry(1,.12,.9), new THREE.MeshStandardMaterial({color:0xff2fd6, emissive:0x880066}));
wing.position.set(s*1.2,.5,-1.2); wing.rotation.z = s*.3; car.add(wing);
}
const jet = new THREE.Mesh(new THREE.ConeGeometry(.4,1.2,8), new THREE.MeshBasicMaterial({color:0x2ffcff, transparent:true, opacity:.8}));
jet.rotation.x = Math.PI/2; jet.position.set(0,.2,-2); car.add(jet);
scene.add(car);
// ---------- Obstacles / pickups / lasers ----------
const obstacles = []; // {mesh, type, x}
function spawnRow(){
const z = car.position.z - 130;
const roll = Math.random();
if(roll < .4){
// rock
const m = new THREE.Mesh(new THREE.DodecahedronGeometry(1+Math.random()),
new THREE.MeshStandardMaterial({color:0x552299, emissive:0x220066, flatShading:true}));
m.position.set((Math.random()*2-1)*(WALL_X-2), -0.2, z);
scene.add(m); obstacles.push({mesh:m, type:'rock', vz:0});
} else if(roll < .7){
// moving drone
const m = new THREE.Mesh(new THREE.OctahedronGeometry(.9),
new THREE.MeshStandardMaterial({color:0xff2fd6, emissive:0xaa0088, flatShading:true}));
m.position.set(0, .6, z);
scene.add(m); obstacles.push({mesh:m, type:'drone', dir:Math.random()<.5?1:-1, vz:0});
} else if(roll < .85){
// laser barrier
const m = new THREE.Mesh(new THREE.BoxGeometry(WALL_X*2-2,.25,.25),
new THREE.MeshBasicMaterial({color:0xff2233}));
m.position.set(0, .4+Math.random()*2, z);
scene.add(m); obstacles.push({mesh:m, type:'laser', phase:Math.random()*7, vz:0, baseY:m.position.y});
} else {
// energy boost
const m = new THREE.Mesh(new THREE.TorusGeometry(.6,.18,8,16),
new THREE.MeshStandardMaterial({color:0x9dff2f, emissive:0x55aa00, emissiveIntensity:1.5}));
m.position.set((Math.random()*2-1)*(WALL_X-3), .8, z);
scene.add(m); obstacles.push({mesh:m, type:'boost', vz:0});
}
}
// ---------- Floating score text (CSS) ----------
const floats = [];
function floatText(txt, x, y, color){
const el = document.createElement('div');
el.textContent = txt;
el.style.cssText = `position:fixed;left:${x}px;top:${y}px;color:${color};font-size:26px;font-weight:bold;text-shadow:0 0 12px ${color};pointer-events:none;transition:all .9s ease-out`;
document.body.appendChild(el);
requestAnimationFrame(()=>{ el.style.top = (y-90)+'px'; el.style.opacity = '0'; });
setTimeout(()=>el.remove(), 1000);
}
// ---------- Audio ----------
let AC=null, musicTimer=null, musicStep=0;
function audio(){ if(!AC) AC = new (window.AudioContext||window.webkitAudioContext)(); return AC; }
function tone(f, dur, type, vol, when){
const ac = audio();
const o = ac.createOscillator(), g = ac.createGain();
o.type = type||'sine'; o.frequency.value = f;
const t0 = ac.currentTime + (when||0);
g.gain.setValueAtTime(vol||.15, t0);
g.gain.exponentialRampToValueAtTime(.001, t0+dur);
o.connect(g); g.connect(ac.destination);
o.start(t0); o.stop(t0+dur);
}
const BASS = [55,55,65.4,49], LEAD = [440,523,659,523,392,440,349,392];
function startMusic(){
stopMusic();
musicTimer = setInterval(()=>{
tone(BASS[musicStep%4], .28, 'sawtooth', .1);
tone(BASS[musicStep%4]*2, .14, 'square', .04);
if(musicStep%2===0) tone(LEAD[(musicStep/2)%8], .22, 'triangle', .05);
musicStep++;
}, 300);
}
function stopMusic(){ if(musicTimer){clearInterval(musicTimer); musicTimer=null;} }
// ---------- UI ----------
const menu=document.getElementById('menu'), startBtn=document.getElementById('start'),
scoreEl=document.getElementById('score'), spdEl=document.getElementById('spd'),
multEl=document.getElementById('mult'), board=document.getElementById('board');
let running=false, score=0, mult=1, multTimer=0, speed=30;
function loadScores(){
try{ return JSON.parse(localStorage.getItem('neonRunnerScores')||'[]'); }catch(e){ return []; }
}
function showBoard(){
const s = loadScores();
board.innerHTML = 'HIGH SCORES<br>' + (s.length? s.slice(0,5).map((v,i)=>`${i+1}. ${v}`).join('<br>') : '— none yet —');
}
function saveScore(v){
const s = loadScores(); s.push(v); s.sort((a,b)=>b-a);
localStorage.setItem('neonRunnerScores', JSON.stringify(s.slice(0,10)));
showBoard();
}
showBoard();
// ---------- Input ----------
const keys = {};
let steer = 0, touchX = null;
addEventListener('keydown', e=>{ keys[e.code]=true; if(e.code.startsWith('Arrow')) e.preventDefault(); });
addEventListener('keyup', e=>keys[e.code]=false);
const touchZone = document.getElementById('touch');
touchZone.style.display = 'block'; touchZone.style.pointerEvents='none';
addEventListener('touchstart', e=>touchX = e.touches[0].clientX, {passive:true});
addEventListener('touchmove', e=>touchX = e.touches[0].clientX, {passive:true});
addEventListener('touchend', ()=>touchX=null, {passive:true});
// ---------- Game loop ----------
const clock = new THREE.Clock();
let travel = 0;
function reset(){
obstacles.forEach(o=>scene.remove(o.mesh)); obstacles.length=0;
score=0; mult=1; speed=30; travel=0;
car.position.set(0,0,0);
scoreEl.textContent=0; multEl.textContent='x1';
}
startBtn.addEventListener('click', ()=>{
audio(); reset();
menu.classList.add('hidden');
running=true;
startMusic();
tone(880,.2,'triangle',.15); tone(1320,.3,'triangle',.1,.1);
});
function crash(){
running=false; stopMusic();
tone(110,.6,'sawtooth',.3); tone(55,.9,'square',.2,.1);
saveScore(Math.floor(score));
menu.classList.remove('hidden');
document.getElementById('menu').querySelector('p').textContent = `CRASHED — Score: ${Math.floor(score)}`;
}
function animate(){
requestAnimationFrame(animate);
const dt = Math.min(clock.getDelta(), .05);
const t = clock.elapsedTime;
// always animate visuals
car.rotation.z = -steer*.4;
car.rotation.y = steer*.15;
jet.scale.setScalar(.8 + Math.sin(t*30)*.2 + speed/200);
magenta.position.set(Math.sin(t)*8, 5, car.position.z-10);
cyan.position.set(Math.cos(t*1.3)*8, 5, car.position.z-20);
if(running){
speed += dt*1.2; // ramp up
score += speed*dt*.1*mult;
scoreEl.textContent = Math.floor(score);
spdEl.textContent = Math.floor(speed*3.6);
multTimer -= dt;
if(multTimer<=0 && mult>1){ mult=Math.max(1,mult-1); multEl.textContent='x'+mult; }
// steering
let s = 0;
if(keys.KeyA||keys.ArrowLeft) s-=1;
if(keys.KeyD||keys.ArrowRight) s+=1;
if(touchX!==null) s = THREE.MathUtils.clamp((touchX-innerWidth/2)/(innerWidth/4), -1, 1);
steer = THREE.MathUtils.lerp(steer, s, .15);
car.position.x = THREE.MathUtils.clamp(car.position.x + steer*14*dt, -WALL_X+1.5, WALL_X-1.5);
car.position.y = Math.sin(t*3)*.15;
car.position.z -= speed*dt;
travel += speed*dt;
// recycle canyon segments
walls.forEach(w=>{
if(w.position.z > car.position.z + SEG_LEN) w.position.z -= SEG_COUNT*SEG_LEN;
});
// spawn
if(travel > 14){ travel=0; spawnRow(); }
// move/update obstacles
for(let i=obstacles.length-1;i>=0;i--){
const o = obstacles[i];
if(o.type==='drone'){
o.mesh.position.x += o.dir*6*dt;
if(Math.abs(o.mesh.position.x)>WALL_X-2) o.dir*=-1;
o.mesh.rotation.y += dt*3;
}
if(o.type==='laser'){
o.mesh.position.y = o.baseY + Math.sin(t*2+o.phase)*1.2;
}
if(o.type==='boost') o.mesh.rotation.y += dt*4;
// despawn behind
if(o.mesh.position.z > car.position.z + 10){ scene.remove(o.mesh); obstacles.splice(i,1); continue; }
// collision
const dz = Math.abs(o.mesh.position.z - car.position.z);
const dx = Math.abs(o.mesh.position.x - car.position.x);
if(dz < 1.6 && dx < 1.8){
if(o.type==='boost'){
scene.remove(o.mesh); obstacles.splice(i,1);
mult = Math.min(8, mult+1); multTimer = 6;
multEl.textContent = 'x'+mult;
floatText('x'+mult+' BOOST!', innerWidth/2, innerHeight/2, '#9dff2f');
tone(700+mult*100,.2,'triangle',.2);
} else {
const dy = Math.abs(o.mesh.position.y - car.position.y);
if(dy < (o.type==='laser'?1.1:1.6)){ crash(); }
}
}
}
}
// camera: damped follow, speed-based FOV
const camT = new THREE.Vector3(car.position.x*.55, 3.4, car.position.z + 8.5);
camera.position.lerp(camT, .12);
camera.lookAt(car.position.x*.3, 1, car.position.z - 12);
camera.fov = THREE.MathUtils.lerp(camera.fov, 68 + speed*.35, .05);
camera.updateProjectionMatrix();
renderer.render(scene, camera);
}
animate();
addEventListener('resize', ()=>{
camera.aspect = innerWidth/innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
})();
</script>
</body>
</html>
Read Next
K2 Horizon: Specs, Benchmarks & Open-Model Analysis
IFM's six-model K2 Horizon family combines open weights, training artifacts, a reported 512K context window, and agentic benchmarks. What developers should know.
Hy4 Preview: It’s a Good, Cost-Efficient Model
Tencent just released Hy4-preview, and it is a great competitor in the cheap AI market. With an open-source 770B MoE architecture (49B active), $0.834 / $2.501 per 1M pricing, and performance matching GLM 5.3 Flash, we test it on Hy AI Studio with our 3D origami crane benchmark.
When OpenAI Hacked Hugging Face: Why a Chinese Open-Source Model Saved the Day
In an unprecedented incident, OpenAI's GPT-5.6 Sol autonomously compromised Hugging Face infrastructure to cheat a security benchmark. When US safety guardrails blocked incident response, Hugging Face turned to China's open-source GLM 5.2 to analyze 17,000 attack footprints.