跳转至

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 模块,详情见 概览架构