Adobe、Intel联合打造的“万能遥控器”,让AI在游戏引擎里随心所欲

这项由Adobe Research、Intel Labs、Manycore Tech Inc、Adobe、NVIDIA、ETH Zurich以及Imperial College London联合开展的研究,以预印本形式于2026年7月7日发布在arXiv平台,论文编号为arXiv:2607.06701。感兴趣的读者可通过该编号在arXiv上查阅完整原文。
**游戏引擎里的"遥控困境"**
假设你是一位机器人研究员,想让AI学会在城市街道上安全行驶。现实世界太危险,真车太昂贵,于是你打算用电脑里的虚拟城市来训练AI。这个虚拟城市画面精美、车水马龙,几乎和现实没什么区别——问题是,你没办法用Python(一种流行的编程语言,可以理解为研究人员的"工作语言")灵活地控制这个虚拟世界,就好像你拥有一台顶级游戏机,却找不到对应的遥控器。
这个困境并不是少数研究者才有的烦恼。近年来,虚拟仿真环境已经成为AI研究的核心基础设施,从让AI学会下围棋到训练无人机飞行、再到开发自动驾驶汽车,都少不了高质量的虚拟世界。在这些虚拟世界里,用游戏引擎构建的场景因为画面逼真、物理效果准确而备受青睐。虚幻引擎(Unreal Engine,简称UE)就是其中最耀眼的一款:它完全开源、画面顶尖,连好莱坞特效和顶级3A游戏都在用它。
然而,现有的基于虚幻引擎的仿真工具有三个让研究者头疼的老毛病。第一,能通过Python控制的功能太少,往往只有几百个固定接口,就像一台遥控器上只有三四个按钮,大部分功能根本按不到。第二,把虚拟世界里渲染好的高清图像传回Python程序的速度极慢——有些工具慢到比直接在游戏里看画面慢了二三十倍,相当于你在游戏里能流畅看4K电影,但把电影截图传给AI时却要等上半分钟。第三,这些工具大多是"一体化大块头",和特定项目深度绑定,很难嵌入到现有的研究项目里,也很难把外部资产导入进去。
正是为了解决这三个痛点,来自多家顶尖机构的研究团队联手打造了SPEAR——一个面向光真实(Photorealistic)具身AI研究的仿真平台。
一、SPEAR究竟是什么:那把"万能遥控器"
SPEAR的核心是一个Python库,可以连接到任何用虚幻引擎开发的应用程序,并通过一套模块化插件架构对其进行编程控制。用一个比喻来说:虚幻引擎就像一台功能无比强大的专业级录音棚,而现有的仿真工具只给你提供了几个简单旋钮,SPEAR则相当于把整个录音棚的所有推子、按键、效果器全部接上了一块全功能调音台,让你从Python端就能精细操控每一个细节。
SPEAR之所以能做到这一点,关键在于它直接对接了虚幻引擎的"反射系统"(Reflection System)。所谓反射系统,可以理解为虚幻引擎内部的一张"功能总目录"——引擎里几乎所有的类、函数、变量都登记在这张目录里,只要你知道名字,就能在运行时动态查找和调用。SPEAR通过一套专门的C++接口把这张目录暴露给Python,让Python代码能用字符串(也就是文字名称)来查找类、调用函数、读写变量,完全不需要为每一个功能手写专属的转接代码。
得益于这个设计,SPEAR一口气向Python暴露了超过14,000个独特的虚幻引擎函数,以及超过53,000个虚幻引擎属性变量。这相当于现有同类工具的十倍以上。与此同时,SPEAR自身的代码量非常克制,全部Python和C++代码合计约27,000行,远少于AirSim的14万行和CARLA的15万行。在同类工具中,UnrealCV+虽然也能访问部分虚幻引擎内部功能(约747个函数和8,721个变量),但它的代码量也只有11,000行左右,而SPEAR在暴露超出它约二十倍功能量的同时,代码体积也只有其约两倍多,足见设计的精炼。
二、编程模型:像写普通Python代码一样控制虚拟世界
SPEAR最让开发者感到亲切的地方,是它的编程体验极其自然。考虑这样一个场景:你想在虚拟室内场景里生成一组坐标轴模型,把它放到某个位置,然后把它放大四倍,最后查询它的位置。在SPEAR里,这整个过程就像这样——先获取一个游戏对象,调用`spawn_actor`生成它,调用`SetActorScale3D`缩放它,再访问`RootComponent`根组件并获取其位置。这些操作写起来就像调用Python的普通函数和属性一样,完全没有额外的包装或注册步骤。
这种体验背后有一套精心设计的"事务"(Transaction)机制。在SPEAR里,对虚幻引擎的操作被组织成一帧一帧的"事务单元",每个事务单元由`begin_frame`上下文和`end_frame`上下文组成,分别对应一帧的开始和结束时刻。用户只需要在Python里用`with begin_frame():`和`with end_frame():`两个代码块把操作包起来,就相当于告诉引擎"这些事情在同一帧的开始做,那些事情在这帧的结束做"。引擎保证同一事务内的所有操作都在同一帧内完成,并且按照Python代码的顺序依次执行,没有歧义。
另一个极为实用的设计是"异步操作"。默认情况下,每次调用虚幻引擎函数,Python都要等待引擎真正执行完毕才能继续,这就像你每发一条短信都要等对方回复了才能发下一条。SPEAR为每一个函数都提供了一个异步版本(在函数名前加`async.`前缀),调用异步版本时Python不等待引擎,而是立刻拿到一个"未来对象"(Future),继续做其他事情,等到真正需要结果时再从这个未来对象里取值。如果结果还没准备好,取值时才会等待。这种机制类似于网购时下单后拿到一张快递单号,你不用守在门口等,快递到了再去取就行。
通过合理使用异步操作,Python线程和引擎的游戏线程可以完全并行运行,彼此不互相阻塞,从而让整个系统以接近引擎原生速度运行。为了防止Python线程跑得太快把引擎远远甩在后面,系统会在同时有超过一个未完成事务时,让Python在进入下一个`begin_frame`之前稍作等待,确保两者的进度不过分偏离。
SPEAR的编程模型还有一个非常重要的特性:扩展极其容易。如果你写了一段C++代码,想让它能从Python端访问,只需要在函数或变量旁边加上`UFUNCTION`或`UPROPERTY`注解,虚幻引擎就会自动把它纳入反射系统,SPEAR就会自动把它暴露给Python——不需要改动任何SPEAR的代码,不需要额外的注册步骤。这对研究者来说意味着极大的灵活性。
三、速度的秘密:图像传输比现有工具快十倍以上
在具身AI研究中,仿真平台需要频繁地把渲染好的图像传给Python程序,让AI"看"到虚拟世界里发生的事情。这个传输过程的速度,直接决定了训练和实验的效率。
SPEAR为此专门设计了一套高性能相机传感器,能以1920×1080(全高清)分辨率每秒渲染73帧图像,并直接写入用户的NumPy数组(一种Python里常用的数据容器),整个过程不需要额外的数据复制。这个速度是同类虚幻引擎插件中的佼佼者,比当时主流的同类工具快了一个数量级(约9至21倍)。
这个成绩是怎么做到的?关键在于两个技术:异步通信和进程间共享内存。异步通信前面已经提到,它让Python不用干等引擎渲染完成。共享内存则是更底层的加速手段:传统做法是引擎把图像数据从GPU显存复制到内存,再通过网络或管道传给Python程序,这个过程要复制多次。SPEAR改用了操作系统级别的"共享内存区域",让引擎和Python程序直接共享同一块内存,渲染好的图像数据从GPU卸载到这块内存后,Python程序直接读取,完全跳过了中间的复制环节,就像两个人共用同一块白板,省去了互相抄写的麻烦。
此外,SPEAR的相机传感器还支持"渲染延迟"(Rendering Latency)配置:允许用户以牺牲一点时效性(即接受图像比当前帧晚一到两帧才到手)为代价,换取更高的吞吐量。配置为0帧延迟时,吞吐率约为56帧/秒;配置为1帧延迟时升至约65帧/秒;配置为2帧延迟时可以达到约73帧/秒。这种设计给了用户根据实际需求灵活权衡的空间。
研究团队做了详细的横向对比实验。在与UnrealCV+的对比中,他们在完全相同的虚幻引擎项目、相同场景、相同项目设置下分别运行两个插件,SPEAR在0帧延迟配置下帧率为56帧/秒,而UnrealCV+仅有3.5帧/秒,相差约16倍。在与AirSim和CARLA的对比中,为了公平比较,研究团队特意将三个平台的"无Python通信时的独立渲染帧率"调整到接近一致(SPEAR约89帧/秒,CARLA约90帧/秒,AirSim约93帧/秒),确保任何差异都来自通信开销而非渲染质量。结果是:在0帧延迟条件下,SPEAR达到32帧/秒,AirSim只有2.6帧/秒,SPEAR约快12倍;在2帧延迟条件下,SPEAR达到37帧/秒,CARLA约33帧/秒,SPEAR仍领先约10%。
四、不只是速度:前所未有的地面真值图像模态
SPEAR的相机传感器不仅快,还"看得多"。除了普通的美感图像(即我们平常看到的彩色照片式渲染图)之外,SPEAR还能渲染多种"地面真值图像模态"(Ground Truth Image Modalities)——这些是研究者用来训练和评估AI的特殊图像,包含普通照片看不到的信息层。
具体来说,SPEAR能输出的图像类型覆盖了深度图(每个像素到相机的距离)、表面法线图(每个点的表面朝向方向)、实例ID图和语义ID图(标注每个像素属于哪个物体或物体类别)、材质ID图(标注每个点的材质类型),以及一套非漫反射本征图像分解(Non-Diffuse Intrinsic Image Decomposition)——这是把图像中的光照、材质、反射等成分分开的技术。此外还有物理基础着色参数(Physically Based Shading Parameters),这些参数描述了每个表面材质的物理属性,比如粗糙度、金属度等。
值得特别提及的是,这套非漫反射本征图像分解在现有任何基于虚幻引擎的仿真器中都找不到,是SPEAR独有的能力。研究团队指出,SPEAR的相机传感器能输出Hypersim数据集(Adobe Research此前发布的一个著名室内场景合成数据集)中的全部图像模态,同时在此基础上增加了新的模态。
五、灵活得出人意料:那些无法用其他工具完成的事
SPEAR的高度可编程性带来了什么?研究团队通过一系列实例展示了它的边界在哪里——或者说,展示了它几乎没有边界。
第一类应用是控制多种具身智能体。研究团队用SPEAR控制了Epic Games多个样例项目中的六种不同智能体:CitySample项目里的行人和汽车、StackOBot项目里的飞行机器人、CropoutSample项目里资源采集游戏中的多个智能体、GameAnimationSample项目里的一个具有跑酷能力的人类角色和一只四足机器人。每种智能体的动作空间完全不同——开车、走路、飞行、奔跑跳跃——而SPEAR用同一套编程接口驾驭了它们全部,这在其他任何现有仿真工具中都无法实现。
第二类应用是操控虚幻引擎的程序化内容生成(PCG)系统。在Epic Games的ElectricDreams样例项目中,研究团队用SPEAR控制了场景里一个巨大的岩石结构的位置,让它从左移到右。神奇的是,引擎的程序化系统会自动根据岩石位置调整周边所有细节——水面绕着岩石流动,木头自动出现并与附近结构相连,整个场景始终保持和谐自洽。研究团队还用同一套接口控制了场景天光的朝向来模拟一天中不同时刻的光照变化。所有这些操作,都是通过几行Python代码完成的。
第三类应用是与MuJoCo物理仿真器的联合仿真(Co-simulation)。MuJoCo是一款专注于精确物理计算的仿真引擎,常用于机器人研究。研究团队建立了一个实时桥接系统:用户在MuJoCo的默认交互界面里操控场景(比如给一把椅子施加一个力),与此同时,SPEAR持续读取MuJoCo场景的状态,并实时更新对应虚幻引擎场景里物体的位置和姿态,使两个仿真世界保持同步。整套协同仿真的逻辑同样可以用SPEAR的`begin_frame`/`end_frame`编程模型干净地表达:在每个仿真步骤里,先禁用虚幻引擎自身的物理,循环执行MuJoCo的若干个子步骤,然后读取MuJoCo里每个物体的位姿,通过SPEAR更新到虚幻引擎里,最后渲染观测图像。这种设计让用户可以完全自定义物理子步数,非常灵活。
第四类应用是渲染同步多视角图像。研究团队用SPEAR配合MetaHumans样例项目(Epic Games推出的高精度数字人系统),在同一帧内同步渲染了同一个细节丰富的数字人角色的多个不同角度的图像。这类同步多视角数据在面部重建、神经辐射场(NeRF)等3D重建研究中非常有价值。
第五类应用是自然语言场景编辑。研究团队构建了一个AI编程助手系统,让视觉-语言大模型(Vision-and-Language Model)读取当前场景图像,根据用户的文字指令(如"把两把扶手椅挪近一些但不要完全接触"、"把地板变得尽可能亮"、"在沙发上方和扶手椅上方各放一盏明亮的聚光灯"),迭代编写SPEAR程序并执行,完成场景修改。整套系统运行流畅,这说明SPEAR对AI编程助手非常友好,因为它的接口和普通Python无异。
六、灵活的同步策略:一套模型,涵盖所有现有方案
SPEAR编程模型的另一个亮点是表达能力的强大:它可以用来实现现有各类仿真器中不同的时间同步策略,而每种策略都只需要几行代码。
AirSim采用"单步执行"模式,每次让引擎前进一帧然后等待Python;CARLA有同步和异步两种模式;UnrealCV+支持"批量命令",把多个操作打包成一次请求发送;Habitat 2.0使用"双缓冲观测"机制,在引擎渲染下一帧时Python就可以开始处理上一帧图像。研究团队在论文中明确展示了如何用SPEAR的`begin_frame`/`end_frame`机制,写出与上述每种方案功能完全等价的步骤函数(即OpenAI Gym风格的`step`函数)。此外,外部物理仿真器的联合仿真、用户自定义子步骤的物理更新,也都能自然地融入这套框架,不需要任何特殊处理。
这种统一性意味着,研究者不再需要为了换一种实验策略而切换到完全不同的仿真工具,只需要调整几行Python代码即可。
七、系统架构:幕后的精密工程
SPEAR采用客户端-服务器架构:Python程序作为客户端运行在一个进程里,虚幻引擎应用作为服务器运行在另一个进程里(可以是同一台机器,也可以是不同机器,通过TCP/IP连接)。
服务器端用rpclib实现(一个现代C++的远程过程调用库),客户端用nanobind实现(一个高效的C++/Python绑定工具)。这套组合让客户端可以像调用本地C++函数一样调用服务器上的入口点,类型安全有保障,性能开销极小。
服务器在虚幻引擎内部运行在一个独立的"服务器线程"上,这与大多数现有插件不同——现有插件通常在游戏主线程上响应命令,这意味着每次响应都要中断游戏主线程的正常执行。SPEAR的服务器线程可以独立响应Python命令,不需要打断游戏线程;当真正需要在游戏线程上执行操作时,服务器把任务放入两个线程安全队列(分别对应`begin_frame`和`end_frame`),游戏线程在每帧的特定时刻自动排空这些队列。
研究团队手工实现了193个专门的服务器入口点,用于暴露那些不在反射系统里的虚幻引擎功能(比如一些底层系统功能)以及反射系统本身。这193个入口点中,约75%专门用于暴露反射系统的各个方面,正是这些入口点让"用字符串动态访问任意反射可见函数"成为可能。每个同步版入口点都手工实现,其对应的异步版本则通过C++模板元编程自动生成,大幅减少了重复代码。
对于涉及大块数据传输的场景(比如渲染图像),SPEAR引入了一套名为"SpFunction"的自定义函数机制。任何虚幻引擎对象都可以在其组件层次结构中插入一个特殊子组件,并在运行时绑定命名函数到这个组件上;这些命名函数(SpFunction)在Python端看起来和普通的反射可见函数完全一样,但它们的输入输出可以是NumPy数组,而不只是JSON字符串。当SpFunction的调用到达客户端-服务器边界时,NumPy数组被映射为内部的"命名数据数组"表示;如果配合共享内存使用,这个过程完全不需要数据复制。
关于类型系统,虚幻引擎对"可反射类型"有严格限制:只有基本类型、字符串、指向UE对象的指针、部分容器、枚举,以及由上述类型递归组合的结构体,才能出现在反射函数的签名和成员变量里。这个限制反而带来了一个便利:反射类型都可以自动序列化和反序列化为JSON,而Python字典也可以轻松转换成JSON。两者的结构对齐,使得Python字典成为了SPEAR里传递函数参数和返回值的通用表示,用户在Python里直接写字典就能调用接受三维向量等复杂类型的UE函数。
**说到底,SPEAR在想什么**
归根结底,SPEAR解决了一个长期被忽视但确实很重要的工程问题:如何让研究者用最少的代码,对一个功能极其强大的引擎拥有最大的控制权,同时还能以接近引擎原生的速度获取渲染数据。
它没有把虚幻引擎包装成一个针对某种特定AI任务设计的专用工具,而是选择把引擎本身最完整地暴露出来,让用户根据自己的需要去决定要做什么。这种"宁可让用户写更多Python,也不预设用户的目标"的设计哲学,让SPEAR能同时服务于机器人仿真、自动驾驶、数据集生成、人脸渲染、场景编辑等看起来毫不相关的用途。
对于普通人来说,这项研究最直接的影响可能体现在:未来那些在城市里穿行的自动驾驶汽车、在仓库里作业的机器人、在医院里辅助手术的机械臂,很可能都在某个虚拟世界里训练了数百万小时,而这些虚拟世界就是由SPEAR这样的工具构建和控制的。光真实的仿真让AI在"假世界"里学到真本事,再把这些本事带进现实世界。
研究团队相信,SPEAR有潜力成为计算机视觉、机器人和具身AI领域的基础数据引擎,并在不远的将来,成为连接互联网规模视觉-语言大模型与虚幻引擎顶级虚拟世界的桥梁。这座桥一旦稳固,通往AI辅助内容创作、个性化娱乐和空间智能基础研究的大门,将会向更多人敞开。
有兴趣深入了解技术细节的读者,可以通过论文编号arXiv:2607.06701在arXiv平台查阅完整原文,项目的全部代码也在GitHub的spear-sim/spear仓库公开,可以自由探索。
---
Q&A
Q1:SPEAR和AirSim、CARLA这些仿真器有什么本质区别?
A:AirSim和CARLA是为特定用途(无人机/自动驾驶)定制的整体式仿真器,只开放了几百个固定接口,和引擎深度绑定。SPEAR是一个通用Python库加模块化插件,直接对接虚幻引擎的反射系统,暴露超过14,000个引擎函数,几乎可以控制任何虚幻引擎项目,不局限于某类任务或场景。
Q2:SPEAR的图像传输为什么能比其他工具快十几倍?
A:核心在于两项技术:异步通信让Python不用等引擎渲染完就能继续执行;进程间共享内存让渲染好的图像从GPU卸载后直接写入Python能读的内存区域,完全跳过了传统方式里多次数据复制的过程,图像传输速度因此大幅提升,在1920×1080分辨率下最高可达73帧/秒。
Q3:SPEAR暴露的那14,000多个虚幻引擎函数是怎么维护的,会随着引擎版本更新而失效吗?
A:这些函数不是手工维护的列表,而是通过SPEAR直接读取虚幻引擎反射系统的实时目录自动获得。只要虚幻引擎更新后某个函数仍然标注了UFUNCTION或UPROPERTY,SPEAR就会自动把它暴露给Python,不需要手动更新。新增的函数同理,天然就会出现在SPEAR可访问的范围里。