磁刻技术实录 · 第 24 篇 · 工程实践 · 技术基线 2026-10-31
我们正在做的「磁刻(Cike)」,是一款鸿蒙原生的生活记录与个性化创作应用。用户可以把照片做成数字冰箱贴,在洞洞板上自由摆放、组合自己的生活片段,也可以把喜欢的内容做成桌面卡片,用来回看、互动和分享。
在空间记录上,我们引入了 3D Gaussian Splatting(3DGS,三维高斯泼溅),把拍摄的视频重建为可以转动、靠近观察的三维场景。为此,我们重构了视频重建链路,实现自己的 C++ 训练核心,并结合鸿蒙原生的媒体处理、模型查看和分享能力,希望让用户保存一段经历时,也能留下当时的空间关系。
我们希望用户在磁刻查看器里看到的结果,能够忠实反映训练产物。若显示参数改变了高斯形状,训练取得的细节也可能被重新模糊。这篇分享协方差与屏幕空间处理的对照方法,让训练质量和显示效果可以分别排查。
同一个 PLY,在训练器的参考渲染中看起来较清晰,进入手机查看器却变得模糊,不一定是导出损坏。显示端可能为了兼容旧模型或制作扫描动画,对协方差、透明度和屏幕覆盖做了额外处理。这些处理会改变训练得到的分布。
以下代码按当前实现整理,保留关键运算与控制顺序;省略导入、日志和完整类型,部分辅助函数采用说明性命名,片段需结合上下文阅读。
磁刻对带自研标记的模型采用明确显示路径,避免无条件套用旧 SDK 的尺度截断和背景判断。模型来源因此不仅影响颜色,也影响几何解释。训练与查看器之间必须共享“这些参数表示什么”的约定。
图 1:同一模型可能因显示端规则得到不同结果
协方差是训练结果的一部分
高斯训练会优化尺度与旋转,使多个分布共同解释目标图像。若显示时把所有尺度统一放大,原本分离的结构可能连在一起;缩小则可能出现孔洞。简单调整一个显示系数,实际上是在修改模型的覆盖关系。
扫描显形阶段可以有视觉演出,例如从细小点逐步增长到完整分布。但动画完成态应回到明确的模型语义,不能让演出参数永久改变自研训练结果。当前路径在完成态保留训练协方差,并使用指定屏幕方差。
抗锯齿与模糊之间需要实验
投影后给二维协方差加入屏幕方差,可以减少过小分布在像素采样中的不稳定。但数值越大,覆盖也可能越宽。当前自研完成态使用 0.30 的屏幕方差,这是实现参数,不是对所有模型最优的普遍常数。
比较时应固定模型、相机与分辨率,观察边缘、高频纹理和稀疏区域。若同时改变模型训练参数和显示方差,就无法判断改善来自哪一层。
裁剪范围不等于压缩分布
很大的屏幕椭圆可能带来高片元成本,因此查看器限制绘制几何范围。关键是保留原始高斯坐标的比例关系:只裁掉远处覆盖,不把完整分布压进一个更小的矩形。
如果顶点几何被缩小,而片元中的局部高斯坐标仍按整个原始范围重新映射,就会改变实际形状,相当于压缩高斯。正确处理需要让裁剪后的几何对应原分布的局部区域,而不是重新定义整个分布。
区分世界协方差与屏幕上的最小方差
mat3 sigmaEye = rotation * covariance * transpose(rotation);
float a = dot(jx, sigmaEye * jx) + screenVariance;
float b = dot(jx, sigmaEye * jy);
float c = dot(jy, sigmaEye * jy) + screenVariance;
// 独立训练模型完成态使用当前约定的 0.30 屏幕方差。
a、b、c 组成二维协方差,非对角项 b 表达椭圆倾斜。屏幕方差只加到对角线,单位属于像素空间;它与把整个世界协方差乘上一个大系数并不等价。若默认显示参数放大了模型形状,训练得到的细节可能在查看器中被重新抹平。
0.30 是当前特定模型完成态的显示约定,不应推广成任意分辨率、任意模型都最佳的参数。诊断时应固定模型、相机、输出尺寸和背景,比较训练参考渲染与查看器结果,再逐项检查协方差、附加方差及动画相关缩放。
图 2:固定模型与相机,一次只改变一个因素
已有参数对照怎样解读
仓库记录过同模型、同相机的 CPU 参数隔离实验,比较协方差缩放与屏幕方差的影响。它能够帮助判断某些显示规则是否偏离参考结果,但不等同于完整 GLES 管线,也不能替代当前手机画面的验收。
实际查看器还涉及着色器精度、实例布局、排序、混合和 Surface 尺寸。即使 CPU 对照显示某组参数更好,也需要回到真实 GLES 路径检查这些环节。宣传时保留实验范围,才能避免把局部证据扩展成整体性能或画质结论。
建立显示一致性样本
可以用单个倾斜椭球检查方向,用大小不同的高斯检查覆盖,用重叠彩色分布检查透明合成,再使用真实模型观察结构。每个样本应保存固定相机与输出尺寸,保证修改前后能够直接比较。
动画测试则分别检查开始、中间与完成态。模型完成后的画面不应继续受到扫描次数或旧路径背景判定影响;重新打开模型也应回到相同最终解释。
限制绘制范围时仍保持高斯坐标一致
vec2 rawRadius = projectedEllipseRadius;
vec2 clippedRadius = min(rawRadius, vec2(256.0));
vec2 screenOffset = corner * clippedRadius;
vec2 gaussianCoord = corner * (clippedRadius / rawRadius) * supportSigma;
// screenOffset 决定四边形覆盖;gaussianCoord 用于指数衰减。
这里假设投影半径已经通过有效性与正值检查。限制四边形尺寸能控制极大高斯带来的片元成本,但局部高斯坐标也必须跟随裁剪比例。如果缩小四边形,却仍把边缘当作原先完整支撑范围,就会把同一个高斯压缩成更尖锐的形状。
这段说明几何裁剪与函数采样之间的关系,并不主张所有模型都统一裁到同样大小。任何显示加速都应回答两个问题:删掉了哪些像素覆盖,保留下来的像素是否仍在计算原来的高斯函数。否则所谓“显示优化”可能同时改变模型外观。
显示端是一套有算法含义的实现。把它视为简单“把点画出来”,会遗漏大量质量问题。训练与查看器共同维护参数协议,才能让最终用户看到训练真正得到的结果。