每个角色在GRAYFALL中都是由Python渲染器生成的:姿势是一个关节角度的字典,形状在4倍分辨率下被纹理化,然后使用模式下采样降低分辨率,形成清晰的像素。两个gif随着这篇文章一起发布。

我们没有通过争论来选择风格https://i.redd.it/ob7hn81qjwth1.gif

我们最初的角色形象很弱:平面脸,机器人动画,缺乏身份。我们没有争论参考,而是从零开始写了四个完整的渲染器,每个渲染器都渲染了相同的角色(女巫,女巫,女巫,女巫)和相同的动画——静止,走,跑,三击组合,投掷和受伤——加上一个肖像,一个关键艺术卡和一个注释文件,讨论其优缺点。

|候选人|比例|高度|成本| |:-|:-|:-|:-| |HD-2D 16位(Octopath样式)|1:4|约50px|屏幕上6个玩家无法阅读| |Chibi(Young Souls样式)|1:2.5|约60px|可爱,但攻击姿势不够| |绘画(Odin Sphere样式)|1:6|约100px|非常漂亮,但每帧的成本太高| |Arcade hi-bit(KOF / Metal Slug)|1:4.6|约80px|发货|

实验室是这个项目最便宜的决定:四个可抛弃的渲染器的成本低于一个错误的风格应用于20个角色。输掉的三个输出仍然在仓库中——没有任何内容被删除,比较仍然解决了几个月后的争论。

# 如何制作一帧https://i.redd.it/0au72usujwth1.gif

没有任何绘图程序参与这个链条。Python,Pillow和numpy只用来做这些事情。

  1. 姿势是一个角度的字典。lean,twist,肩部角度,握持位置沿着法杖。一个IK求解器从手和脚目标中放置肘部和膝盖,因此我动画意图,而不是肢体。
  2. 形状在4倍分辨率下被纹理化。胶囊,带状和Catmull-Rom曲线写入三个缓冲区中:材质,调色板和部件ID。
  3. 阴影效果是一个遮罩偏移。每种材质都有5种调色板。将部件的遮罩向一个固定光源偏移,未被遮掩的带状变成下一个调色板。第二次,较长的偏移给出了深调;向相反方向偏移则创建了高光。部件也会在它们后面的内容上投射阴影。
  4. 通过多数投票进行下采样。每个4x4块都取了最常见的(部件,材质,调色板)关键。没有平均值,没有抗锯齿,所以结果是一个真正的像素图像,而不是缩小的渲染。
  5. 内部线。只有当两个不同部件相互接触时才写入一个暗色边缘——臂膀覆盖胸部,而不是臂膀覆盖臂膀。
  6. 一个像素的黑色轮廓周围的身体,FX除外。这个轮廓是使角色在640x360的光源3D舞台上可读的。
  7. 脸部是在下采样后绘制的,以像素为单位,最后分辨率。眼睛和嘴巴是1-2个像素的特征;如果它们通过4x4投票,那么它们就会变成糟糕的样子。这是“hi-bit”和“娃娃”之间的单个最大差异。
  8. 正常图案是生成的,而不是绘制的,并且3D舞台将2D角色上的它们照亮。
  9. 头发和布料是弹簧。带有休息角度,刚度,重力,阻尼和风的链条,根据每个帧进行模拟。次要运动从来不通过手动键入——它会从模拟中跌出,这就是为什么它看起来不会粘在身上。
  10. 关键帧和子帧是两回事。攻击框架在关键帧上触发(游戏的逻辑可以理解的帧)。子帧纯粹是为了平滑度而插入的,游戏逻辑从来不会看到它们。

# 为什么编码,并且使其安全的合同

手绘帧在这个规模上是一个死胡同:20个可玩的英雄,每个英雄约50个动画,6个玩家在屏幕上。胜利不是速度,而是传播。改变阴影规则,每个帧的每个角色都会得到它。重新设计一个英雄的外套,50个动画也会重新设计。危险显而易见:重新生成艺术就会打破每个攻击框架。因此,每个角色都有一个冻结的合同——一个JSON动画名称的快照,动画的逻辑帧数,和每个帧的时间预算。渲染器可以更改姿势,添加子帧,重新绘制整个服装。它不能更改合同。游戏始终会索引punch2的第3帧,并将其击中。每个帧也会导出锚点:手,手方向,手,头,胸,武器尖端。尾迹,火花,弹丸和持有的道具会附着在这些锚点上,所以VFX从来不会在动画重新绘制时漂移出手。

# 入口:一个脚本告诉我一个角色还没有完成

“看起来很好”不再是标准时,质量提高了。qa_hero.py <id> 将每个英雄的一行打印出来,并将其与固定的阈值进行比较。

|指标|最小值|存在的原因| |:-|:-|:-| |动画|50|一个角色缺乏起立,晕倒或携带时会感到破碎,而不是时尚| |逻辑帧|195|所有50个帧的底座| |流动性(子帧/逻辑帧)|0.85|这是一个“平滑”的数字| |攻击帧|5|预期,接触,追击,恢复——三个姿势不算是一个攻击| |攻击帧中的一帧被持有者至少6个时间戳|是的|没有被持有的接触帧,攻击就会“滑行”而不是落地| |独特的特殊|12|4个默认值加上商店替代品| |3D VFX调用|30|一个特殊动作没有音量时看起来像贴纸| |FX条/ SFX文件|24 / 28|没有共享的通用击中闪烁| |元素色调匹配|70%|一名火元素的效果是蓝色而不是火元素|

今天,20个英雄的阵容中,有7个通过了,13个失败了。这是真实状态,我每周都会发布它。脚本是底线,而不是天花板:通过每个数字并仍然看起来很糟糕是失败。第二部分的审查是通过眼睛打开的联系单——纯黑色的轮廓可读,身体停止后仍然移动的次要运动,脸部的表情在静止,击中和胜利之间改变,尾迹细长透明,和大小检查(任何大于8%的阵容中92px的中位数就像孩子站在一起一样看起来很孩子气)。

# 五条规则,花费了我们实实在在的钱来学习

能力必须是一个可以绘制的对象,而不是一个可以描述的效果。

一个角色烧掉了三轮重新设计。她的套件是“地板上的影子”,“敌人3秒无法命中”,“冷火”。没有什么可绘制的,所以每个尝试都回到了紫色糟糕的状态,美化无法解决概念问题。被每个人赞扬的角色都有名词:一个巨大的顶帽子,一个切割盒子,鸽子,扇子,一个聚光灯,一个冰锥,一个彗星,一个火环。

我现在在任何生产开始之前都会进行的测试:描述能力而不使用“效果”一词,且不使用任何颜色形容词。如果一个名词通过了这个测试,一名draughtsman可以从记忆中绘制它,建造它。

大形状是固色最差的位置。

圆顶,窗帘,地环和光环都是自然而大,添加性混合会将其核心扩展到白色。6个玩家在屏幕上时,一个特殊动作会像这样会消除整个战斗。绘制可读的外壳,中间留空,永远不要将英雄隐藏在自己的效果中。

发射器需要一个明确的发射高度。

抛物线衰退正在根据击中时间不同的击中时间进行缩放,因此相同的动作会在不同高度上发射,并且空中组合只有“有时”会关闭。