// ===== STARFIELD (FIXED CLEAN VERSION) ===== let stars; let starPositions; let starSpeeds; function createStars(scene) { const starCount = 4000; const geometry = new THREE.BufferGeometry(); starPositions = new Float32Array(starCount * 3); starSpeeds = new Float32Array(starCount); for (let i = 0; i < starCount; i++) { const i3 = i * 3; // Spread stars in deep space starPositions[i3] = (Math.random() - 0.5) * 2000; starPositions[i3 + 1] = (Math.random() - 0.5) * 2000; starPositions[i3 + 2] = -Math.random() * 2000; // Slow forward drift (towards camera) starSpeeds[i] = 0.02 + Math.random() * 0.05; } geometry.setAttribute( 'position', new THREE.BufferAttribute(starPositions, 3) ); const material = new THREE.PointsMaterial({ color: 0xffffff, size: 0.8, // SMALL → fixes big squares sizeAttenuation: true, // perspective scaling depthWrite: false // prevents glow artifacts }); stars = new THREE.Points(geometry, material); scene.add(stars); } // ===== STAR ANIMATION ===== function updateStars() { const positions = stars.geometry.attributes.position.array; for (let i = 0; i < positions.length; i += 3) { const index = i / 3; // Move toward camera (Z axis) positions[i + 2] += starSpeeds[index]; // Reset when too close if (positions[i + 2] > 10) { positions[i] = (Math.random() - 0.5) * 2000; positions[i + 1] = (Math.random() - 0.5) * 2000; positions[i + 2] = -2000; starSpeeds[index] = 0.02 + Math.random() * 0.05; } } stars.geometry.attributes.position.needsUpdate = true; }