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

Three.js:如何检测Mesh的单次渲染完成?

检测Three.js单个Mesh渲染完成的可行方法

针对你遇到的onBeforeRender/onAfterRender因多材质、requestAnimationFrame持续重复触发,无法判断单个Mesh渲染完成的问题,以下是几种可行的解决方法:

方法一:单次触发标记法

给Mesh添加自定义状态标记,首次触发onAfterRender时执行逻辑并移除回调,避免重复触发:

scene.add(mesh);
render();

// 标记Mesh未完成首次渲染
mesh._hasRendered = false;

mesh.onAfterRender = function(renderer, scene) {
  if (!this._hasRendered) {
    // 此处编写Mesh渲染完成后的处理逻辑
    console.log('该Mesh首次渲染完成');
    this._hasRendered = true;
    // 移除回调,防止重复触发
    this.onAfterRender = null;
  }
};

方法二:多材质计数法

如果Mesh使用了多个材质,每个材质会单独触发一次onAfterRender,可以通过计数匹配材质总数来判定完成:

scene.add(mesh);
render();

// 获取Mesh的材质总数
const totalMaterials = Array.isArray(mesh.material) ? mesh.material.length : 1;
let renderedMaterialCount = 0;

mesh.onAfterRender = function(renderer, scene) {
  renderedMaterialCount++;
  if (renderedMaterialCount === totalMaterials) {
    // 所有材质均已渲染完成,执行逻辑
    console.log('该Mesh所有材质渲染完成');
    this.onAfterRender = null;
  }
};

方法三:帧延迟检查法

利用WebGL渲染的异步特性,在render()调用后通过requestAnimationFrame延迟一帧检查,适合静态场景或需要停止持续渲染的情况:

scene.add(mesh);
render();

let isMeshRendered = false;

function handleRenderComplete() {
  if (!isMeshRendered) {
    console.log('Mesh渲染完成');
    isMeshRendered = true;
    // 若无需持续渲染,可停止动画循环
    renderer.setAnimationLoop(null);
  }
}

// 延迟一帧确保渲染操作已完成
requestAnimationFrame(handleRenderComplete);

// 若为动态持续渲染场景,保留动画循环并在帧内检查
renderer.setAnimationLoop(() => {
  render();
  handleRenderComplete();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 17:55:15