Skip to content
RobotWorld
返回博客
把 3DGS 带进 NVIDIA Isaac Sim:实写品质导入流程与工业仿真四大弱点
3DGSIsaac Sim仿真环境

把 3DGS 带进 NVIDIA Isaac Sim:实写品质导入流程与工业仿真四大弱点

把3DGS扫描导入Isaac Sim 6.0的通用流程:点数压到2^24以下、转.usdc、矫正朝向、沿轨迹放相机;并剖析单体块、单标签、无碰撞、固定光照四大弱点与网格分层对策。

LocaHun 3D(ロケハン3D)2026年7月26日3 分钟阅读
EN

一句话流程:3DGS 扫描 → 点数削减到 224 以下 → 转换为 USD → 放上 stage 并矫正朝向 → 把相机放到扫描轨迹上。

如果要把 3DGS 扫描用于机器人或自主移动的仿真,目的地不是游戏引擎,而是 NVIDIA Isaac Sim。本文把「从读入到以实写品质渲染」的完整流程整理成一套适用于任何数据的做法;后半部分则直面 3DGS 用于工业仿真时的本质弱点以及规避方法

在 NVIDIA Isaac Sim 中渲染的 3DGS 扫描(行人视角)
在 Isaac Sim 中渲染的 3DGS 扫描。1,650 万个高斯由 RTX 绘制,以能看清招牌文字的分辨率原样复现了真实的街景。

01 为什么是 Isaac Sim

3DGS 扫描要送进哪里,取决于用途。作为影像素材使用,UE5 的自由度最高;但如果目标是机器人、自主移动、传感器仿真,本命就是 NVIDIA Isaac Sim——因为你可以把真实存在的场所直接变成验证环境。

  • 能在真实场所里运行机器人——仿真环境不再是虚构空间,而是实际扫描过的现场。
  • 能与物理仿真共存——PhysX 的刚体、关节、传感器,可以在实写背景中运转。
  • 能批量生产训练图像——以真实风景为背景,从任意角度生成相机图像。

Isaac Sim 6.0 原生渲染高斯泼溅,并参与 RTX 路径追踪,景深与运动模糊直接生效。但真正动手导入时,你会撞上几堵文档里没有写的墙。

02 需要准备什么

  • Isaac Sim 6.0 或更高版本——解压后约 40 GB,请预留 50 GB 空闲空间。
  • 扫描数据——3DGS 的 .ply 文件。
  • 转换工具——PlayCanvas 的 splat-transform(npm 安装,免费)。
  • USD 转换——Isaac Sim 标准自带,无需额外安装。

不要把 Isaac Sim 装进 C:\Program Files。它运行时会写入数据,放在需要管理员权限的位置只会招来多余的麻烦。

扫描仪私有格式可以不转换直接用:splat-transform 除了 .ply,还能直接读取主流扫描仪和查看器的原生格式,省去转中间格式的工序。而且这些包里常常附带碰撞网格和扫描时的相机轨迹,会在后面的工序里派上用场。手上有原始格式的话,从它开始最划算。

03 第一道坎:超过绘制上限就什么都不显示

要处理大扫描,请先记住这一点:Isaac Sim 的 RTX 渲染器对每个 prim 最多只能绘制 224(16,777,216)个点。超过这个数,光线追踪结构的构建就会失败,该 prim 一个点都不会显示。转换工具不报错,Python API 也不报错——你会得到「转换成功、点数正确、但画面一片漆黑」的状态。

棘手的是:即使失败,每一道工序也都正常结束。USD 文件里正确写入了全部点的坐标、缩放、不透明度、颜色;放上 stage,prim 类型也能被正确识别。唯独不显示。

这个上限在官方文档里没有记载,唯一的线索是日志里的一行 Failed to create TLAS。规格上的正确解法是「减少点数,或拆成多个 prim」,本文采用前者。

看视口之前先看日志。放上 stage 后,在 Isaac Sim 日志里搜索 Gaussian prim loaded:带着点数出现,说明已注册为绘制对象;出现的是 Failed to create TLAS,则不会显示。别把黑屏误诊为相机问题,先查这里最保险。

04 导入流程

把点数压到上限以下

用 splat-transform 的 --decimate 传入目标点数:

# 按绝对数量指定(压到 2^24 = 16,777,216 以下)
splat-transform input.ply -d 16500000 output.ply

# 也可以按比例指定
splat-transform input.ply -d 95% output.ply

这不是简单的随机抽稀,而是把相邻高斯逐级配对合并。相比随机删除,信息损失更少;削减率只有几个百分点的话,外观劣化几乎看不出来。

转换为 USD 并放上 stage

在 Isaac Sim 内的 Python 中调用自带的转换器,把 PLY 转成 USD。输出扩展名请用 .usdc——用 .usdz 会让内部变成文本格式,文件体积膨胀两倍以上。

放置之前,先清理已有的高斯泼溅 prim。残留旧数据会造成「只显示新场景的一部分」的假象,让问题定位变得极其困难。

from omni.kit.converter.gsplat import convertPlyUSD
convertPlyUSD(r"output.ply", r"scene.usdc")

import omni.usd
stage = omni.usd.get_context().get_stage()

# 删除已有的高斯泼溅 prim
for p in list(stage.Traverse()):
    if p.GetTypeName() == "ParticleField3DGaussianSplat":
        stage.RemovePrim(p.GetPath())

# 不指定类型,用 OverridePrim 引用
prim = stage.OverridePrim("/World/Scene")
prim.GetReferences().AddReference(r"scene.usdc")

用 OverridePrim,不要用 DefinePrim。先显式指定类型再添加引用,本地类型会压过引用目标的类型,高斯泼溅类型就此丢失:属性都进来了,prim 类型却变了,渲染不出来。请用不指定类型的 OverridePrim 创建。

矫正上下翻转

转换器允许指定上方轴,但把 Z-up 的扫描数据按 Y-up 转换,会得到上下颠倒的场景——建筑物从地面向下生长。

如果没发现这一点,抱着「从上空俯瞰」的心态放置相机,看到的将是地面的背面,画面一片漆黑。对 prim 施加绕 X 轴的 −90° 旋转即可恢复原朝向:

from pxr import UsdGeom

x = UsdGeom.Xformable(prim)
x.ClearXformOpOrder()
x.AddRotateXOp().Set(-90.0)

05 放置相机

实用上的诀窍是:不要自己计算相机位置。从包围盒自动算距离的做法,会被稀疏离群点拖垮——扫描数据在拍摄范围之外也散布着稀疏的点,算出来的整体范围远比你想看的区域大。

改用扫描时实际走过的轨迹坐标。多数扫描仪会把移动轨迹作为位姿数据输出,从中取一点,把相机放在视线高度(约 1.7 m 前后),朝水平方向看即可。

朝向计算用 SetLookAt().GetInverse(),写进 AddTransformOp()——这种写法不会出现矩阵转置错误:

from pxr import Gf, UsdGeom

eye = Gf.Vec3d(...)    # 轨迹上一点 + 视线高度
target = Gf.Vec3d(...) # 想看的朝向

xf = Gf.Matrix4d().SetLookAt(eye, target, Gf.Vec3d(0,0,1)).GetInverse()
cx = UsdGeom.Xformable(cam_prim)
cx.ClearXformOpOrder()
cx.AddTransformOp().Set(xf)

用轨迹的理由很简单:扫描人员走过的地方,正是该数据被记录得最稠密的地方。把相机放到拍摄范围之外,看到的只能是根本没被拍摄过的面。即使拿不到位姿数据,也应该先从近距离试拍,看着拍到的范围逐步后撤,这样更稳妥。

从扫描范围之外观察 3DGS:未被拍摄的面破碎失真
相机放在扫描范围之外:这是建筑物的背面,属于未被拍摄的面,噪点明显。
放在扫描轨迹上的相机看到的街景:招牌文字清晰可辨
相机放在轨迹上、视线高度:这是实际走过的位置,达到能读懂招牌文字的品质。
在 Isaac Sim 中渲染的十字路口俯瞰图
俯瞰同理:不要一下子飞到几百米高空,从轨迹上一点点后撤才是稳妥做法。

渲染等待时间。超过 1,000 万个点后,RTX 收敛需要时间。截图之前,请把 await app.next_update_async() 跑满 150 帧以上;等待不足,保存下来的就是一张纯黑的图。

06 用于工业仿真的四个弱点

接下来才是正题。3DGS 在「外观」上具有压倒性优势,但工业仿真所需要的信息它几乎一概没有。以下是在 Isaac Sim 上实际取输出、逐项验证后的结论。

弱点 1:整个场景是「一整块」,无法按物体分离

这是最大的制约。3DGS 是几千万个高斯排成的一个 prim,不存在「这栋楼」「这个信号灯」「这辆车」的单位。它无法像 3D 模型那样选中物体 A、B,也无法只对某个物体做移动、隐藏、替换。

仿真默认你能「只移动目标物」「替换障碍物」——未经处理的 3DGS 做不到。

弱点 2:语义标签整个场景只能有一个

Isaac Sim 支持输出语义分割(逐像素分类「这是道路」「这是建筑」的图像),这是感知 AI 训练数据生成的核心功能。高斯泼溅也可以打标签,并反映到分割输出里。

但标签的单位是 prim。如弱点 1 所述,整个场景是一个 prim,所以结果就是整个场景只有一个标签。实际取输出:建筑、道路、人行道、信号灯,全被涂成同一个 ID。「只想学习道路区域」「只想提取标志」这类用途,现状直接不可用。

弱点 3:没有物理碰撞

高斯泼溅是外观数据,不携带面信息,因此无法参与物理引擎的碰撞判定。机器人会穿墙而过、穿透地板下坠——视觉上明明有地板,物理上却是一片虚空。

弱点 4:光照无法事后更改

3DGS 把拍摄时的光照作为颜色信息烘焙了进去。阴天扫出来的数据,即使往场景里加太阳光,也依然是阴天。想制作不同时间段、不同天气的训练数据时,这一性质就成了制约。

07 弱点的应对

每个弱点都有规避办法,共同的思路是「外观交给 3DGS,其余交给网格」的分工——这也是 NVIDIA 给出的架构。

应对 1:并用碰撞网格(物理)

在与 3DGS 相同的位置叠放一个简易网格(代理网格),把碰撞设在它身上:外观由泼溅负责,碰撞判定由网格负责,网格本身设为不可见。

from pxr import UsdPhysics, UsdGeom

mesh = stage.GetPrimAtPath("/World/CollisionMesh")
UsdPhysics.CollisionAPI.Apply(mesh)      # 赋予碰撞
UsdGeom.Imageable(mesh).MakeInvisible()  # 隐藏外观

网格来源有三条路:用扫描仪同时输出的网格最省事;没有的话,splat-transform 可以直接从 3DGS 生成碰撞网格;或者用简单的箱体近似地板、墙壁、障碍物——如果用途只是验证「机器人能不能通过」,箱体往往就够了。

这一思路的完整落地案例,是同一团队的后续文章:以 LiDAR 实测数据修补碰撞网格的地面孔洞,在涩谷十字路口叠加双层环境,并用 PhysX Vehicle 验证 53 米直行零穿透(中译本见 RobotWorld 博客)。

应对 2:按区域分割打标签(语义)

标签的单位是 prim,那么分开 prim 就能分开标签:把泼溅在空间上切开,分别导出为不同的 USD,再逐个赋标签。

分割在导入 Isaac Sim 之前完成:用 SuperSplat(PlayCanvas 的免费编辑器)选中区域单独导出,或按坐标机械切割。但工序量与分割细度成正比——「道路/建筑/其他」级别的粗分类是现实的,按物体逐一手工标注则不具实用性。

更稳妥的做法:把标签放在网格一侧。需要精细语义时,把带标签的网格作为独立图层叠上去才是现实解:复用应对 1 的碰撞网格,按部位拆分并赋标签。分割输出取自网格层,外观取自泼溅层。公开数据集也已经采用这种结构:泼溅 USD 与碰撞 USD 分开分发,使用时再合成。

应对 3:光照要么接受,要么换手段

对 3DGS 本体做重打光不在 Isaac Sim 的能力范围内。需要天气和时段的变化的话,可以把输出图像交给图像生成 AI 后处理,或者改变条件对同一场景扫描多次。UE5 一侧有支持重打光的插件,使用那边制作的素材也是一种办法。

判断用武之地

综合以上,3DGS 适合与不适合的用途分得很清楚:

用途仅靠 3DGS补充说明
实写品质的背景 / 外观验证最大强项,真实现场原样复现
相机图像生成(作为背景)角度自由,但没有像素级真值标签
机器人移动 / 碰撞验证×必须并用碰撞网格
分割训练数据×需要叠加带标签的网格
物体级操作 / 替换×不分割做不到;并用 CG 资产更快
光照条件变化×已烘焙,需要别的手段

归纳起来:3DGS 是「把真实环境作为实写品质背景搬进来」的技术。在其中活动的目标物、需要真值标签的部分,照旧用网格准备。只要做好这种分工,3DGS 就是一个非常强力的选项。

08 总结

导入流程是一条直线:「点数压到 224 以下 → 转换为 .usdc → 用 OverridePrim 引用 → 矫正朝向 → 把相机放到轨迹上」。容易栽跟头的是首尾两端:点数超限会毫无报错地什么都不显示;相机放到扫描范围之外只能看到破碎的面。这两点掌握了,其余都会顺利推进。

用于工业用途时,把 3DGS 理解为「把真实环境作为实写品质背景搬进来的技术」——不多不少——就是捷径。物体级分离、语义标签、碰撞判定,泼溅本身一概没有;需要的话,就把网格作为独立图层叠上去分工。反过来看,这也说明「外观的忠实度」是其他手段无法替代的。

按用途与 UE5 分开使用也是现实选择:作为影像素材的输出,参见作者的 UE5 × XGRIDs SDK 文章

来源:LocaHun 3D 技术博客 —— NVIDIA Isaac Simに3DGSを持ち込む(作者:中村航 / Kou Nakamura)

相关文章