经纬志
首页 / three.js / API 文档

Frustum

先看结论

视锥体。由六个平面围出的可见空间,用来快速判断物体是否可能出现在屏幕上, 是渲染前剔除的核心数据结构。

最后验证 2026-11-03 · three.js 0.160.0 · 更新 2026-10-29 · 引用本文
new THREE.Frustum(p0, p1, p2, p3, p4, p5)

构造参数

参数说明
p0 … p5六个 Plane,依次为左、右、下、上、近、远

通常不手工传入六个平面,而是从相机矩阵一次性生成。

属性

属性说明
planes六个平面组成的数组
isFrustum恒为 true

方法

方法说明
setFromProjectionMatrix(matrix)由投影矩阵或「投影 × 视图」矩阵生成六个平面
intersectsObject(object)对象的包围球是否与视锥相交
intersectsSprite(sprite)精灵的包围球是否相交
intersectsBox(box)包围盒是否相交
intersectsSphere(sphere)包围球是否相交
containsPoint(point)点是否在视锥内部
clone() / copy(frustum)复制

示例:手动剔除

const frustum = new THREE.Frustum();
const matrix = new THREE.Matrix4();

function cullVisible(camera, objects) {
  matrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
  frustum.setFromProjectionMatrix(matrix);

  return objects.filter(function (obj) {
    return frustum.intersectsObject(obj);
  });
}

// 每帧或在相机移动后调用
const visible = cullVisible(camera, scene.children);

判定是保守的

intersectsObject 用的是对象的包围球,不是真实几何。 球体与视锥相交时对象就算可见,哪怕实际形状在屏幕外。 这种保守策略只会多画、不会漏画,不会造成物体突然消失。 反过来,包围球算错(例如修改顶点后没重算)才会出现漏画。

相机矩阵的时机

投影矩阵在相机参数(fov、near、far、aspect)变化时才更新, 视图矩阵每次移动都会变。matrixWorldInverse 要等 camera.updateMatrixWorld() 之后才是最新值。 渲染循环里 three.js 会自动更新,手动调用时顺序不能颠倒。

自定义渲染很依赖这一步。用 renderer.render 时 three.js 已内置剔除,不需要自己算视锥;但自己写通道、 做实例化批处理、实现 LOD 时,这层判断能省掉大量无效绘制。

引用本文

经纬志(2026)。《Frustum》。https://www.jingweizhi.com/three/api/frustum.html(访问日期 2026-11-03)。