From fc624a53c04467b70d5e77638e71142fddcfb4a4 Mon Sep 17 00:00:00 2001 From: teahubxyz Date: Fri, 23 Oct 2026 20:26:50 +0000 Subject: [PATCH] Sphere explorer: stop leaking GPU memory on every rebuild; render only when needed Every slider move rebuilt all lines without disposing the old geometries and materials, and the render loop ran at full rate even when idle or hidden. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01161aC97vUnBnyZRBGyJeHy --- sphere/index.html | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sphere/index.html b/sphere/index.html index 2dc517c..2ecd366 100644 --- a/sphere/index.html +++ b/sphere/index.html @@ -98,7 +98,7 @@ function toPlane([x,y]){return new THREE.Vector3(x*lift,-1.001,y*lift)} const W=()=>innerWidth,H=()=>innerHeight; const renderer=new THREE.WebGLRenderer({antialias:true,alpha:false}); -renderer.setPixelRatio(Math.min(devicePixelRatio,2));renderer.setClearColor(new THREE.Color(css('--bg'))); +renderer.setPixelRatio(Math.min(devicePixelRatio,1.5));renderer.setClearColor(new THREE.Color(css('--bg'))); document.getElementById('stage').appendChild(renderer.domElement); const scene=new THREE.Scene(); const cam=new THREE.PerspectiveCamera(40,1,0.01,100);cam.position.set(2.6,-2.4,3.2); @@ -117,8 +117,11 @@ const invP=([x,y])=>{const r=x*x+y*y;return r<1e-12?[1e6,0]:[x/r,y/r]}; const trisDense=T.map(([lx,by,ay,rx,ty])=>{const A=P(lx,by),B=P(150,ay),Cc=P(rx,by);return{up:!!ty,pts:[...seg(A,B,600),...seg(B,Cc,600).slice(1),...seg(Cc,A,600).slice(1)]}}); const bindu2=new THREE.Mesh(new THREE.SphereGeometry(.022,16,12),new THREE.MeshBasicMaterial({color:C.bindu}));scene.add(bindu2); -function build(){ - group.clear();planeG.clear(); +const drop=g=>{g.traverse(o=>{if(o.geometry)o.geometry.dispose();if(o.material)o.material.dispose()});g.clear()}; +let pending=false; +function build(){if(pending)return;pending=true;requestAnimationFrame(()=>{pending=false;rebuild()})} +function rebuild(){ + drop(group);drop(planeG); const mk=(pts,col,op,g,f)=>g.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts.map(f)),new THREE.LineBasicMaterial({color:col,transparent:op<1,opacity:op}))); tris.forEach(t=>mk(t.pts,t.up?C.up:C.down,1,group,toSphere)); decor.forEach(d=>mk(d,C.fg,.45,group,toSphere)); @@ -142,7 +145,7 @@ function resize(){renderer.setSize(W(),H());cam.aspect=W()/H();cam.updateProject addEventListener('resize',resize);resize();build(); const reduce=matchMedia('(prefers-reduced-motion: reduce)').matches; if(reduce){ctl.autoRotate=false;document.getElementById('t-spin').setAttribute('aria-pressed','false')} -(function loop(){requestAnimationFrame(loop);ctl.update();renderer.render(scene,cam)})(); +(function loop(){requestAnimationFrame(loop);if(document.hidden)return;ctl.update();renderer.render(scene,cam)})(); const $=id=>document.getElementById(id); function setMode(m){mode=m;$('m-stereo').setAttribute('aria-pressed',m==='stereo');$('m-gnomo').setAttribute('aria-pressed',m==='gnomo');build()}