Jesper Vos 和 Jack KMkota0 为Resn 撰写的文章 。

2018年8月3日,HBO播出了《飞行随机行动》的第一集 ,这是艺术家特伦斯·南斯(Terence Nance)的最新深夜系列。 HBO将节目描述为“对当代美国生活的流动,意识流考察”。
该系列的第2集描绘了该剧的主要角色在玩名为Kekubian Assassin的街机游戏。 为了推广该系列,HBO委托Resn制作了一个版本的《 Kekubian刺客》 ,任何人都可以在智能手机上播放。
在本文中,我们将带您解决制作此迷你游戏时遇到的一些挑战。
该系列的每一集都具有相互联系的小插曲,使其成为vérité纪录片,音乐表演,超现实主义情节剧和幽默动画的独特组合。 我们也希望游戏也具有多种风格,因此我们将摄影纹理混合在建筑物上以及长凳,黄色出租车和其他道具的低聚物体上。 我们以迷幻的,非裔未来主义者的主题来封装所有这些内容。


球形地面不仅有助于视觉风格,还可以在减少场景中物体的数量的同时,给人一种无尽世界的错觉。 由于远离相机的物体会被地面覆盖,因此我们不需要同时渲染两个以上的块。 为了创建这种类型的设置,我们需要在世界范围内投影块。
地面-包括转弯的道路,公园小径以及室内瓷砖地板-使用顶视图正交摄影机渲染到画布目标上。 每帧都会更新,以匹配世界范围。 渲染目标纹理用作球体的贴图,该贴图的UV位置战略性地位于顶部。
实例化的世界对象(建筑物,树木,灯,长凳等)实时投影在球体上。 首先,使用半圆函数计算位置。 然后,调整旋转以匹配从球体中心到重新定位的对象的矢量方向(将该方向四元数与原始旋转相乘)。
最后,为了放大深度的视觉效果,我们向某些对象材质添加了衰减效果。 当物体离摄像机越远时,它可以作为颜色叠加层以更高的强度混合在物体纹理上。


我们的工作流程始于在Cinema4D中创建低多边形模型,并以包含预支持照明的微小纹理导出它们。 感谢Mixamo,我们将骨架添加到模型中,并使用Blender,每个角色导出一个GLTF。 使用Mixamo,我们还可以向其中一个角色添加多达30个动画。 不幸的是,Mixamo一次只能导出一个动画,因此它们需要在Blender中作为NLA轨道进行组合,并作为单个GLTF导出[本教程是救生员,而且由于此分叉–现在已合并–我们可以导出所有动画。动画放入同一文件]。
结果,我们有:
- 9个字符作为蒙皮网格物体导出,没有动画[每个〜350kb]。
- 1个字符作为蒙皮网格导出,并输出30个动画[8mb]。
为了在角色之间共享动画,我们需要重命名所有导入的骨骼以匹配AnimationTracks中定义的骨骼,否则THREE.AnimationMixer将找不到合适的节点进行动画处理。 我们还删除了所有骨骼位置轨迹,因为我们只需要骨骼旋转-否则,孩子的伸展时间将与成年人一样长!



现在,我们可以穿越一个拥有各种角色的无限世界,我们需要强调谁在烦人,谁应该一个人呆着。 我们形象化了带有气泡的微侵略的概念。 一个简单的JSON文件存储了22个与特定角色和动画相关的侮辱。 例如,白人女孩在扭动时只会说“你能扭动吗?”,而在她做另一个手势时,相同的角色可能会说“来吧!”。
然后,将气泡的显示和隐藏方法连接到角色的状态。 在友好角色上,气泡永远不会显示,而在其他角色上,气泡只有在触发“侮辱”动画后才会显示。 轻敲角色时头部上方没有气泡的角色,或者不轻敲具有攻击性的角色将使玩家丧命。




我们首先开始为背景进行圆形位移。 在研究了一些不同的方法之后,我们决定使用流程图。 这只是一个包含扭曲的UV坐标的纹理,我们可以在片段着色器中使用它。 为了在黑洞的不同状态之间建立动画,我们只需要在原始UV和流程图中变形的UV之间进行插值。
为了营造一个无限旋转的宇宙的错觉,我们复制了具有180°偏移量的背景纹理,并在两者之间不断进行淡入淡出,同时在每个序列的原始UV和流图UV之间进行插值。
为了使老板级别更具动态性,我们使角色成为交互式模型。 为了能够从身体上单独旋转头部,我们需要将这些部分设置为单独的网格,但是由于我们之前制作的所有字符都由单个网格组成,因此我们必须为老板角色进行单独的导出。 我们还通过从小腿上切下几何形状来优化这些模型,因为无论如何它们永远都不会被看见……我们给他戴了顶帽子。



现在,我们在游戏中有了一个交互式3d模型,我们不能仅对背景应用相同的UV扭曲-为此,我们需要一个纹理。 幸运的是,我们可以使用帧缓冲区(Three.js中的RenderTarget)将任何场景转换为纹理。 我们对该纹理应用了与背景相同的UV扭曲,只是没有添加无限循环的旋转,而是添加了一些简单的窦性位移。

现在,我们在WebGL中拥有了所有可用的内容,我们渲染了我们想要过渡到渲染目标的UI视图。 在着色器中,我们将此纹理输出与旋转金字塔的纹理合并-在另一个渲染目标中渲染。 现在,我们可以将UI纹理的颜色和Alpha与金字塔颜色混合,以创建蒙版。



大多数视图需要金字塔垂直平移。 很快,我们注意到透视相机不允许我们移动几何而不丢失其前视图。 为了解决这个问题,我们改为对渲染目标纹理的UV进行动画处理。
完成体验的最后一件事是为游戏添加声音。 我们将音频分为三层:背景音乐,环境音频和角色效果。 对于后者,我们使用了与角色动画类似的系统-一个JSON文件,将音频文件连接到角色及其手势。 为了使音频与游戏保持同步,我们还将其与全局游戏速度联系在一起。
为了使其更具动态性,我们还将每个角色的声音效果的音量与它们与相机的距离相关联。 就像在现实生活中一样,现在靠近相机的角色比远处的角色发出更大的噪音。
作为我们的第一个带有动画角色的3D游戏,《库库比亚刺客》对我们来说是一个很大的学习曲线。 团队接受了这些挑战,并有动力使所有工作及时进行。 有了从这个项目中学到的一切,我们就很乐意做出更多游戏和3D体验。
Jesper Vos 和 Jack KMkota0 为Resn 撰写的文章 。