Mesh + Gaussian 能否驱动?GaMeS RTX 4090 实测与 Avatar 路线
在 RTX 4090 上复现 GaMeS,从 flat Gaussian、伪三角面参数化到驱动动画,并梳理 GoMAvatar、SplattingAvatar、GART 等可动画人体方案。
可以驱动,而且“Mesh 管控制、Gaussian 管外观”很可能比“让 Gaussian 完全替代 Mesh”更接近游戏和数字人的实际生产方式。
本站在 RTX 4090 上跑通了 GaMeS 的无输入 Mesh 路线:先训练 149,657 个 flat Gaussian,再把每个 Gaussian 表示成一个可编辑伪三角面,用三角面重新计算它的位置、尺度和旋转,最后施加逐帧波浪形变。参数化前后的留出视角 PSNR 仅相差 0.0126 dB,200 帧驱动序列也已生成。
但这个结果不能被夸大成“任意 3DGS 已经能自动绑骨”。通用几何形变、SMPL/FLAME 参数化人体、带 IK 的游戏角色,是三个不同难度层级。本文先把可运行的底层机制测清楚,再说明向人体骨骼化还缺什么。
如果你还不了解 canonical space、LBS 和姿态残差,可先阅读《从 4DGS 到可驱动数字人》。
先分清三种“Mesh + Gaussian”
这个名称至少覆盖三类任务:
| 路线 | Mesh 的角色 | 能否直接驱动 | 典型项目 |
|---|---|---|---|
| 从 Gaussian 提取 Mesh | 导出表面、碰撞或编辑代理 | 不一定;还要拓扑清理和绑定 | SuGaR、GS2Mesh、2DGS |
| Gaussian 绑定三角面 | 三角面提供局部坐标和形变 | 可以接受 Mesh 形变 | GaMeS、SplattingAvatar |
| Gaussian 绑定人体模板 | SMPL/FLAME、骨骼和姿态提供控制 | 面向动作或表情驱动 | GoMAvatar、GART、GaussianAvatars |
本文实测的是第二类的最小闭环。它回答“几何载体变化后,Gaussian 外观能否稳定跟随”,还没有回答人体关节、衣服和未见姿态的全部问题。
核心机制:用三角形重建 Gaussian
普通 3DGS 独立优化每个 Gaussian 的中心、旋转和三个尺度,几十万个元素之间没有天然拓扑关系。GaMeS 把一个 flat Gaussian 的最小尺度压到接近零,再用中心 v₁ 和两个主轴端点 v₂、v₃ 构成三角形:
Gaussian 中心、旋转、尺度
→ 三个顶点 (v₁, v₂, v₃)
→ Mesh / 骨骼 / 程序形变修改顶点
→ 从边向量与法线重建中心、旋转、尺度
→ Gaussian rasterizer 绘制高保真外观
这样,动画系统只需要改变三角形,Gaussian 的空间参数会自动随局部面片变化。颜色、透明度和球谐外观仍保留在 Gaussian 中。对真正 Avatar 来说,三角面还可以来自 SMPL 身体或 FLAME 头模;骨骼先通过 LBS 驱动 Mesh,再由 Mesh 驱动 Gaussian。
GaMeS 论文同时支持已有 Mesh 初始化,也提供“先训练 flat Gaussian、再为每个 Gaussian 构造伪三角面”的路线。本站选择后者,因为它不需要作者的 OBJ 或受限人体模型,任何人用公开 NeRF Synthetic 数据都能复现。
GeekX 实测环境与数据
| 项目 | 本次配置 |
|---|---|
| 主机 | WSL2 Ubuntu;Intel Core i5-13600KF,14 个逻辑 CPU |
| GPU | NVIDIA GeForce RTX 4090 24GB;驱动 591.86 |
| 软件 | Python 3.10、PyTorch 2.9.1+cu128、CUDA Toolkit 12.9 |
| 代码 | GaMeS commit 1722f7089c7ad94e875876c0216b10f89f11f026 |
| 数据 | NeRF Synthetic hotdog 的公开镜像 |
| 数据划分 | 100 张训练、100 张验证、200 张测试 RGB;800×800,白底 |
| 配置 | gs_flat、SH degree 3、30,000 步、开启白底和测试划分 |
Google 托管的原始 NeRF Synthetic 下载地址目前返回 404,因此本站使用保留原 README 和归属说明的 Hugging Face 镜像。三个 transforms_*.json 与图像引用均做了完整性检查,数据变换文件的合并 SHA256 为 09904880466bb82d4。
仓库 README 以 Python 3.8、PyTorch/CUDA 11.8 为基线。本次在 CUDA 12.9 编译 simple-knn 时遇到 FLT_MAX 未定义,在 simple_knn.cu 增加 #include <cfloat> 后通过;diff-gaussian-rasterization 则直接为 RTX 4090 的 sm_89 编译成功。这是环境兼容补丁,不是算法修改。
训练结果:分钟级,但资源口径要说清
正式训练命令为:
python train.py --eval \
-s data/hotdog \
-m output/hotdog-gs-flat-30000 \
--gs_type gs_flat -w \
--iterations 30000 \
--test_iterations 7000 20000 30000 \
--save_iterations 7000 20000 30000 \
--quiet
| 指标 | RTX 4090 实测 |
|---|---|
| 30,000 步墙钟时间 | 4 分 37.05 秒 |
| 训练进程最大主存 RSS | 8,969,164 KiB,约 8.55 GiB |
nvidia-smi 整卡显存峰值 |
7,242 MiB |
| 活跃窗口 GPU 平均利用率 / P95 | 76.59% / 88% |
| 平均功耗 / 峰值功耗 | 235.50 W / 268.82 W |
| 最高温度 | 60°C |
| 最终 Gaussian 数量 | 149,657 |
| 最终 PLY 大小 | 37,116,467 字节,约 35.4 MiB |
GPU 以 1 秒采样,并用整卡显存超过 3,000 MiB 确定 281 个活跃样本;因此显存仍包含 WSL 和桌面基线,不是训练进程独占值。最终 PLY SHA256 为 60df9f4fbe93d159。
参数化是否损失外观
训练完成后,先以原始 gs_flat 渲染 200 张测试图,再以 gs_points 将每个 Gaussian 转成三角面、从三角面重建空间参数并渲染同一批视角:
python scripts/render.py -m output/hotdog-gs-flat-30000 \
--gs_type gs_flat --skip_train --quiet
python metrics.py -m output/hotdog-gs-flat-30000 --gs_type gs_flat
python scripts/render.py -m output/hotdog-gs-flat-30000 \
--gs_type gs_points --skip_train --quiet
python metrics.py -m output/hotdog-gs-flat-30000 --gs_type gs_points
| 表示 | PSNR ↑ | SSIM ↑ | LPIPS ↓ | 200 张渲染墙钟 |
|---|---|---|---|---|
原始 gs_flat |
37.55925 dB | 0.984935 | 0.020416 | 27.62 秒 |
三角面参数化 gs_points |
37.54668 dB | 0.984906 | 0.020437 | 17.32 秒 |
| 差值 | -0.01257 dB | -0.000030 | +0.000021 | — |
这组差值小到足以说明:在这个静态场景上,三角面参数化几乎完整保留了 flat Gaussian 的成像质量。 两次墙钟包含模型加载和 PNG 写盘,且首次路径有缓存差异,不能用 27.62 与 17.32 秒宣称某种表示更快。
让高保真外观层真正动起来
官方热狗脚本对三角形 z 坐标施加正弦位移:
triangles_new[:, :, 2] += 0.3 * torch.sin(
triangles[:, :, 0] * torch.pi + t
)
仓库当前 commit 的循环却固定使用 t[43],导致每一帧形变相同、只有测试相机变化。本站将这一行改为 t[idx],否则不能称为时变驱动:
- new_triangles = transform_hotdog(triangles, t[43])
+ new_triangles = transform_hotdog(triangles, t[idx])
脚本从 scripts/ 路径直接执行时还需要把项目根目录加入模块搜索路径:
PYTHONPATH=.:/usr/local/cuda/lib64 \
python scripts/render_points_time_animated.py \
-m output/hotdog-gs-flat-30000 \
--skip_train --quiet

200 帧、800×800 PNG 的完整命令墙钟时间为 29.54 秒,进程最大主存 RSS 约 8.22 GiB;原始帧共约 52 MiB,30 FPS H.264 预览约 2.0 MB。29.54 秒包含加载、逐帧形变和 PNG 写盘,只能视为离线序列吞吐,不能换算成 Viewer、游戏或 VR 的交互帧率。
从热狗形变到人体骨骼,还差哪几层
这次实验证明了两个必要条件:Gaussian 可以由可编辑三角面参数化;三角面变化可以传播到 Gaussian 外观。它没有证明以下生产能力:
- 拓扑与语义:伪三角面彼此独立,没有肩、肘、手指或衣片的连接关系;
- 骨骼蒙皮:还没有骨骼层级、蒙皮权重、IK、动作重定向和动画状态机;
- 未见姿态:抬手后新暴露的腋下、背面和衣褶必须有训练数据或生成先验;
- 非刚性残差:肌肉、布料、头发和接触不能只靠 LBS;
- 游戏属性:Gaussian 没有碰撞体、导航网格、插槽和可靠阴影代理;
- 重光照:捕获时的高光与阴影容易被烘进外观,换场景后不一定可信。
真正的人体路线通常让 SMPL/SMPL-X 或 FLAME 提供共享拓扑与骨骼,再学习 Gaussian 的外观和姿态残差。本站没有跳过授权步骤去拼凑人体数据:SMPL/FLAME 需要账户和单独许可,ZJU-MoCap、PeopleSnapshot 也有各自的数据条款。
哪些开源方案值得继续跑
| 项目 | 控制载体与特点 | 复现门槛 / 许可提醒 |
|---|---|---|
| GaMeS | 通用 Mesh 或每 Gaussian 伪三角面;适合学习最小机制 | 本文已跑通;继承原 3DGS,限非商业研究/评估 |
| GoMAvatar | Gaussians-on-Mesh 全身 Avatar;论文页面报告 43 FPS、每主体 3.63 MB | 需要 SMPL 与人体视频/数据;数字是论文环境,不是本站实测 |
| SplattingAvatar | Gaussian 嵌入三角网格,并允许嵌入点在面上移动 | 测试环境为 PyTorch 1.13.1+cu117;仓库为 CC BY-NC-SA 4.0 |
| GART | SMPL/SMAL 模板、可学习蒙皮与新增 latent bones | 代码 MIT,但人体模型、数据和 rasterizer 许可需分别检查 |
| GaussianAvatars | Gaussian 绑定 FLAME 面部三角形,适合可驱动高保真头部 | FLAME 与跟踪前处理;仓库为非商业许可 |
| Animatable Gaussians | 前后 Gaussian 特征图结合姿态相关外观,面向宽松衣物 | 需要多视图人体数据、SMPL 和较完整预处理 |
“代码仓库是 MIT”也不自动意味着整个项目可商用。生产评估至少要分别审计主代码、CUDA rasterizer、SMPL/FLAME 等人体模型、训练数据、预训练权重和导出资产。
面向游戏、模特和直播的建议架构
如果目标是实时场景或数字人,不建议把静态 PLY 直接挂到一个骨骼节点。更稳妥的混合管线是:
多机位/单目视频 + 相机与人体跟踪
→ canonical SMPL/FLAME/服装 Mesh
→ Gaussian 外观绑定到三角面或骨骼权重
→ 学习 pose-conditioned 非刚性残差
→ 骨骼、表情、IK 驱动 Mesh
→ 每帧更新 Gaussian 中心、旋转、尺度
→ LOD / 裁剪 / 排序后 splatting
→ 与 Mesh 深度、阴影、碰撞和场景光照合成
其中 Mesh 不一定要被用户看见,但应保留为结构层:它负责动画编辑、碰撞、物理、阴影和低端 LOD;Gaussian 作为外观层负责皮肤、发丝、衣服褶皱和视角相关细节。网络直播也只需同步骨骼、表情和低维残差,而不是逐帧传几十万个 Gaussian。
结论
Mesh + Gaussian 已经不是纯概念:GaMeS 的公开实现能把无拓扑 flat Gaussian 转为可编辑伪三角面,并在几乎不损失静态画质的情况下传播形变;GoMAvatar、SplattingAvatar、GART 等项目则把同一思路推进到人体模板、蒙皮和新姿态合成。
目前最有希望的方向不是“Gaussian 取代游戏 Mesh”,而是:
用骨骼和 Mesh 建立可控、可碰撞、可同步的角色结构,再把 Gaussian 作为高保真外观层附着其上。
下一步最有价值的对照实验,是在获得合规 SMPL 与公开人体数据授权后,跑通一个完整全身方案,分别测训练成本、未见动作质量、单 Avatar 渲染、双眼 VR 和多人场景预算。届时论文 FPS 与真实引擎帧预算才能放在同一张表里比较。