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

正交投影模式下如何实现点云LoD过滤?

正交投影模式下点云LoD加载内存过高的解决方案

我基于Qt参考Potree实现了点云渲染软件,层级过滤逻辑如下:

  • 将整个点云划分为不同层级的小点云块
  • 执行视锥体剔除,过滤视野外的块
  • 计算每个点云块在屏幕上的投影尺寸,以此判断是否加载对应等级的LoD

但Potree未提供正交投影模式下的解决方案,原代码仅留有TODO注释:

// TODO ortho visibility
let bb = child.getBoundingBox();                
let distance = child.getBoundingSphere().center.distanceTo(camObjPos);
let diagonal = bb.max.clone().sub(bb.min).length();
//weight = diagonal / distance;

weight = diagonal;

问题根源

透视投影模式下,点云呈现近大远小的效果,相机仅为近处物体加载高等级LoD,远处用低等级LoD,内存占用可控。但正交投影中,物体投影到屏幕的尺寸与距离无关——视野内所有可见点云块都会加载高等级LoD,直接导致内存占用过高。

解决办法

针对正交投影特性,重新设计LoD加载判断逻辑即可,核心是基于点云块的屏幕实际像素占比+动态阈值调整,具体实现方向如下:

  1. 计算正交投影下的屏幕像素占比
    正交投影中,屏幕像素与世界空间的对应关系固定,可通过相机正交参数和屏幕分辨率计算点云块的实际屏幕占比:

    • 以Qt为例,先获取相机的正交宽度/高度(QCamera::orthoWidth())和视口宽高
    • 计算点云块包围盒在相机轴向的长度,再换算为屏幕像素数
      示例代码(C++/Qt):
    float orthoWidth = camera->orthoWidth();
    float screenWidth = ui->viewport->width();
    // 点云块包围盒X轴方向长度
    float bbXLen = boundingBox.maximum().x() - boundingBox.minimum().x();
    // 计算该块在屏幕上的像素宽度
    float screenPixelWidth = (bbXLen / orthoWidth) * screenWidth;
    

    用这个screenPixelWidth替代原有的diagonal/distance作为LoD等级判断依据——仅当像素宽度超过设定阈值时,才加载高等级LoD。

  2. 动态调整LoD阈值
    根据当前内存占用和可见块数量自动调整阈值:

    • 内存占用过高时,调高阈值,仅让占比更大的块加载高LoD
    • 内存充足时,调低阈值,提升更多区域的渲染精度
  3. 给焦点区域优先加载高LoD
    正交模式下用户通常聚焦特定区域,可增加鼠标悬浮或视图中心区域的优先级:

    • 焦点区域内的块优先加载高LoD
    • 非焦点区域的块即使可见,也先加载低LoD,待用户聚焦后再升级
  4. 合并小尺寸点云块
    对正交视角下显示极小的点云块,加载时自动合并为大区块,减少Draw Call、降低LoD切换频率,同时节省内存

可视化效果对比

  • 透视模式效果:
    透视模式可视化效果
  • 正交模式效果:
    正交模式可视化效果

内容的提问来源于stack exchange,提问作者MR-DAI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 00:45:00