使用geometry.needsUpdate无法更新THREE.LineSegments的问题求助
解决Three.js LineSegments无法更新的问题
你的问题出在两个核心点上:
BufferAttribute不会自动同步原数组
创建new THREE.Float32BufferAttribute(side, 3)时,Three.js会基于side数组生成一个独立的Float32Array副本并上传到GPU。后续修改原side数组完全不会影响几何体内存中的顶点数据——控制台打印的side数值变化只是前端数组的修改,GPU里的渲染数据根本没更新。错误使用
needsUpdate
你设置的geometry.needsUpdate = true无效,正确的做法是标记对应顶点属性的needsUpdate,也就是geometry.attributes.position.needsUpdate = true,这样Three.js才会触发GPU数据的重新上传。
修改后的代码
直接操作BufferAttribute的数组,同时在数据更新后标记需要同步:
import './style.css' import * as THREE from 'three' const canvas = document.querySelector('canvas.webgl') const width = canvas.offsetWidth, height = canvas.offsetHeight; const renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true }); renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1); renderer.setSize(width, height); renderer.setClearColor(0x000000); const scene = new THREE.Scene() scene.background = new THREE.Color(0x21282a); const camera = new THREE.PerspectiveCamera(75, width / height) camera.position.z = 3 scene.add(camera) const material = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 直接创建几何并保存position属性引用 const geometry = new THREE.BufferGeometry(); const positionAttribute = new THREE.Float32BufferAttribute([0, 0, 0, 0, 1, 0], 3); geometry.setAttribute('position', positionAttribute); const segments = new THREE.LineSegments(geometry, material); scene.add(segments); let i = 0 function moveLine() { TweenMax.to({}, 4, { onUpdate: function () { // 直接操作GPU对应的顶点数组 const posArray = positionAttribute.array; if (i === 0){ posArray[0] = 0; posArray[1] = 0; posArray[2] = 0; posArray[3] = 0; posArray[4] = 1; posArray[5] = 0; i++ } else if (i === 1){ posArray[0] = 0; posArray[1] = 1; posArray[2] = 0; posArray[3] = 1; posArray[4] = 1; posArray[5] = 0; i++ } else if (i === 2){ posArray[0] = 1; posArray[1] = 1; posArray[2] = 0; posArray[3] = 1; posArray[4] = 0; posArray[5] = 0; i++ } else if (i === 3){ posArray[0] = 1; posArray[1] = 0; posArray[2] = 0; posArray[3] = 0; posArray[4] = 0; posArray[5] = 0; i=0 } // 修改后标记属性需要更新 positionAttribute.needsUpdate = true; } }); } moveLine() const render = () => { renderer.render(scene, camera); } TweenMax.ticker.addEventListener("tick", render);
额外说明
- 不需要在render循环中重复设置
needsUpdate,只需要在数据修改完成后设置一次即可。 - 后续动态修改顶点数据时,始终直接操作
positionAttribute.array,才能确保GPU拿到最新的渲染数据。
内容的提问来源于stack exchange,提问作者cannon303
相关产品推荐
相关产品推荐

