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

如何获取ThreeJS mesh对象可见区域的像素级宽度与高度

解决方案

现有代码问题

你当前的实现逻辑存在错误:project()方法是用于将3D空间中的单个坐标点转换到裁剪空间,直接对包围盒的尺寸向量做投影,既没有考虑物体的旋转、空间位置对投影结果的影响,也无法覆盖包围盒所有顶点的投影范围,最终得到的数值是不准确的。

实现方案

方案1:计算物体包围盒在视口的投影像素尺寸(不考虑遮挡)

如果不需要排除其他物体遮挡的区域,只需要计算物体整体在视口上占据的像素范围,可以遍历包围盒的8个顶点逐一投影,再取投影点的极值计算宽高:

getObjectSizeInViewSpace(object) {
  // 1. 计算物体世界空间包围盒
  const box = new THREE.Box3().setFromObject(object);
  const vertices = [
    new THREE.Vector3(box.min.x, box.min.y, box.min.z),
    new THREE.Vector3(box.min.x, box.min.y, box.max.z),
    new THREE.Vector3(box.min.x, box.max.y, box.min.z),
    new THREE.Vector3(box.min.x, box.max.y, box.max.z),
    new THREE.Vector3(box.max.x, box.min.y, box.min.z),
    new THREE.Vector3(box.max.x, box.min.y, box.max.z),
    new THREE.Vector3(box.max.x, box.max.y, box.min.z),
    new THREE.Vector3(box.max.x, box.max.y, box.max.z),
  ];

  // 2. 把所有顶点投影到屏幕空间
  const projectedVertices = vertices.map(v => {
    v.project(this.camera);
    // 转换为canvas像素坐标,以左上角为原点
    const x = (v.x + 1) * window.innerWidth / 2;
    const y = (-v.y + 1) * window.innerHeight / 2;
    return {x, y};
  });

  // 3. 计算投影点的极值
  const minX = Math.min(...projectedVertices.map(p => p.x));
  const maxX = Math.max(...projectedVertices.map(p => p.x));
  const minY = Math.min(...projectedVertices.map(p => p.y));
  const maxY = Math.max(...projectedVertices.map(p => p.y));

  // 4. 返回宽高,物体完全在视口外时会得到0,可按需扩展边界校验逻辑
  return new THREE.Vector2(
    Math.max(0, maxX - minX),
    Math.max(0, maxY - minY)
  );
}

注意:如果你的canvas没有占满整个窗口,需要把代码中的window.innerWidth、window.innerHeight替换为canvas元素的clientWidth、clientHeight。

方案2:计算物体实际可见区域的像素尺寸(排除遮挡)

如果需要精确统计没有被其他物体遮挡的可见区域的大小,需要借助离屏渲染实现:

  1. 创建一个和当前画布尺寸一致的WebGLRenderTarget离屏渲染目标
  2. 临时把目标mesh替换为唯一的纯色材质(比如纯红色#ff0000),场景内其他所有物体替换为黑色材质
  3. 把场景渲染到离屏渲染目标上
  4. 读取渲染结果的像素数据,统计非黑色像素的范围,即可得到可见区域的像素宽高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:48:02