3. 渲染管线 (Rendering Pipeline)
Visionary 采用混合渲染管线 (Hybrid Rendering Pipeline)。由于 Gaussian Splatting 使用自定义的基于计算着色器(Compute Shader)的光栅化技术,它无法直接利用 Three.js 的标准 renderer.render 进行绘制。
因此,Visionary 引入了 GaussianThreeJSRenderer 类作为渲染协调器,专门负责管理标准 3D 物体与高斯粒子的深度混合和遮挡关系。
3.1 渲染器初始化
在使用渲染管线前,需确保 WebGPU 环境与 Three.js 上下文正确桥接。
import { initThreeContext } from 'src/app/three-context';
// 初始化包含 WebGPU 适配器配置的渲染器
// 注意:内部会加载一个 dummy ONNX 模型以激活 ORT 的 WebGPU 后端
const renderer = await initThreeContext(canvasElement);
// 默认配置:
// - antialias: true
// - powerPreference: 'high-performance'
// - pixelRatio: Math.min(window.devicePixelRatio, 2)
3.2 混合渲染循环 (The Mixed Loop)
为了正确处理 Mesh 遮挡 Splats,必须严格按照以下顺序调用 API。
循环逻辑详解
function animate() {
const currentTime = (Date.now() - startTime) / 1000.0;
// 1. 更新 4D 动态模型 (Update)
// 计算当前时间点的粒子变形。这是一个异步操作(含 await),但在循环中通常不阻塞。
// 内部会自动处理相机的 View/Projection 矩阵转换。
gaussianRenderer.updateDynamicModels(camera, currentTime);
// 2. 渲染背景与标准 Mesh (Scene Pass):
// a. 渲染标准 Three.js 场景到 sceneDepthRT (包含 Color 和 Depth)。
// b. 捕获深度缓冲区 (Depth Buffer),供高斯光栅化器使用。
// c. 将渲染结果 Blit (拷贝) 到屏幕 Canvas。
gaussianRenderer.renderThreeScene(camera);
// 3. 绘制高斯粒子 (Splatting Pass):
// a. 读取步骤 2 生成的 Depth Buffer,实现 Mesh 对 Splats 的遮挡。
// b. 执行高斯光栅化,叠加在屏幕 Canvas 上。
gaussianRenderer.drawSplats(renderer, scene, camera);
}
3.3 核心类:GaussianThreeJSRenderer
该类管理着所有与 WebGPU 光栅化器交互的逻辑。
构造函数
import { GaussianThreeJSRenderer } from 'src/app/GaussianThreeJSRenderer';
import { GaussianModel } from 'src/app/GaussianModel';
const gaussianRenderer = new GaussianThreeJSRenderer(
renderer: THREE.WebGPURenderer,
scene: THREE.Scene,
gaussianModels: GaussianModel[]
);
关键方法
| 方法名 | 参数 | 说明 |
|---|---|---|
updateDynamicModels |
(camera: Camera, time?: number) |
更新所有动态(ONNX)模型的顶点状态。 |
renderThreeScene |
(camera: Camera) |
替代标准 renderer.render。它开启了 autoDepthMode,自动捕获全场景深度。 |
drawSplats |
(renderer, scene, camera) |
执行最终的光栅化绘制。返回 boolean 表示是否绘制成功。 |
appendGaussianModel |
(model: GaussianModel) |
动态向渲染管线添加新加载的模型。 |
removeModelById |
(modelId: string) |
移除模型并清理资源。 |
3.4 深度与遮挡 (Auto Depth Mode)
Visionary 默认开启 自动深度模式 (Auto Depth Mode)。
- 原理:
renderThreeScene使用THREE.HalfFloatType(16位浮点) 创建了一个 RenderTarget。渲染标准 Mesh 时,深度信息被写入sceneDepthTexture。 - 交互:
drawSplats在开始 WebGPU RenderPass 时,会将这个深度纹理作为depthStencilAttachment加载(LoadOp: 'load')。 - 效果: 高斯粒子在光栅化时会进行深度测试(Depth Test),从而正确地被标准 Mesh 遮挡(例如:人走到高斯模型生成的墙后面)。
注意: 如果你不使用
renderThreeScene而使用原生的renderer.render,高斯模型将无法感知场景中的 Mesh,导致“透视”现象。
3.5 高斯模型对象 (GaussianModel)
GaussianModel 继承自 THREE.Object3D,这意味着你可以像操作普通 Mesh 一样操作它。
变换同步 (Auto-Sync)
Visionary 实现了变换拦截机制。当你修改位置、旋转或缩放时,数据会自动同步到 GPU。
import { GaussianModel } from 'src/app/GaussianModel';
const model = gaussianModels[0];
// 下列操作会自动触发 syncTransformToGPU,无需手动更新
model.position.set(10, 0, 0);
model.rotation.y += 0.1;
model.scale.setScalar(2.0);
常用控制 API
import { GaussianModel } from 'src/app/GaussianModel';
// 调整粒子大小 (不改变模型缩放,只改变 splat 半径)
model.setGaussianScale(1.5);
// 调整透明度
model.setOpacityScale(0.8);
// 裁剪阈值 (优化性能)
model.setCutoffScale(0.5);
// 动画控制
model.startAnimation(1.0); // 1.0x 速度播放
model.setAnimationTime(2.5); // 跳转到 2.5秒
模块索引
- App 模块 (01-app) – 3.1 节使用的
initThreeContext、渲染循环管理等均来自该模块,详见 概览 与 架构。 - Three.js Integration 模块 (12-three-integration) – 贯穿 3.2~3.4 的
GaussianThreeJSRenderer、混合渲染/自动深度逻辑由此模块提供,可参考 概览 与 API 文档。 - Models 模块 (16-models) – 3.5 节的
GaussianModel及其控制 API 源于该模块,参阅 概览 与 API 文档。 - ONNX 模块 (13-onnx) – 3.2、3.3 中的
updateDynamicModels、4D 动态推理依赖 ONNX 模块,详情见 概览 与 架构。