2026 年初,有一群做机器人的人遇到了一件挺尴尬的事。
他们想让机器人在仿真环境里练习开抽屉、按面包机的开关,练好了再搬到现实世界里用。这套路数叫"real-to-sim-to-real",听着挺顺,先造一个和真实物体一模一样的数字分身,在电脑里让机器人反复练,练熟了再放到真实物体上。
问题出在"造一个数字分身"这一步。
**你让机器人在虚拟抽屉上练开抽屉,如果虚拟抽屉的把手位置和真实抽屉差了两厘米,那机器人练得再熟,换到真实世界照样抓空。**
这篇来自 NVIDIA 和南洋理工、北大团队的论文,叫 USDCraft,讲的就是怎么解决这个"差之毫厘谬以千里"的麻烦事。
### 造数字分身,难在哪
过去几年,造这种"能动的 3D 资产"大体有两条路。
第一条路是让模型学会看一个静态的 3D 网格模型,然后自动把它切成一块一块的零件,再猜每块零件是怎么动的,比如门绕哪个轴转、抽屉沿哪条轨道滑。这类方法叫 Particulate、SIMART,论文里管它们叫"mesh-based"方法。
网格(mesh)*:3D 建模里最常见的表示方式,用无数个三角形拼出物体的表面形状,有点像用乐高积木拼出一个轮廓。
这条路有两个硬伤。真实世界扫描出来的物体表面经常是不完整的,扫描仪照不到的角落就是一片空白,而且很多零件会"粘"在一起,比如门和门框连成一坨几何体,模型分不清哪是哪。更麻烦的是,这些方法都是靠大量标注数据训练出来的,一旦遇到训练集里没见过的物体类别,比如一个造型古怪的老式缝纫机,模型就抓瞎了。
第二条路反过来,不依赖扫描网格,直接让大语言模型凭着自己对世界的常识知识,从零开始写代码生成一个物体。这类方法叫 Articraft、Procedura。
好处是灵活,不挑物体类别,AI 什么都见过。但坏处也很致命,如果手头有一个真实物体需要复刻,这类方法没有测量数据可参照,生成出来的尺寸和真实物体对不上号,造出来的东西好看是好看,就是不像那个真家伙。
**这就是论文开篇点出的矛盾:精确的方法不够灵活,灵活的方法不够精确。**
你细想这个矛盾挺眼熟的。这就跟请两种人来帮你复刻一件家具一样。一种是严谨的木匠,拿着卷尺一寸一寸量,但只会照着图纸做,遇到图纸缺一角,他就不知道怎么补;另一种是经验丰富的老师傅,什么家具都见过,凭记忆就能做出个大概,但没量过尺寸,做出来的东西总归和原件差了那么点意思。如果只用木匠,缺角的地方永远是个洞;如果只用老师傅,做出来的抽屉把手位置可能偏出两厘米,机器人伸手去抓就扑空了。USDCraft 想做的事,就是让这两种人变成同一个人。
### USDCraft 的核心思路:先让 AI "读懂"尺子
USDCraft 的做法说起来是一句话:让一个预训练好的大语言模型(不需要专门为这个任务重新训练)去写代码,生成物体的 3D 模型,代码写完还要反复检查、修改,检查的依据就是原始扫描得到的真实几何数据。
这里立刻冒出一个技术难题。
大语言模型是处理文字的,它不会直接"看"一个 3D 网格文件。你给它一堆三角形顶点坐标,它消化不了,信息量太大,塞不进它的上下文窗口。给它渲染出来的图片呢?图片又丢失了精确的尺寸信息,而且看不到物体内部的结构。
论文管这个转换步骤叫"源几何分析"(source geometry analysis)。
源几何分析*:把一个 3D 网格模型,转换成一段带精确尺寸的文字描述,让语言模型可以像读说明书一样"读懂"这个物体的形状。
具体怎么做的呢?研究者把物体放进一个规则的三维网格(想象成一个三维方格纸),然后沿着竖直方向一层一层地切片,每一层记录哪些格子里有扫描到的物体表面,哪些格子是空的。关键的巧思在于:没被扫描到的格子,不会被标记成"空的"或者"实心的",而是老老实实标成"未知"。
这个区分很重要。一个扫描有破洞的地方,不代表那里真的是空的(可能只是传感器没照到),一个封闭外壳的内部,也不代表里面一定是实心的(可能里面藏着电机)。给语言模型留出"我不确定"的选项,它才敢在图像和常识的指导下,大胆地把缺失的部分补全,而不是瞎编一气。
这就像给一个法医看一具不完整的骸骨。如果法医把所有缺失的骨头都当成"原本就没有",复原出来的骨架肯定是残缺畸形的。真正专业的做法是标清楚"这块缺失、未知",然后再结合解剖学常识去合理推断缺的那块骨头大概是什么形状,而不是拍脑袋瞎猜,也不是干脆放弃。如果不做这个区分,模型要么把洞当成真的凹陷复刻出来(丑),要么干脆不敢补任何东西(残)。
光有一个粗粒度的全局切片还不够精细,所以 USDCraft 还给模型配了个"放大镜"工具,叫网格检查(mesh inspection),模型可以根据参考图片和自己当前的建模计划,主动要求渲染某个局部视角,去查询某个区域的具体边界、点分布和表面朝向。
两件事合在一起,模型就有了既能看全局轮廓、又能查局部细节的能力,而且全程都是用文字在"看",不需要专门针对 3D 理解去训练这个语言模型。
### 代码即资产:为什么不直接改网格
接下来一个关键设计选择:USDCraft 把每个物体表示成一段可执行的程序代码,而不是直接输出一堆三角形网格。
这个选择初看有点绕,为啥不直接修网格呢?
原因在于,程序里的每个零件、每个关节、每个物理参数,都是用显式的变量写出来的。比如一个抽屉把手的坐标是 (x=0.12, y=0.05),这个数字就明明白白地躺在代码里。当后续检查发现"这个把手往前偏了 0.64 毫米"的时候,模型可以直接定位到代码里那一行,改一个数字就行,不需要把整个几何体推倒重来。
而且代码可以凭空"生造"出扫描网格里压根没出现过的零件和连接关系,比如一个被扫描仪完全遮住的内部弹簧,这是单纯"切分已有表面"的方法做不到的,因为它们手里压根没有这块材料可切。
这个工具箱里混用了两套建模手法,一套叫 CadQuery,专门做有精确尺寸、带棱角的机械零件(比如螺丝、支架);另一套叫 SDF(signed distance field,有符号距离场),专门做圆润的有机形状和平滑过渡的曲面。外观方面,材质、贴图、贴花也都写在同一段代码里。
你可以把这个选择理解成装修房子的两种方式。一种是直接在毛坯墙上刷腻子抹灰,改一个地方就得把那一片墙面铲掉重来,另一种是先画好 CAD 图纸,改哪里就在图纸上改哪个数字,然后重新打印出来。前者改起来又慢又容易出错,后者虽然多了一道"画图纸"的工序,但后期维护的代价小得多。USDCraft 选的是后一种,代价是模型得先学会"画图纸"这件麻烦事,但换来的是后续反复修改的高效率。
更重要的是,这段代码编译出来之后,直接携带了碰撞体积、质量、摩擦系数、关节限位这些物理参数,可以无缝加载进 Isaac Sim(英伟达的机器人仿真平台)里跑起来,不需要人工再去调整任何参数。
PhysX*:英伟达开发的物理引擎,负责计算仿真世界里物体碰撞、重力、摩擦力这些物理效果,是 Isaac Sim 仿真平台的底层引擎。
### 迭代几何复核:让错误无处藏身
写出第一版代码只是开始,接下来的问题是怎么找出代码里的错误并改掉它。
论文给这个环节取名叫"迭代几何复核"(iterative geometric rechecking),思路是把生成出来的候选模型,用和原始扫描一模一样的"切片文字描述"方式,重新编码一遍,然后拿两份描述做比对。
比对会产生两个集合。一个叫







