You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用geometry.needsUpdate无法更新THREE.LineSegments的问题求助

解决Three.js LineSegments无法更新的问题

你的问题出在两个核心点上:

  1. BufferAttribute不会自动同步原数组
    创建new THREE.Float32BufferAttribute(side, 3)时,Three.js会基于side数组生成一个独立的Float32Array副本并上传到GPU。后续修改原side数组完全不会影响几何体内存中的顶点数据——控制台打印的side数值变化只是前端数组的修改,GPU里的渲染数据根本没更新。

  2. 错误使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:15:31