Three.js 大场景分块加载实战:从全量渲染到可视集调度

文章目录

Three.js 大场景分块加载实战:从全量渲染到可视集调度

很多 Three.js 项目在 Demo 阶段都很流畅,一到真实业务场景就开始掉帧。根因往往不是"Three.js 不行",而是仍在使用全量渲染思路。

本文给出一套可落地的大场景治理方案:分块、裁剪、调度

一、为什么全量渲染会崩

当你把园区、工厂、城市一次性丢进场景,问题会立刻出现:

  • draw call 暴涨
  • 主线程压力高
  • 资源下载、解析、上传集中爆发

用户视角一次只看到部分区域,全量加载本质上是在渲染"看不见的成本"。

二、先做空间分块,而不是业务分层

推荐先按空间切块(Grid/Quadtree),每块维护:

  • 包围盒(AABB)
  • 资源列表(模型、纹理、特效)
  • 当前状态(未加载/加载中/已加载)
js 复制代码
class TileNode {
  constructor(id, aabb, assets) {
    this.id = id;
    this.aabb = aabb;
    this.assets = assets;
    this.state = 'idle';
  }
}

分块后,场景从"一个大对象"变成"可调度的资源单元"。

三、可视集判定:只加载相机附近+可见块

每帧根据相机视锥体和距离,筛出候选块:

js 复制代码
function collectVisibleTiles(camera, tiles) {
  const frustum = new THREE.Frustum();
  const proj = new THREE.Matrix4().multiplyMatrices(
    camera.projectionMatrix,
    camera.matrixWorldInverse
  );
  frustum.setFromProjectionMatrix(proj);

  return tiles.filter(t => frustum.intersectsBox(t.aabb));
}

建议再加距离阈值,避免远处块抢占带宽。

四、加载调度器:限制并发,避免瞬时拥塞

常见错误是可见块一多就并发全开,导致主线程卡死。

工程建议:

  • 维护任务队列
  • 限制并发(如 2~4)
  • 给"近处块"更高优先级
js 复制代码
const MAX_CONCURRENT = 3;
let running = 0;

async function runTask(task) {
  if (running >= MAX_CONCURRENT) return;
  running++;
  try { await task(); } finally { running--; }
}

五、卸载策略:离开视野要及时回收

只加载不卸载,内存必涨。离相机较远且持续不可见的块,应执行:

  • scene.remove
  • geometry/material/texture dispose
  • 从缓存池标记为可回收

结合 LRU 缓存效果更稳:热点区域保留,冷区逐步淘汰。

六、实践顺序(推荐)

  1. 先切块(数据结构)
  2. 再做可视判定
  3. 上调度器(并发控制)
  4. 最后做卸载回收

每一步都可独立验证,风险低、收益明确。

七、结语

Three.js 大场景优化不是"魔改引擎",而是建立资源生命周期管理。

当你把"看见什么、加载什么、离开就回收"跑通后,项目稳定性会明显提升。

相关推荐
不会敲代码13 小时前
手写 Mini React:从 JSX 到虚拟 DOM 再到 render,搞懂 React 底层原理
前端·javascript·react.js
你不是我我4 小时前
【Java 开发日记】HTTP3 性能更好,为什么内网微服务依然多用 HTTP2?HTTP2 内网优势是什么?
java·开发语言·微服务
kyriewen4 小时前
你的代码仓库变成“毛线团”了?Monorepo 用 Turborepo 拆成“乐高积木”
前端·javascript·面试
tjl521314_214 小时前
04C++ 名称空间(Namespace)
开发语言·c++
赏金术士4 小时前
Kotlin 数据流与单双向绑定
android·开发语言·kotlin
逻辑驱动的ken5 小时前
Java高频面试场景题25
java·开发语言·深度学习·面试·职场和发展
openKaka_5 小时前
createRoot 到底创建了什么:FiberRootNode 和 HostRootFiber 的初始化过程
前端·javascript·react.js
AI人工智能+电脑小能手6 小时前
【大白话说Java面试题】【Java基础篇】第32题:Java的异常处理机制是什么
java·开发语言·后端·面试
阿豪只会阿巴7 小时前
【没事学点啥】TurboBlog轻量级个人博客项目——项目介绍
javascript·python·django·html
刀法如飞8 小时前
TypeScript 数组去重的 20 种实现方式,哪一种你还不知道?
前端·javascript·算法