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

ThreeJS中onBeforeRender回调无法正确更新对象几何体的问题

问题:Three.js中onBeforeRender回调内更新物体缩放未达到预期效果

基于Three.js的THREE.Mesh扩展了Test类,想要实现相机缩放时物体大小固定的效果,给类添加了update方法通过修改scale抵消相机缩放的影响。但发现只有在render函数渲染前调用update才能生效,在onBeforeRender回调中调用会得到异常结果。

问题原因

当onBeforeRender回调触发时,Three.js的渲染流程已经完成了**模型视图矩阵(ModelViewMatrix)**的计算。此时修改物体的scale属性,不会触发矩阵的重新计算,当前帧渲染会沿用旧矩阵,导致缩放修改无法生效。而在renderer.render()调用前执行update,修改scale后,Three.js会在渲染流程中重新计算物体的模型矩阵,确保修改被正确应用。

解决方案

方案1:手动触发矩阵更新

在update方法末尾添加矩阵更新标记,强制Three.js重新计算矩阵:

update(zoom) {
  this.scale.x = width / zoom
  this.scale.y = height / zoom
  // 强制更新矩阵,确保修改生效
  this.matrixWorldNeedsUpdate = true;
}

这样即使在onBeforeRender中调用update,修改后的缩放也会触发矩阵重新计算,渲染时使用最新的矩阵数据。

方案2:保持在render前调用update(原有效方案)

继续沿用在render函数中renderer.render()之前调用test.update(camera.zoom)的方式,确保渲染前完成所有属性修改,让Three.js的默认渲染流程自动处理矩阵计算。

额外优化建议

对于正交相机下的“物体大小固定”需求,还可以直接通过修改相机的投影参数实现,不需要修改物体缩放:

function updateCamera(camera, width, height) {
  const k = 0.5 / camera.zoom; // 加入zoom抵消逻辑
  camera.left = -k * width
  camera.right = k * width
  camera.top = k * height
  camera.bottom = -k * height
  camera.updateProjectionMatrix()
}

这种方式不需要额外维护物体的scale,逻辑更简洁,也避免了矩阵更新的额外开销。

内容的提问来源于stack exchange,提问作者Pavel Yakovlev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:17:55