Train, export, render—and defend every step训练、导出、渲染,并解释每一步
After this lesson本课目标Run the repository’s end-to-end exercise and explain how to integrate and profile its Rust/wgpu render pass.跑通仓库端到端练习,说清 Rust/wgpu 渲染通道的接入与性能测量。
You are ready when you can explain a bad image, not only display a good one. This final lesson turns the chain into a reproducible exercise and a debugging conversation.能显示好看的画面还不够,能解释坏画面的原因才算真正掌握。最后一课把整条链变成可复现练习与调试思路。
Build the idea, one step at a time一步步建立理解
Need a math refresher?需要补一点数学基础?
Open only the tool you need; return here to use it in the next step.按需打开一个小工具,再回到本课把它用起来。
Use the repository commands below. The Python exercise creates a synthetic teacher, fits five Gaussians with Adam, evaluates separate synthetic views/times and exports a PLY plus cameras. It needs Python with PyTorch and NumPy. The native Rust example needs a working wgpu adapter. This exercise is distinct from the two-Gaussian browser SGD lab.运行下方仓库命令。Python 练习创建合成教师,用 Adam 拟合五颗 Gaussian,对单独的合成视角与时间评估,并导出 PLY 和相机。需要带 PyTorch、NumPy 的 Python 环境;Rust 原生示例需要可用 wgpu 适配器。它与浏览器双 Gaussian SGD 实验不同。
STEP步骤 2 / 5
Integrate a pass, not a second engine把渲染通道接入引擎
Let the host own device, queue, camera, clock and render targets. The Gaussian pass owns model buffers and its rendering resources. Each frame evaluates visibility/order, updates per-frame camera/time and index data, then encodes a pass into the host’s command flow. The current StgPass is an integration starting point; it is not evidence of a completed integration into another engine repository.设备、队列、相机、时钟与渲染目标由主引擎管理,Gaussian 通道管理模型缓冲与自己的渲染资源。每帧求可见性和顺序,更新相机、时间与索引数据,再把渲染通道编码到主机命令流。当前 StgPass 是接入起点,不等于已经集成到另一个引擎仓库。
STEP步骤 3 / 5
Keep common math separate from backend mechanics分离通用数学与后端机制
Time decoding, coordinate contracts, SH conventions and expected pixel behavior can be shared across backends. Buffer alignment, shader language, synchronization, sorting primitives and render/compute dispatch belong to backend implementation. CUDA compute splatting and wgpu quads can implement related image formation with different scheduling. Matching outputs requires matching approximations as well as formulas.时间解码、坐标契约、SH 约定与像素预期可以跨后端共享。缓冲对齐、着色语言、同步、排序原语及渲染或计算调度由后端实现。CUDA 计算 Splat 与 wgpu 四边形可以实现相关成像,但调度方式不同。对齐输出不仅要对公式,还要对近似。
STEP步骤 4 / 5
Measure the actual bottleneck测出真正瓶颈
Record decode time, CPU visibility/sort time, upload bytes, GPU pass time, resolution and visible splat count. High overlap can dominate fragment work even with a modest point count. Timing an asynchronous API call is not GPU execution time. Use supported timestamp queries or carefully scoped measurement; avoid a blocking readback every frame.记录解码时间、CPU 可见性与排序时间、上传字节数、GPU 通道时间、分辨率与可见点数。即使点数不多,重叠严重也可能使片元工作量很大。异步 API 调用耗时不等于 GPU 执行耗时。使用受支持的时间戳或明确范围的测量,避免每帧阻塞回读。
STEP步骤 5 / 5
Debug in the same order that pixels are made沿成像顺序调试
Wrong motion: inspect normalized time and decoded coefficients. Mirrored scene: inspect camera axes and matrix conventions. Giant splats: inspect log-scale activation and covariance units. Dark colors: inspect direct RGB versus SH and premultiplied blending. Popping: inspect visibility and order changes. Low FPS: measure stages before replacing the rasterizer.运动错误查归一化时间与解码系数;镜像场景查相机轴和矩阵约定;巨大点查 log-scale 激活与协方差单位;颜色发黑查直接 RGB / SH 与预乘混合;跳变查可见性与排序变化;低帧率先分阶段测量,再决定是否替换光栅器。
PUT NUMBERS IN代入数字
A decoded 32-float row is 128 bytes. At 108,317 splats this is about 13.22 MiB. Uploading only 108,317 32-bit indices costs about 0.413 MiB per frame, rather than resending the complete records. These numbers exclude duplicate CPU copies, GPU padding, render targets and other resources.每行 32 个 float 是 128 字节,108,317 颗约占 13.22 MiB。每帧只上传同数量的 32 位索引约需 0.413 MiB,无需重传整套记录。这些数字不包含 CPU 重复副本、GPU 填充、渲染目标与其他资源。
FORMULA → RUNNING CODE公式 → 可运行代码
Find the same operation in the code在源码里找到同一个计算
These excerpts are read from the current repository when the site is built. Expand one to inspect it; the full snapshot opens in a separate tab.以下片段在构建时从当前仓库读取。展开查看,完整源码快照会在新标签页打开。
public/learn/models.mjsL23–23
The exact arithmetic behind this lesson’s controls and worked example.本课控件与算例实际执行的计算函数。
export function memoryBudget(count,visible,fps){return {records:count*128,indices:count*visible*4,perSecond:count*visible*4*fps};}
The existing pass adapts the host camera and updates ordering.现有通道适配主机相机并更新排序。
let view = Mat4::from_cols_array_2d(&view_columns);
let projection = Mat4::from_cols_array_2d(&projection_columns);
let view_projection = projection * view;
let [width, height] = viewport.map(|v| v as f32);
Run from the repository root after installing its Rust/Node dependencies and Python with PyTorch and NumPy. CPU training is sufficient for this small exercise. Outputs go to artifacts/.从仓库根目录运行,先安装 Rust/Node 依赖与带 PyTorch、NumPy 的 Python。小实验使用 CPU 即可,输出位于 artifacts/。
python scripts/train_toy_stg.py --device cpu --steps 400 --output artifacts/toy-training
cargo run --example native_smoke -- artifacts/toy-training/model.ply artifacts/toy-training/cameras.json artifacts/toy-native
cargo run --example mini_compute
npm run check
Inspect native output at multiple timestamps; verify time and camera conventions before judging image fidelity.检查多个时间的原生输出,先核对时间与相机约定,再判断图像保真度。
Run mini_compute and inspect its CPU/GPU pixel comparison; explain that it has no GPU tile bins or sorter.运行 mini_compute 并检查 CPU/GPU 像素对照,说明它没有 GPU 分块或排序器。
Explain the full pipeline without opening the formulas, then use the code links to verify your explanation.不看公式讲完整条管线,再用源码链接核对自己的解释。
CHECK YOUR UNDERSTANDING检查理解
Can you predict the result?你能预测结果吗?
This is your own review mark. You can remove it at any time.这是你自己的复习标记,随时可以取消。