制作传统风格像素游戏时的几个陷阱

承认吧,我就是个保守派!

像素风格的游戏是在显示设备分辨率不足、颜色数有限的时代产生的特殊风格的游戏。这使得过去的像素游戏带有浓重的时代气息。今天的大多数像素游戏都是在支持高分辨率高发色数的引擎基础上开发,和传统像素游戏在风格上有明显区别。本文讨论传统像素游戏的一些特点,并且和当代像素游戏做比较,指出那些是传统游戏的风格,哪些是当代像素游戏的风格,哪些根本就是伪像素游戏。

当然,传统像素游戏和当代像素游戏的区别不表示制作者一定要遵循哪些惯例。游戏最终只要好看好玩就好了。不过当制作者想做一款复古的像素游戏时,以下的问题需要格外注意。

1. 分辨率和像素的问题

问题1:平移中的像素不对齐

很多游戏在制作的时候没有从像素游戏的来历出发,仍然按照高分辨率游戏的方法来做,只是把图片换成了低分辨率资源。这种权宜的做法会带来很多问题。

为了下文举例子方便,先认识下我们本期的朋友——内裤国王:

大家好

内裤国王是一个16×16像素大小的图片,愉快地生活在一个64×64的场景内:

今天的故事就发生在这里

现在,假设我们在某个设备上做这个游戏。我们不需要太高清的设备,就假设是个分辨率512×512的手机就好。那么所有资源在使用时都需要放大到8倍使用。

于是,现在内裤国王是一张128×128的图片,在512×512的屏幕坐标系内活动。

问题来了,因为屏幕分辨率很高,屏幕坐标的一个像素只相当于内裤国王一个像素大小的1/8。当内裤国王平滑移动时,很容易就会出现内裤国王的像素和背景像素不对齐的情况。

左:移动前 右:移动中

在游戏中动起来的对象会比静态时穿帮更明显。玩家不傻的话一眼就能看穿你是在用高清游戏的做法假装做一个复古的像素游戏。

移动得太平滑了……

确实有一些游戏就是这么做的。也不能说这么做就一无是处,因为这种平滑移动的质感有时候蛮有趣的。

限制对象的移动步长为资源像素的大小(在这个例子里,是8像素)可以基本解决这个问题,但对下一个问题无计可施。

问题2:旋转和缩放

如果图片发生旋转,问题会比平移更难以处理。例如在劈砍动作中旋转国王的武器:

劈砍!

像素不对齐已经到了可怕的地步。真正的像素游戏里剑旋转起来应该是这样的:

真正的剑

解决办法只有真的像传统游戏的做法那样手绘旋转过程中的每一帧,但是很没有效率。

可以想见,缩放也会遇到类似的问题。

2. 在问题变得更严重之前……

总结问题1和问题2,都是因为实际绘制的分辨率过高造成的的穿帮。那么我们换个思路,先模拟一下低分辨率的设备,把画面渲染到一个低分辨率的屏幕上,然后再放大显示在我们实际的屏幕上。从技术的角度就是先在一个低分辨率的 Render Texture 上绘制,然后再放大到屏幕上是不是就可以解决问题了?

还真可以!

仍然是刚才的例子。我们新建一个摄像机(以下称为像素摄像机)用来将场景绘制到低分辨率的 Render Texture 上。由于现在要绘制的场景大小是 64×64,所以将像素摄像机的 size 设为 32,然后为其 Target Texture 设置一个 64×64 的 Render Texure。将所有要绘制的场景放置在像素摄像机的视野内。

再在主摄像机视野内放置一个 Raw Image 用来将这个 Render Texture 放大显示出来。注意这个 Render Texture 的 Filter Mode 为 Point,因为更『高级』的过滤方式会把我们辛辛苦苦画出来的低分辨率像素图搞糊。

以下是效果:

像素对齐

图片在像素摄像机的视野内多么平滑缓慢地移动也没关系。因为 Render Texture 的 Filter Mode 为 Point,当图片移动小于0.5像素时,采样的结果如同没有移动;超过0.5像素时采样的结果如同移动了1像素。绝妙。

这里注意放入像素摄像机视野内的图片不要进行缩放,保证 Render Texture 内的每个像素都与放入像素摄像机视野内的图片的像素大小一致(理由见问题3)。将这个 Render Texture 再放大,就可以得到像素感强烈而且每个像素都对齐的最终效果了。

理论上用这种方法可以直接把一个3D场景渲染成2D像素风格游戏。实际上大多数像素游戏项目也是实现的同样思路。如果需要参考的话,可以看看 PixelCamera2D。这个项目提供了这样功能的摄像机,用Render Texture来实现将任何场景像素化的效果。

这么做是不是就一劳永逸了?也不是。至少存在一个技术性问题。

图片移动小于0.5像素时,采样的结果如同没有移动,超过0.5像素时采样的结果如同移动了1像素。当我们将内裤国王和他手里的剑正好0.5像素时……

两种错误

我在测试时使用了不同规格的图片,至少出现了上述两种错误。

  • 左图:国王和剑两张图同样移动半个像素时,一个向下取整一个向上取整导致了两者位置的错位
  • 右图:国王移动半个像素时,一部分像素被错误拉伸

我认为是采样精度的问题。实际上右图的错误发生在两张图的大小都不是2的幂的情况下,我把两张图的大小都限制为2的幂之后右图问题就消失了。

但是左图的错误发生在两张图都是 64×64 的时候。这个错误是这么出现的:首先我把国王和剑直接在场景中导出,因此他们都是 64×64 的透明背景的图片,只是有颜色的部分位置不同。把两张图坐标重合地放在场景中,一起移动。本来应该天衣无缝,结果出现了左图的错误。看起来在图片的不同位置采样的精度会有误差。

如果图片比较小,我认为限制长宽为2的幂(Power of 2)足以解决问题。如果是较大的图片,我能想到的最后的手段就是按整像素移动。(这样一点也不绝妙了啦!)

如果是自己维护坐标,那么只需要在最后设置坐标前把坐标取整。如果是动画,看看有没有对齐到整数的参数,比如如果用 DOTween 的话 snapping 属性可以设置结果对齐到整数。

这个小技术问题引发了另一个问题。以前的老游戏也经常出现这个瑕疵(或者不如说是故意利用这个瑕疵),这就是我们接下来要讨论的。

问题3:模糊闪烁的采样

如果在像素摄像机的视野内放置像素大小不同的图片,当移动它时,就会出现图片边缘一直在改变的情况。

比如下图这样在场景内放置一个太阳。这个太阳原图很大所以放进场景时被缩小了,这也导致它的一个像素比场景内其他图片的像素要小,因而也比 Render Texture 的像素要小。场景和渲染结果分别是这样的:

模糊闪烁的边缘

Render Texture 的一个像素中会包含很多太阳的像素,Render Texture 的每个像素采样到的是内部众多像素中的一个。太阳在移动时,像素激烈变化,因此采样出来的颜色也在激烈变化,渲染出的图片就非常不稳定。对于边缘,就是模糊变化,而对于内部的一些微小细节,就会忽隐忽现。

这其实不是任何 bug,低分辨率设备显示高分辨率的图像本来就是这样。在游戏中出现这种效果是一个很明确的信号——这个物体就是非像素对齐的,一般来说这意味着这个物体非常细腻以至于它的精度高于显示精度。

但是在非常古老的设备上是不会出现这种效果的。在FC或GB的年代,游戏对象的显示都是像素对齐的。受存储容量的限制,那个年代的游戏也不会尝试显示缩放的高清图像(更何况还要软采样)。不过到了SFC的时代随着硬件支持缩放,这种模模糊糊的采样就开始出现了。

这种效果在显示背景之类的表现氛围的场合其实还挺适合。这些场合不需要清晰的形状,而不稳定的采样恰好可以暗示物体的很多细节。通过模糊的闪烁的像素,玩家在低分辨率设备上也可以脑补一部分高精度的细节。

但是对于前景,尤其是操作人物或者可交互物体,这种效果就应该避免。因为清晰的边缘对玩家的判断非常重要。

通常在做2D游戏的时候我们不会轻易缩放图片,也就不会出现这个问题。不过,如果一个像素游戏是3D游戏实时渲染成2D的呢?或者至少一个2D游戏内有一部分物体是3D的,将它们像素化。这个时候就几乎一定会出现问题。

顺带一提,Dead Cells 的制作流程是先建立3D模型,调整动作,然后像素化生成帧动画。他们尽量减少颜色尽量避免对象内部的像素闪烁问题,但还是无法避免边缘的闪烁。他们的解决办法是:手动修图。

3. 颜色

问题4:过多的颜色

像素风格的游戏或者静态画给人以非常强烈的视觉冲击,一方面来源于低分辨率,另一方面来自于低颜色数。这种艺术形式的美来源于人对于特征明显但不清晰的物体进行的脑补,像素艺术归根究底是一种『受限制所以美』的艺术。如果不加限制会怎么样呢?

如果无限制提升分辨率,那么就越来越接近人眼的分辨率,物体形状变得越来越精细,这肯定不『像素』。无限制地提升颜色数呢?效果就是这样的:

颜色比较

左图为最初的场景,手绘的物体边缘『坚硬』。中间图不在乎颜色限制,随意使用渐变和光照,以及颜色边缘的抗锯齿。看起来只是分辨率低,并不具有浓厚的像素感。右图将中间图的颜色重新限制在调色板范围内,画面又重新具有像素感了。得益于抖动出来的渐变颜色,物体也更有体积感。

右边的场景兼具像素感和丰富的细节。这是因为它使用了抖动和(调色板限制下的)抗锯齿。这是绘制像素画的技巧,不在本文的讨论范围。事实上右图只是在PS里把中图套用了左图的调色板的结果,效果就已经非常好了,只需要再手动进行一些调整即可。

在绘制图像时我们很容易注意颜色数,但是在游戏开发过程中就容易忽略。这是因为我们现在用的引擎普遍没有限制颜色,容易让我们放飞自我。下面单独列出几个可能出现的问题,但其实它们都是颜色过多的衍生问题。

问题5:光

自从开始用3D引擎做2D游戏后,在2D图片上加动态光照就越来越常见。而自赛博朋克近年再次兴起之后,像素+霓虹灯&雾气的风潮变得愈演愈烈。

传统像素游戏一般只有环境光而不会有局部的光源,这一方面是因为颜色数量有限,另一方面也是因为计算光照的开销太大。传统游戏里要么不表现局部的光源,要么只对固定的光源提前绘制好光照效果,要么用遮罩来表现局部光源的照射范围(例如很多RPG在山洞中视野受到限制)。比如:

两种传统的光照表现方法

而在3D引擎下,对2D Sprite打光就像给3D物体打光一样。点光源的光照强度随着到光源的距离变化,会给照射到的图像带来很多颜色变化。

比如,我们让内裤国王来到一个赛博朋克的世界,那么传统的像素游戏和现在流行的像素游戏风格差别可能有这么大:

光污染、雾气,给画面带来了无比丰富的颜色

目前游戏的通常做法是把2D图像放到3D场景里然后在场景中加上光照直接渲染出来。为了让光照适应分辨率,除了之前提到的低分辨率渲染之外还可以用抖动来模拟光照的强弱,例如

光照强度的抖动表现

这个例子来自 2d-gamedemo-robodash。做法是对接受光照的地面施加密密麻麻的 dither pattern,每个 pattern 都是棋盘式交替排列的灰度像素构成的。再通过 dither pattern 和 render texture 分辨率不同来获得采样误差,从而获得有趣的网格抖动效果。我们在前面 render texure 的部分讨论过分辨率不相符可能带来的问题,这里则是巧妙利用了这个问题。
有趣的是更换不同的 pattern 可以获得宏观上的不同效果。改天单独写一篇介绍下这个效果吧。

有了光照很漂亮,不过这已经不是传统意义上的像素游戏了,只能叫做像素风格。(就像风味酸奶和酸奶的区别。)

但是真好看呀。我觉得现代像素游戏区分于传统像素游戏的主要不同就是大胆使用光照。

问题6:透明

透明在现代引擎里也是很常见的,只要我们设置透明度……

没有!

传统像素游戏和当代像素游戏的又一个不同就是像素透明度:

在没有透明度的时代只能对静态场景用特定的颜色搭配表达透明,现在就没有限制了

透明物体本质上是颜色融合的问题。在调色板的时代,颜色都是索引,从索引数字本身并不能知道颜色的RGB。如果我们要让索引颜色之间也可以融合,需要这么做:

  1. 先假设一个融合比例,比如50%。
  2. 构建一个表,假设调色板有N种颜色,这个表就是NxN大小。
  3. 表的每一项,比如A行B列,填上A、B两种颜色融合后的颜色索引,这需要先将AB两种颜色还原成RGB,再计算融合,然后在调色板里寻找和融合颜色最接近的颜色。
  4. 填好每一项之后,我们就获得了调色板中任意颜色在一半一半融合时的结果。
  5. 如果我们需要其他融合比例,就需要建立新的表。比如我们需要10%、20%……90%的融合,就需要9个表
  6. 当游戏中需要颜色融合时,查表。

这个听起来不是很现实,尤其是当调色板颜色比较多时(比如64种颜色……)。但如果我们不建立这样的表,在运行时手动计算每一次颜色融合,就更不现实。

我们来比较下各种透明的做法:

不限制颜色的透明

今天的像素游戏不用考虑颜色限制,透明可以非常平滑。

调色板限制的透明

在颜色有限的前提下,用近似的颜色表现颜色融合是可能的。但前后景随机或动态搭配的情况处理起来代价较高。通常只在预设的场景中使用预先调好的透明效果。。

用变色和删除线表现『逐渐消失』

传统像素游戏中表达『逐渐消失』的方法有很多,图中是其中一种。这种方法的优点是可以处理任何场景下任何物体的消失——靠玩家的脑补。

总结一下:半透明的对象非常漂亮,不过和光照类似,当游戏模拟非常复古的游戏时必须要考虑颜色数的问题。

另一方面,大胆在游戏中使用半透明也没什么大不了的。这个对观感的影响是较小的。

4. 总结

以上提出的这些问题其实体现了游戏硬件设备的进步给游戏画面带来的变化。最初人们使用低分辨率像素和低颜色数不是因为喜欢,而是因为没办法。随着设备的革新,分辨率上升、高精度的素材得以使用、颜色不再基于索引、颜色融合的开销也变得不再重要。

本文旨在分析传统的像素游戏与现在流行的像素风格游戏之间的区别,但并不觉得哪种风格更高级。如果你觉得现代的基于3D引擎带来的各种丰富效果正是你追求的,那么请尽情使用。好看就行。复古风格的像素游戏早已不是游戏界的主流,只受到一部分具有复古审美的人的喜爱,是小众中的小众。不用特意纠结过去与现在的差异——除非你就是要模拟复古,那就不能犯错误。

作为参考,近期比较完美的复古游戏是 The MessengerBloodstained: Curse of the Moon。这两款游戏对8位机画面的模拟非常到位。相对的,像 Dead Cells 就是非常典型的现代像素游戏了。但这并不影响三者都是非常成功好玩的像素风格游戏。毕竟画面风格只是画面表现效果的一个方面,而画面表现效果只是游戏表现的一个方面。

本文的低颜色数图片以 Aseprite 绘制,使用 AAP-64 调色板。高颜色数图片使用 Affinity Designer 绘制。
所以写本文的最大收获就是设定了一个新人物吗?!


相关文章:

Aya Magician:聊聊像素游戏的调色板

来源:知乎 www.zhihu.com

作者:Aya Magician

【知乎日报】千万用户的选择,做朋友圈里的新鲜事分享大牛。
点击下载