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

如何在Babylon.js中每次渲染前创建新网格?附示例代码

在Babylon.js中每次渲染前创建新Mesh的实现方案

我明白你想要在每次渲染操作前生成新的Mesh,这在做动态效果演示或测试场景时会很实用。下面我会基于你给出的代码框架,帮你实现完整功能,同时解决内存泄漏的问题。

完整实现代码

let canvas, engine, camera, scene;
// 用来存储当前的Mesh,方便后续销毁释放资源
let currentMesh = null;

function initEngine(){
  canvas = document.getElementById("renderCanvas");
  engine = new BABYLON.Engine(canvas, true);
}

function createScene(){
  initEngine();
  scene = new BABYLON.Scene(engine);
  scene.clearColor = new BABYLON.Color4(0.1, 0.1, 0.1, 1);

  // 创建可交互的弧旋转相机
  camera = new BABYLON.ArcRotateCamera("camera", Math.PI / 2, Math.PI / 2, 4, BABYLON.Vector3.Zero(), scene);
  camera.attachControl(canvas, true);
  camera.lowerRadiusLimit = 2; // 限制相机最近距离,避免穿模
  camera.upperRadiusLimit = 10; // 限制相机最远距离

  // 添加半球光源
  const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
  light.intensity = 0.7;

  // 监听「每一帧渲染前」的事件
  scene.onBeforeRenderObservable.add(() => {
    // 先销毁旧Mesh(如果存在),必须调用dispose彻底释放资源
    if (currentMesh) {
      currentMesh.dispose();
      currentMesh = null;
    }

    // 创建新Mesh - 示例用随机形状,你可以替换成自己需要的Mesh类型
    const randomShape = Math.floor(Math.random() * 3);
    switch(randomShape) {
      case 0:
        currentMesh = BABYLON.MeshBuilder.CreateBox("box", {size: 1}, scene);
        break;
      case 1:
        currentMesh = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 1}, scene);
        break;
      case 2:
        currentMesh = BABYLON.MeshBuilder.CreateCylinder("cylinder", {height: 1, diameter: 1}, scene);
        break;
    }

    // 为新Mesh设置随机位置和颜色,直观展示每次渲染的变化
    currentMesh.position = new BABYLON.Vector3(
      (Math.random() - 0.5) * 2,
      (Math.random() - 0.5) * 2,
      (Math.random() - 0.5) * 2
    );
    currentMesh.material = new BABYLON.StandardMaterial(`mat-${Date.now()}`, scene);
    currentMesh.material.diffuseColor = new BABYLON.Color3(
      Math.random(),
      Math.random(),
      Math.random()
    );
  });

  // 启动渲染循环
  engine.runRenderLoop(() => {
    scene.render();
  });

  // 处理窗口大小变化
  window.addEventListener("resize", () => {
    engine.resize();
  });
}

// 初始化整个场景
createScene();

关键细节说明

  • scene.onBeforeRenderObservable:这是Babylon.js专门用来监听「每一帧渲染前」的事件,完美契合你“每次渲染操作前创建新Mesh”的需求,比直接在渲染循环里写代码更符合框架的事件机制。
  • 销毁旧Mesh:每次创建新Mesh前调用currentMesh.dispose()非常重要,它会彻底移除旧Mesh并释放其占用的内存、材质等资源,避免内存泄漏。
  • 自定义Mesh逻辑:示例里用了随机形状、位置和颜色,你可以把这部分替换成你自己需要的Mesh创建代码,比如固定的模型、特定的位置或材质。

性能优化提示

如果你的场景运行在60帧/秒的设备上,这段代码每秒会创建并销毁60个Mesh。如果你的Mesh比较复杂(比如高多边形模型),可能会有性能压力。这种情况下,你可以改成每隔N帧创建一次,比如:

let frameCount = 0;
scene.onBeforeRenderObservable.add(() => {
  frameCount++;
  // 每10帧创建一次新Mesh,降低频率
  if (frameCount % 10 !== 0) return;

  // 销毁旧Mesh + 创建新Mesh的代码...
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:17:55