基于管理器的架构 (Manager-based Architecture)
App 模块实现了一种 基于管理器的架构,其中 App 类作为一个轻量级的协调器。职责被分离到专门的管理器中,分别处理特定领域:数据管理、文件加载、渲染、动画和用户交互。这种设计提高了模块化程度、可测试性和可扩展性,适用于混合静态和 ONNX 驱动的高斯点 (Splat) 场景。
高层布局
┌────────────────────────────────────────────────────────────┐
│ 表示层 (Presentation layer) │
│ UIController ◄───► DOMElements ◄───► Canvas/Events │
└───────────────▲────────────────────────────────────────────┘
│ 回调 (callbacks)
┌───────────────┴────────────────────────────────────────────┐
│ 应用层 (Application layer) │
│ App (协调器) │
│ - initWebGPU_onnx() │
│ - 创建 GaussianRenderer │
│ - 连接管理器 & 启动 RenderLoop │
└───────────────┬────────────────────────────────────────────┘
│ 拥有 (owns)
┌───────────────┴────────────────────────────────────────────┐
│ 管理器层 (Manager layer) │
│ ModelManager FileLoader ONNXManager │
│ CameraManager AnimationManager RenderLoop │
└───────────────┬────────────────────────────────────────────┘
│ 使用 (uses)
┌───────────────┴────────────────────────────────────────────┐
│ 核心子系统 (Core subsystems) │
│ PointCloud / DynamicPointCloud • GaussianRenderer │
│ Preprocess (SH/RGB) • GPURSSorter │
└────────────────────────────────────────────────────────────┘
关键设计原则
- 关注点分离 (Separation of Concerns): 每个管理器处理特定领域(模型、文件、相机、动画、渲染)。
- 外观模式 (Facade Pattern): App 类提供简单的公共 API,同时委托给管理器处理。
- 多模型支持:
ModelManager支持并发模型(PLY, SPZ, KSplat, SPLAT, SOG, ONNX, FBX)。 - 格式无关: 使用 IO 模块中的
defaultLoader进行统一格式处理。 - ORT 集成: 与 ONNX Runtime 共享 WebGPU 设备,以实现高效的 GPU 使用。
- 渲染循环所有权:
RenderLoop封装 RAF 生命周期;App 仅负责启动和监控它。 - 动态内容: ONNX 集成仅在 GPU 上运行,使用共享设备——无需 CPU 回读。
职责快速参考
| 管理器 | 职责 | 关键特性 |
|---|---|---|
| App | 协调、依赖注入、UI 回调界面 | 公共 API 外观、初始化协调 |
| ModelManager | 元数据存储、可见性过滤、模型跟踪 | ModelEntry 管理、ID 生成、容量限制 |
| FileLoader | 统一资源摄入 | 支持 PLY, SPZ, KSplat, SPLAT, SOG, compressed PLY, FBX |
| ONNXManager | ONNX 模型生命周期 | 设备共享、会话管理、动态生成器 |
| CameraManager | 相机和控制器管理 | Orbit/FPS 切换、自动取景、调整大小处理 |
| AnimationManager | 动态内容更新 | 每帧更新、节流、性能跟踪 |
| RenderLoop | 帧周期协调 | RAF 循环、FPS 计数、渲染管线、状态管理 |
初始化流程
- DOM 验证 - 通过
DOMElements查询并缓存 DOM 元素 - 管理器创建 - 实例化所有管理器 (Model, File, ONNX, Camera, Animation, RenderLoop)
- ORT 环境 - 使用 WASM 路径初始化 ONNX Runtime 环境
- WebGPU 上下文 - 通过
initWebGPU_onnx获取共享 WebGPU 设备 (带回退机制) - 渲染器设置 - 实例化
GaussianRenderer并确保排序器准备就绪 - 相机初始化 - 初始化透视相机和默认控制器 (FPS)
- UI 绑定 - 通过
UIController绑定事件监听器 - 调整大小处理 - 设置窗口调整大小处理程序
- 渲染循环配置 - 使用 GPU 上下文和回调初始化 RenderLoop
- 启动循环 - 开始动画帧循环
事件与数据流
示例流程
文件加载 (高斯格式):
File dropped → UIController.onFileLoad → App.loadFile →
App.loadGaussianModel → FileLoader.loadFile →
defaultLoader (IO module) → PointCloud creation →
ModelManager.addModel → RenderLoop renders
ONNX 模型加载:
App.loadONNXModel → ONNXManager.loadONNXModel →
ONNXGenerator creation → DynamicPointCloud creation →
ModelManager.addModel → AnimationManager tracks →
RenderLoop updates per-frame → Renderer renders
相机控制:
UI button click → UIController.onControllerSwitch →
App.switchController → CameraManager.switchController →
Controller update → RenderLoop uses new camera matrix
动态动画:
App.controlDynamicAnimation → AnimationManager.controlDynamicAnimation →
RenderLoop.updateDynamicPointClouds → DynamicPointCloud.update →
ONNX inference → GPU buffer update → Renderer renders
WebGPU 上下文共享
initWebGPU_onnx() 实现了两阶段初始化:
- ORT 集成尝试: 尝试复用 ONNX Runtime 设备 (可选择使用虚拟模型强制创建)
- 回退: 如果 ORT 集成失败,回退到独立的 WebGPU 初始化
优势
- 单一设备: ONNX 推理和渲染都使用同一个 GPU 设备
- 资源效率: 共享设备减少内存开销
- 特性一致性: 请求的限制和特性 (
shader-f16, 时间戳查询) 仅应用一次 - 缓冲区兼容性: 没有隐藏设备,消除了缓冲区兼容性问题
- 优雅降级: 即使 ORT 集成失败,回退机制也能确保应用正常工作
配置选项
interface WebGPUInitOptions {
preferShareWithOrt?: boolean; // 首选 ORT 设备共享
dummyModelUrl?: string | null; // 强制创建 ORT 设备
adapterPowerPreference?: 'high-performance' | 'low-power';
allowOwnDeviceWhenOrtPresent?: boolean; // 允许独立设备
}
渲染循环所有权
RenderLoop 拥有整个帧周期:
- 调度:
requestAnimationFrame生命周期管理 - 计时: Delta time 计算和 FPS 计数
- 状态: 背景颜色、高斯缩放、渲染状态
- 协调: 每帧调用管理器和渲染器
帧周期
每一帧按顺序执行:
- 计算 Delta Time -
dt = currentTime - lastTime - 相机更新 -
CameraManager.update(dt) - 动态更新 -
AnimationManager.updateDynamicPointClouds(view, proj, time) - FPS 计数 - 更新内部计数器
- 渲染 -
GaussianRenderer.prepareMulti(...)/renderMulti(...) - 回调调用 - FPS 和点数回调
App 公共 API
App 暴露了委托给管理器的对测试友好的辅助方法:
模型管理:
getModels()- 获取简化模型信息getModelWithPointCloud(type, id?)- 获取完整模型条目getFullModels()- 获取所有模型条目
加载:
loadGaussian(input, options?)- 加载任何高斯格式loadSPZ(input, options?)- 加载 SPZ 格式loadKSplat(input, options?)- 加载 KSplat 格式loadSplat(input, options?)- 加载 SPLAT 格式loadSOG(input, options?)- 加载 SOG 格式loadONNXModel(path, name?, staticInference?)- 加载 ONNX 模型
相机:
resetCamera()- 重置到默认位置switchController('orbit'|'fps')- 切换相机模式getCameraMatrix()- 获取当前视图矩阵getProjectionMatrix()- 获取当前投影矩阵
渲染:
setGaussianScale(scale)- 设置高斯点大小getGaussianScale()- 获取当前缩放比例setBackgroundColor(color)- 设置背景 RGBAgetBackgroundColor()- 获取当前背景
动画:
controlDynamicAnimation(action, speed?)- 控制动态模型setDynamicAnimationTime(time)- 设置动画时间getDynamicPerformanceStats()- 获取性能指标
诊断与调试
调试信息
App.getDebugInfo() 聚合了来自所有管理器的综合状态:
{
app: {
initialized: boolean,
canvas: { width, height },
supportedFormats: { gaussian, onnx, models, all }
},
models: {
count: number,
capacity: number,
totalPoints: number,
visiblePoints: number
},
camera: CameraManager.getDebugInfo(),
animation: AnimationManager.getDebugInfo(),
renderLoop: RenderLoop.getDebugInfo(),
onnx: {
hasModels: boolean,
modelCount: number,
performanceStats: object
}
}
管理器访问
对于高级用法,可以直接访问管理器:
app.getModelManager()- 直接访问 ModelManagerapp.getONNXManager()- 直接访问 ONNXManagerapp.getCameraManager()- 直接访问 CameraManagerapp.getAnimationManager()- 直接访问 AnimationManagerapp.getRenderLoop()- 直接访问 RenderLoop
格式支持
App.getSupportedFormats() 返回所有支持的文件扩展名:
{
gaussian: ['.ply', '.spz', '.ksplat', '.splat', '.sog', '.compressed.ply'],
onnx: ['.onnx'],
models: ['.gltf', '.glb', '.obj', '.fbx', '.stl'],
all: [...all extensions]
}
性能监控
RenderLoop.getPerformanceInfo()- 实时 FPS 和帧时间AnimationManager.getDynamicPerformanceStats()- ONNX 推理指标ONNXManager.getONNXPerformanceStats()- 生成器和点云计数
管理器架构提高了模块化程度、可测试性,并增强了混合静态和 ONNX 驱动的高斯点场景的可扩展性。