一个叫阿古斯蒂斯纳尔万的爸爸曾经从事游戏开发、计算机视觉、3D动画等工作。疫情期间,他为两岁半的儿子德希制作了一款名为格里芬的视觉互动游戏。
德赛的游戏体验
格里芬最初的意思是一只长着狮子身体和鹰脸的野兽。在《哈利波特》中,格兰芬多的意思是金色的格里芬。纳尔万的儿子德希非常喜欢老鹰,所以纳尔万就以格里芬为蓝本做了这样一款游戏。在Medium上,他公布了制作过程的细节,并公布了游戏的开源代码。本文主要研究生产过程。
传说中的格里芬
必备模块:3D游戏引擎;身体姿势的估计;动作映射和手势识别;通信系统。
所需硬件:NVIDIA捷信AGX Xavier;显示;索尼IMX327相机;通用磁带。
图为NVIDIA Jetson AGX Xavier、索尼IMX327相机和通用磁带
一、构建3D游戏引擎
Griffin系统从第三视角渲染3D世界,不仅可以看到鹰的翅膀与玩家同步摆动,还能更逼真地模拟真实飞行。专业的3D游戏引擎包括Unity和Unreal,但无法在Ubuntu OS或ARM上运行。于是,纳尔万找到了一个可以在OpenGL上运行的C开源飞行模拟器,并对其进行了一些修改。
首先,他把基于按钮的飞控系统改成了基于手势识别的飞控。
其次,他重建了静态三维模型,以适应鹰的身体结构。原来的飞机模型和鹰的区别是飞机是一个不变的机体,以机身为轴旋转,而鹰有一对活动的翅膀。因此,他使用3D绘图工具Blender改变了原机身的骨骼动画系统,将机翼作为两个独立的3D模型添加到机身中,作为鹰的翅膀。
在Blender中编辑的鹰的三维模型
然后,他设置不同的游戏状态,这样他就可以通过玩家的动作直接重启游戏。游戏中的鹰有两种状态,要么站在树枝上,要么在蓝天上飞翔。
最后他用libSFML添加了音效,当老鹰一起飞的时候,会伴随着老鹰的嚎叫和疾风。
二、建立身体姿势识别
该模块通过确认身体的各个部位,识别不同的身体姿势来表示不同的游戏指令。通过检测手臂的姿势和脸部的位置,系统可以确定玩家的具体姿势,触发动画中老鹰的动作效果。
它涉及一个名为OpenPose的开源库,其中包含了各种用于手势识别、姿势识别和人脸识别的AI模型,而纳尔万则使用了一个名为COCO的身体姿势模型。该模型包含18个骨节点捕捉器,可以实时识别人体的18个关节,Griffin使用了6个关节。
e178afad8" />
图丨 COCO 关节点图
OpenPose 建立在 PyTorch 框架之上,该框架在 NVIDIA AGX Xavier 中运行帧率很低,只有 4FPS。Nalwan 则使用 torch2trt 工具,将 PyTorch 模型移植到 TensorRT 中,大大加快了帧率,达到 100FPS。
图丨人体姿态识别
不过,该模型的关节识别有时候会出错,偶尔会识别到一些其他物件,而不是玩家本人。为此,Nalman 添加了辅助 AI 模型来解决这个问题,他使用 Amazon SageMaker JumpStart,这是 AWS 近日发布的一款工具,可以轻易在 TensorFlowHub 和 PyTorchHub 部署 AI 模型,一共有 150 多种型号可选。
图丨错误情况
这种 AI 辅助模型具有对象检测功能,可以确定玩家主体的边界框,这样系统就不会把一些杂物识别成人物关节了。
图丨人体边框以外的关节点被排除在外
三、构建动作映射和手势识别
该模块将通过玩家的 6 个关节识别出游戏的各种指令:
第一,身体倾斜。玩家通过倾斜身体控制鹰在飞行途中的转向。系统根据手臂与水平面的角度来计算倾斜程度,从而控制转向幅度。在这里 Nalwan 选择了肘关节作为参考点,而非腕关节,是因为腕关节常常出画或被遮挡。
第二,手臂旋转。在站立时旋转手臂,鹰也会跟着拨动翅膀,这单纯是一个趣味性互动画面。系统根据手肘与水平面的夹角计算鹰翼的倾角,同时再增加 15 度,使得画面更加生动。
图丨身体倾斜和手臂旋转的动作映射
第三,下蹲。这也是一个没有具体功能的动作,代表雄鹰起飞前的起势动作。系统计算颈部到鼻子的长度与肩膀长度的比例,作为蹲伏偏移量。蹲的幅度越大,颈部到鼻子的距离就越小,而肩膀长度不变。之所以不直接计算颈部到鼻子的长度,是因为玩家到相机的距离不同,这个长度也不同,会影响到就算结果,从而不能触发雄鹰的下蹲动作。
图丨下蹲动作映射
第四,起飞姿势。该姿势识别通过两肩的中心点的探测,如果在一秒内该点上下移动的幅度大于阈值,则判定为起飞姿势。触发起飞姿势后,雄鹰就会跳出树枝,腾空而起。
第五,重新启动姿势。当玩家转身背对相机,左右肩交换位置,系统判定为重新启动。重新启动后,雄鹰将再次站在树枝上,等待起飞。
图丨起飞和复位姿势识别
四、整合系统
在完成了上述三个模块的基础上,下一步就是把三者整合起来。连接关节识别模块和手势识别模块不难,因为两者都是由 Python 编写。但把这两者和 3D 引擎结合就出现了难题,因为 3D 引擎是由 C++ 编写的,而用 Python 访问 OpenGL 基本是不可能的。
为此,Nalwan 选择通过 socket 来整合该系统,这是 TCP 协议使用的一种低级通信机制。由于两个模块在同一电脑中运行,延迟将被控制在 5 毫秒以内。通信层由一个在 Python 应用中的客户端模块、和一个在 C++ 应用中的服务器模块组成。
图丨 Griffin 的整体架构图
一切准备好后,Nalwan 对 Griffin 系统进行了测试,在执行以上的节点捕捉、姿势识别和 3D 渲染的同时,整体的帧率达到 60FPS。
Nalwan 向儿子 Dexie 演示了如何玩这个游戏,儿子看着电视里的雄鹰和爸爸是一样的姿势,感到十分兴奋。Dexie 上手玩的时候,一下子就玩了半个小时,扮演着雄鹰的身份,在蓝天下翱翔、在峡谷里躲避。
图丨 Dexie 的飞行体验
对于 Nalwan 来说,这也是好事,一方面儿子玩的开心了,另一方面,儿子玩累了睡得很早,晚上 Nalwan 就不会被熊孩子打扰了。
在 Nalwan 看来,这次制作游戏的实践也让他受益匪浅,他总结了如下的一些收获。
1.Torch2trt 能自动将 PyTorch 模型移植到 TensorRT 中去,大大加快 AI 模型的运行速率。
2.NVIDIA Jetson AGX Xavier 性能非常强劲,可以连贯地运行包含 30 个实时 1080p 视频的视觉模型。
3.Amazon SageMaker JumpStart 提供了海量的流行 AI 模型供开发者使用。
4.构建 3D 游戏引擎让他回忆起了之前作为游戏和电影 SFX 开发者的身份,刷新了对自己 OpenGL、C++ 和计算机图形学能力的认知。
5. 他本可以通过 Unity Engine 和 Kinect sensor 在 Xbox 中构建 Griffin,但是自己动手 DIY 一个游戏远比这有趣得多。
6. 在游戏里扮演一只老鹰是很累人的,要一直举着自己的手臂。然而,真正的老鹰会借助气流,保持它们滑翔的姿态。