Three.js正确集成cannon-es物理模拟教程

作者:技术拾光

时间:2026-07-12

浏览:470

在Three.js中集成cannon-es需注意:避免混用旧版cannon.js;importmap应指向ESM格式的cannon-es;物理世界需显式调用step()并控制步长;手动同步刚体与网格的位置和旋转;静态物体设mass:0;若白屏,检查控制台报错及网络加载状态。

在现代 Web 项目中整合物理引擎与 Three.js 场景,听起来极具吸引力,但实际操作中常会遇到不少问题。最典型的失败场景是页面白屏,控制台报错 ReferenceError: CANNON is not defined 或 Cannot instantiate cyclic dependency,有时甚至没有任何提示,页面直接空白。遇到这种情况,不必急于怀疑代码逻辑——问题通常出在物理引擎的引入方式上。

初学者容易犯的错误清单大致包括以下几种:

  • 混用已停止维护的旧版 cannon.js 及其现代替代品 cannon-es(后者使用 TypeScript 重写,原生支持 ES Module);
  • 在

    运行这段代码,你会看到一个绿色立方体从空中落到灰色地面,带有轻微弹性弹跳,最终静止。如果依然出现白屏,不必慌张——多半是以下某个细节未注意到。

    关键注意事项总结

    切勿混用 cannon.js 与 cannon-es。前者为 CommonJS/UMD 打包的旧版,后者是纯 ESM 的现代版本。cannon-es 是目前社区推荐的替代品,功能更全面且维护活跃。一旦混合使用,import 解析将出现问题。

    importmap 中的 Cannon 地址必须返回一个 .js 文件,且该文件需兼容 ESM。 推荐使用 jsDelivr 或 unpkg 提供的 .min.js 构建版本,它们已预编译为兼容 ESM 的格式。若使用其他链接,很可能导致加载失败。

    物理世界必须显式调用 step()。 Three.js 的渲染帧与物理帧是独立的两套机制。world.step(delta) 是驱动物理演化的唯一入口,遗漏此调用则物体永远不会运动。同时,需控制步长上限,防止卡顿时物理崩溃。示例中使用了 Math.min(clock.getDelta(), 0.1)。

    位置同步不可省略。 CANNON.Body 的 position 和 quaternion 与 THREE.Mesh 对应属性并无自动绑定关系。每次物理更新后,必须手动执行 cubeMesh.position.copy(cubeBody.position) 和 cubeMesh.quaternion.copy(cubeBody.quaternion)。否则你看到的场景仅是个静态模型。

    静态物体请设 mass: 0。 地面、墙壁等不应受重力影响的物体,将质量设为零后它们会变为静态刚体。若不设置,它们会受力移动,导致场景稳定性崩溃。

    调试技巧: 若依然白屏,打开浏览器 DevTools → Console 查看具体报错;再切换到 Network 标签页确认 cannon-es.min.js 是否成功加载(状态码为 200)。加载失败的常见原因包括 CDN 域名被屏蔽或路径书写错误。

    牢记上述要点,你不仅能解决“屏幕变白”的困扰,还能建立起物理引擎与渲染引擎协同工作的清晰认知。这正是构建交互式 3D 应用的重要基础。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›