如何用lil gui结合THREE.js调整2D圆形的大小?
问题修复:通过lil-gui滑块修改Three.js圆形大小
核心问题分析
你的代码存在两个关键问题导致圆形大小无法更新:
- 作用域问题:
renderer、scene、camera、geometry等变量如果是局部声明,changeRadius函数无法访问到; - 顶点数据未同步到现有几何体:你在
changeRadius里重新生成了顶点数组,但没有将新数据同步到已添加到场景的BufferGeometry,也未标记几何体需要更新,Three.js不会自动刷新GPU中的数据。
修正后的完整代码
1. 全局/可访问变量声明
确保关键变量在changeRadius能访问的作用域内:
let radius = 0.6; let geometry; let lineStrip; let scene, camera, renderer;
2. 场景与圆形初始化
补全基础环境初始化,并将圆形添加到场景:
// 初始化Three.js基础环境 scene = new THREE.Scene(); camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); initGUI(); // 生成初始圆形顶点 let vertices = []; for(let i = 0; i <= 360; i++){ vertices.push(new THREE.Vector3( Math.sin(i*(Math.PI/180))*radius, Math.cos(i*(Math.PI/180))*radius, 0 )); } geometry = new THREE.BufferGeometry().setFromPoints(vertices); const material = new THREE.LineBasicMaterial({color:"blue"}); lineStrip = new THREE.Line(geometry, material); scene.add(lineStrip); // 必须将线条添加到场景才能渲染 // 初始渲染 renderer.render(scene, camera);
3. GUI与changeRadius函数修改
直接更新现有几何体的顶点数据,并标记更新:
function initGUI() { const controls = { radius: 0.6 }; const gui = new lil.GUI(); // 确保已引入lil-gui库 gui.add(controls, 'radius', 0.1, 0.7).onChange(changeRadius); gui.open(); }; function changeRadius(value) { radius = value; // 获取几何体的位置属性,直接修改顶点数据 const positionAttr = geometry.attributes.position; for(let i = 0; i <= 360; i++){ const x = Math.sin(i*(Math.PI/180))*radius; const y = Math.cos(i*(Math.PI/180))*radius; positionAttr.setXYZ(i, x, y, 0); } // 标记位置属性需要更新,触发Three.js重新上传数据到GPU positionAttr.needsUpdate = true; // 重新渲染场景 renderer.render(scene, camera); }
关键修复点说明
- 复用几何体:直接修改已有
geometry的顶点属性,比重新创建几何体更高效; - 标记属性更新:修改顶点数据后必须设置
positionAttribute.needsUpdate = true,否则Three.js无法感知数据变化; - 作用域保障:所有需要在回调中访问的变量,需在全局或闭包范围内声明;
- 添加物体到场景:不要忘记将
lineStrip添加到scene,否则初始状态也无法看到圆形。
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

