转载:2D Pixel Perfect:使用Unity创建任天堂红白机风格复古游戏

作者:转载小公举
2019-04-08
36 41 1

本文转载自 Unity 官方平台,已获得授权。

正文

拥有简单机制和像素图形的复古游戏,可以勾起老玩家很多美好的回忆,同时也会给年轻玩家带来亲切感。

许多游戏都带有“复古”的标签,但创作一款带有怀旧外观和感觉的游戏需要不少精力和构思,因此我们邀请了 Mega Cat Studios 的开发团队来探讨这个话题。

本文,我们将介绍创作任天堂红白机风格游戏美术所要了解的知识,包括重要的 Unity 设置,图形结构和调色板。

请下载本文的示例项目:

项目文件

Google Drive获取

Mega Cat Studios

来自美国宾夕法尼亚州的 Mega Cat Studios 将还原度极高的复古游戏变成了一种艺术形式。他们的多款游戏也提供实体卡带的形式,能够运行于 Sega Genesis 等复古游戏机上。

下面是分别为 Mega Cat Studios 开发的《Little Medusa》和《Coffee Crisis》。

实现复古效果的 Unity 工作流程

Unity 工作流程近来加入的新功能使 Unity 成为了适合开发复古游戏的环境。

2D Tilemap 系统越来越强大,已支持网格,六边形和等距 Tilemap。我们也可以使用全新的 Pixel Perfect Camera 组件,实现稳定的像素动作和视觉效果。

我们甚至可以使用 Post Processing Stack 后期处理特效保来添加炫酷的复古画面效果。但首先我们必须正确的导入和设置资源。

准备精灵资源

首先,我们需要对资源进行正确的配置,以得到清晰简洁的效果。

对于每个需要使用的资源,请在项目窗口选中资源,然后在检视窗口修改以下设置:

  • Filter Mode 改为 Point
  • Compression 改为 None

其它 Filter Mode 会产生略为模糊的图像,这会破坏我们希望得到的清晰像素艺术风格。

如果使用压缩功能,图像的数据会被压缩,这会导致原始图像的精度损失。请特别注意,因为压缩功能会造成部分像素改变颜色,从而可能会改变整体调色板的效果。

精灵的颜色越少且尺寸越小,压缩造成的视效差异越大。如下图所示,左侧图片是普通压缩效果,右侧图片是未使用压缩的。我们可以看见右侧的图片更符合原始图像的效果。

我们还要注意检视窗口中图像的 Max Size 设置。如果精灵图像在任何轴的大小都大于 Max Size 属性,图像会自动调整为最大大小。

这会导致图像质量下降,使图像变得模糊。由于部分硬件不正确支持轴上大于 2048 的纹理,我们最好把大小保持在 2048 的限制内。

下图是示例项目中精灵图集的精灵,左侧图片轴上的大小为 2208,最大值设为 2048。可以看出,右侧图片把 Max Size 属性提高到 4096 会正确地调整图像大小,避免画面质量损失。

最后在准备精灵或精灵图集时,请确保把 Pivot Unit Mode 设为 Pixels,而不是 Normalized。

精灵的轴心点会取决于像素,而不是取决于图像上每个轴从0到1的平滑范围。如果精灵不根据像素确定轴心,像素清晰度会下降。

我们可以在精灵编辑器为精灵设置轴心。选中精灵资源,在检视窗口单击 Sprite Editor 按钮,如下图所示。

安装 2D Pixel Perfect 资源包

准备好资源后,我们可以设置摄像机为“完美像素”类型。完美像素的效果应该看起来简洁而清晰。未能呈现完美像素的像素特征包括:模糊效果,以及部分像素本应为正方形,但却呈现为长方形。

2D Pixel Perfect 资源包可以通过 Unity 资源包管理器导入。单击工具栏的 Window 菜单,然后单击 Package Manager 选项。

在新窗口中,单击 Advanced,勾选“Show preview packages”。从左侧列表选择 2D Pixel Perfect,在窗口右上角单击 Install 按钮。这样便完成了导入过程,已经准备好使用 Pixel Perfect Camera 组件。

高级的完美像素的高级设置程度

将 Pixel Perfect Camera 组件添加到 Unity 的 Camera 对象上,它会加强 Camera 对象的功能。

我们选中 Main Camera 对象,给该对象添加 Pixel Perfect Camera 组件。

现在我们查看可以使用的设置。

首先建议查看“Run In Edit Mode”,把游戏视图内的画面宽高比设为“Free Aspect”,以便随意调整游戏视图的大小。

Pixel Perfect Camera 组件会在游戏视图显示帮助信息,以确定显示画面是否在特定分辨率下有完美像素效果。

现在我们可以查看每个属性,了解它们的功能以及对游戏外观的影响。

 

Assets Pixels Per Unit

Assets Pixels Per Unit(每个单位的资源像素量)对应每个资源检视窗口的相应设置。在游戏的世界空间使用的资源都应该使用相同的 Pixels Per Unit 单位像素量,即 PPU。我们应该将该值填入 Assets Pixels Per Unit 字段。

如果游戏世界的形式为瓦片和精灵的网格,每个网格的大小为 16*16 像素,我们应该把 Pixels Per Unit 设为 16,因为每个网格瓦片在世界空间坐标系中为 1 个单位。请在此设置正确的 Pixels Per Unit 值。

 

Reference Resolution

Reference Resolution(参考分辨率)将设置为你要在查看所有资源的分辨率。

如果想实现复古外观,通常要设为很小的分辨率,例如:Sega Genesis 游戏机的原始分辨率大小为 320×224。

当从 Sega Genesis 游戏机移植游戏时,我们会使用 320×224 大小的参考分辨率。对于 16:9 的使用情况,我们可以设为 320×180 和 398×224。

 

Upscale Render Texture

Upscale Render Texture(调整渲染纹理)这项设置会使场景在渲染时尽可能接近参考分辨率,然后进行调整以符合实际显示大小。

由于这项设置会产生填充画面,所以我们建议在实现无边框的全屏完美像素体验时使用。Upscale Render Texture 也会显著影响精灵旋转时的效果。

我们观看下图中的对比效果图:

  • 图 1 是原始效果,未旋转。
  • 图 2 未启用 Upscale Render Texture,旋转 45 度,我们会发现像素清晰度下降,这是因为斜边的像素大小会发生变化。
  • 图 3 启用 Upscale Render Texture,旋转 45 度。图像会保持原来的像素清晰度,因为所有像素都大小相同,但是和原始效果相比,精灵外观的准确度下降了。

Snapping

Snapping (像素对齐)仅在禁用 Upscale Render Texture 时可用。启用该功能时,精灵渲染器会自动对齐到世界空间网格,网格大小取决于 PPU 值。

Snapping 不会影响任何对象的 Transform Position 属性,因此我们可以平滑地在位置间插补对象,但移动效果仍可保持完美像素和简洁的特点。

下面是启用和仅用 Pixel Snapping 的对比效果:

  • 左侧图片禁用 Pixel Snapping,由于背景位于(0, 0),角色精灵位于(1.075, 0),部分像素没有正确对齐,有部分像素仅被阴影覆盖了一半。
  • 右侧图片启用 Pixel Snapping,背景位于(0, 0),角色精灵位于(1.075, 0),位置和原来一致,但像素仍然完美的互相对齐。


Crop Frame (X and Y)

Crop Frame (X and Y) (剪裁边框)会剪裁世界空间的观察区域,使其正好符合参考分辨率,而且它会对画面添加黑色边框,以填充屏幕边缘的空隙。

 

Stretch Fill

Stretch Fill(拉伸填充)会使摄像机根据游戏视图调整大小,从而在维持宽高比的同时适应屏幕。如果在 X 轴和 Y 轴都启用了 Crop Frame,便可以使用该功能。

因为这种大小调整不会仅在变为参考分辨率的整数倍数,所以如果分辨率不是参考分辨率的整数倍数,该功能会造成像素清晰度下降。 

但优点是即使在一些分辨率下会降低像素清晰度,我们也不会得到黑色边框,而是得到完全填充的屏幕。

我们需要注意,虽然拉伸填充经常造成模糊,但是不会显示常见的警告信息。如下图所示,角色和背景由于使用拉伸填充而模糊。

使用 Pixel Perfect Camera 的建议

如果我们希望得到完美像素和简洁的显示效果,并使该效果适用于各种用例,下面里有几点建议:

 

  • 使用的参考分辨率不大于播放器的窗口分辨率,例如:320×180。
  • 启用或禁用 Upscale Render Texture

    如果使用90度,180度和270度之外的旋转角,而且对旋转精灵的视觉效果满意,请启用 Upscale Render Texture。

    Upscale Render Texture 在部分分辨率下会得到非完美像素的图像,具体取决于参考分辨率。

    在 Pixel Perfect Camera 组件启用 Run in Edit Mode 时,请尝试不同的屏幕分辨率,以决定它是否会对分辨率造成负面影响。如果我们能让它对所有目标分辨率都产生完美像素图像,这将带来最佳全屏完美像素体验。

  • 根据偏好启用或禁用 Pixel Snapping。这项设置更多地取决于个人喜好偏好,没有对齐功能时,我们会得到更流畅的运动效果,但像素可能会不对齐。
  • 如果不使用 Upscale Render Texture,可以勾选 Crop Frame 的 X 或 Y,也可以同时勾选二者。

    如果无法通过 Upscale Render Texture 稳定地得到完美像素结果,裁剪 X 轴或 Y 轴会为任何大于 Reference Resolution 的分辨率取得完美像素图像,但是会在部分分辨率下的屏幕边缘出现较大边框。

  • 禁用 Stretch Fill

我们建议将摄像机设置为16:9的宽高比视图查看,并进行优化。 

大多数玩家在 16:9 的屏幕运行游戏,分辨率多为 1920×1080,例如:参考分辨率为 320×180 时,宽高比为 16:9,因此当游戏运行在 1920×1080 分辨率,或 320×180 的偶数倍数分辨率时,例如:1280×720 时,不会出现黑色边框。

在 Unity 的工具栏中,我们可以点击 Edit > Project Settings > Player,限制游戏支持的宽高比。如果发现某个适用于目标宽高比的特别配置,但它在部分宽高比下效果不好,我们可以在此避免让窗口使用这些宽高比。

然而并非所有用户都有适合这些限制的显示设置,因此建议的处理方法是启用剪裁功能,这样用户会看到边框,而不是必须在不适合屏幕的分辨率下运行游戏。

创作任天堂红白机风格的美术效果

我们介绍了如何为完美像素美术设置 Unity,下面将介绍创作游戏美术的基础知识,使游戏遵循经典的红白机风格限制。

红白机对创作图像的艺术家带来了大量限制,这些限制包括:使用的调色板,屏幕上对象的大小和数量。在面向这款游戏机开发时,参考分辨率为 256×240。

 

调色板

在创作符合红白机风格的美术时,艺术家必须遵循许多限制。无论艺术家打算模仿哪款复古游戏机,有一部分限制是相同的,而其它限制则特定于红白机本身。

首先,最重要的限制在于图像中调色板的使用。对于调色板而言,红白机的调色板比较特别,因为游戏机的完整调色板会硬编码到游戏机上。

红白机选择图像使用的颜色时,会发送一组数值到红白机的图形处理器,然后图像处理返回和数值相关的颜色。

下图是红白机的调色板。

这些颜色无法修改,它们是红白机的一部分,红白机的所有游戏都使用这些颜色的组合来实现图像。


子调色板

为了创作游戏使用的颜色组合,我们将创建子调色板并指定到游戏精灵或背景元素

 

红白机可以将其调色板分离为子调色板,指定到精灵和背景上。每个子调色板包含一种在所有子调色板使用的常用颜色和三种特别的颜色。

红白机能为背景和精灵分别加载四个子调色板。对于精灵而言,每个子调色板开始的常用颜色会视作透明度。

下图是游戏中使用的一组子调色板示例。顶行表示背景的子调色板,底行表示精灵的子调色板。

本示例中,黑色是所有子调色板共享的常用颜色。因为常用颜色被视作精灵的透明度,我们需要使用第二个黑色调色板作为精灵子调色板,从而把黑色用作可见颜色。

 

指定子调色板

随着艺术家了解如何在游戏中使用调色板,调色板的使用限制会更加严格。为了解释这一点,我们需要进一步讨论复古游戏机如何保存,使用和显示美术。

任何复古游戏机的美术在游戏中保存为 8×8 像素的瓦片,使用这些基于瓦片的方法可以让艺术家通过为不同内容重用瓦片来节省空间,例如:人行道部分可以重用为建筑上的窗台。

关于基于瓦片的保存,需要注意的一个重要是想是颜色信息通常不和图形一起保存,所有瓦片都使用单色调色板保存。因此无论何时瓦片在游戏中显示,都可以给它指定子调色板,使相同的瓦片通过不同的子调色板同时显示在屏幕上。在现代平台创作复古游戏机风格的美术时,这种做法的效果很明显。

红白机对精灵和背景有不同的调色板指定方法,它会逐个瓦片为精灵指定子调色板,这意味着精灵中的每个 8×8 瓦片可以指定四个子调色板中一个。

下图的忍者角色使用了二个子调色板,来赋予它更大的色彩深度。右侧图片中,我们可以看到画面分为独立的 8×8 精灵瓦片。 

通过这种分离视图,我们发现剑上和头巾上使用的浅绿色和深红色使用了特别的瓦片,同时深紫色和黑色轮廓部分用于剩下的三个瓦片部分。

另一方面,背景的使用更加严格,背景会在 16×16 大小的部分指定调色板。为整个画面背景部分的子调色板指定情况被称为属性表。

属性表是大多数复古美术大量使用重复平铺部分的原因,这些部分一般由16×16的瓦片组成,因此它们整齐地符合属性表。

尽管要考虑硬件限制,但是16×16大小且基于瓦片的背景处理方法成为了复古美术的决定性特点,在模仿复古美术时艺术家必须遵循这种特点。

下图是一个 RPG 风格城镇背景的示例,它遵循前面所讲的限制。右侧图片是分为16×16像素块的效果,调色板会根据每个像素块选取。

房顶瓦片,草地和桥上的砖块由像素块的重复部分组成,以节省使用空间。较小建筑的房顶瓦片都使用相同的瓦片,但是指定了不同的子调色板,使它们有不同的效果。

精灵分层

尽管艺术家可以为精灵的每个 8×8 瓦片使用不同的子调色板,但他们可能会发现自己希望为精灵提供比可用效果更好的颜色深度,我们可以使用 Sprite Layering(精灵分层)功能。

精灵分层会把精灵分为 2 个单独的精灵,然后重叠放置2个精灵,这允许艺术家避免在每个 8×8 瓦片只使用一个子调色板的限制。这样做会允许艺术家将单个 8×8 区域可以使用的颜色增加多一倍。

这种做法的唯一缺点是精灵的渲染限制。红白机仅支持同时在画面上显示 64 个 8×8 精灵瓦片,而且只能在同一水平线上显示 8 个精灵瓦片。当达到数量限制时,其它精灵瓦片不会在画面中渲染。

这就是为什么在画面中同时出现大量精灵时,很多红白机游戏会闪烁精灵,它只会在替换帧显示特定精灵。当对精灵进行分层时,这些限制都是艺术家需要考虑的内容,因为虽然这种会加倍颜色的数量,但它也会加倍相同水平线上的精灵瓦片数量。

下图是精灵分层的实际效果。最左侧的图片是海盗亡魂精灵的原始版本,它只有三种颜色,艺术家将该图片分离为身体/帽子和面部/手部二个部分,然后给这些部分指定不同的调色板。最后我们可以看见分层处理二个部分叠加后的效果。

精灵分层功能也可以处理背景,从而解决属性表的限制。这个技巧通常用于静态图像,例如故事画面和角色形象,使它们有更好的颜色深度。

为了实现这种效果,艺术家需要绘制部分图像作为背景,然后在背景上放置分层精灵以填补剩余部分。

海盗亡魂的形象也使用了精灵分层功能,从而得到更好的深度。绿色骷髅在画面中被渲染为精灵,而他的衣领和帽子被渲染为背景的一部分。这样可以使艺术家在 16×16 区域内使用更多颜色,从整体上解决属性表的限制。

图形库

为了讲解红白机的下一个主要限制,首先要记住红白机以瓦片的形式保存图形。图形瓦片保存在 256 个瓦片页面中,这些页面的瓦片无法加载到 VRAM 的不同位置,因此很难在运行中即时混合和匹配不同页面的瓦片。

红白机的 VRAM 仅支持同时显示 512 个这类瓦片。超过这个限制,它会把瓦片数量对半分开,分别用于精灵和背景,这也意味着红白机只能同时显示 256 个精灵瓦片和 256 个背景瓦片。如果艺术家想显示多种精灵和背景元素,这种处理会产生很大的限制。

下图是加载到 VRAM 中的游戏背景和精灵瓦片的可视化效果。游戏机会保持背景和精灵加载在独立的页面。

为了解决这种限制,红白机有一项功能允许艺术家将每个页面分离为称作图形库(Banks)的局部页面。因此,尽管红白机不支持从图形数据的多个部分加载独立的瓦片,但它支持在不同时间加载不同的页面部分。

对于大多数游戏而言,图形库分为 1K 图形库和 2K 图形库,1K 图形库等同于页面的四分之一,即 64 个瓦片,2K 图形库等同于页面的一半,即 128 个瓦片。

艺术家必须决定是否为精灵或背景保留每种类型图形库的使用,因为使用二种类型的图形库,这意味着无法为精灵和背景都使用1K 图形库。一个页面需要使用 1K 图形库,另一个页面需要使用 2K 图形库。

通常,多数游戏会为精灵使用 1K 图形库,为背景使用 2K 图形库,因为背景的瓦片集更为静态,即时变化更少。

下图显示了图像划分为图形库的方法。左侧的背景部分使用2K 图形库,它会从中间划分图像,而右侧的精灵部分使用 1K 图形库。每个图形库都可以即时交换。

精灵的1K 图形库实用性非常明显。如果玩家精灵拥有大量不符合单个页面的动画以及其它需要加载的精灵,则可以将单独的行保存在 1K 图形库中,然后根据画面上发生的行为进行交换。

这样可以在单个游戏区域使用更多种精灵,例如,如果玩家在一个游戏区域遇到六种不同的敌人,但是精灵页面只能实现玩家和三种其它精灵,于是当一种敌人类型从画面清除时,游戏可以交换其中一个敌人图形库为新的敌人类型。

为精灵使用1K 图形并为背景使用2K 图形库的主要缺点,在于红白机处理背景动画的方法。

为了给红白机游戏制作动态背景元素,艺术家加必须创建动态背景元素的副本图形库。每个新副本图形库会包含每个动态对象下一帧的动画,然后这些图形库会一次一个进行交换,就像 Flipbook 一样,以实现动画效果。

如果艺术家为背景使用半页图形库(half-page bank),那么保存所有副本图形库会需要很大空间。

解决该问题的方法是把整个游戏的所有动态背景元素放到单个图形库中。但这样也会让艺术家受到限制,每个背景的静态元素只能有 128 个瓦片。艺术家要选择出最佳方案,以决定为美术使用的图形库类型。

分层技巧

早期时代的许多游戏会采用技巧来创建背景中的视差滚动等效果,但这样也给艺术家和设计师带来了挑战。

虽然后来的 16 位游戏机可以使用多个背景图层,但红白机却无法使用,它的所有背景都是一个平整的图像。为了实现深度和分层效果,开发者使用了不同的编程技巧。

例如,为了实现视差背景,开发者可以设置一个寄存器,它可以判断何时在屏幕上呈现特定的水平线即光栅线。然后,开发者可以使用寄存器控制屏幕画面滚动的速度和方向。

通过使用这种技巧,开发者可以实现背景的水平行,它会作为剩余背景以不同的速度滚动。此时,艺术家和设计师的技巧是把背景看作是一个平面图像。

如果平台或元素应该处于移动速度较慢的背景“前面”,并要放置在该区域,那么该平台或元素也会比剩余图像滚动得更慢。这意味着设计师需要考虑在场景的什么位置放置背景元素,而艺术家需要创建出有无缝衔接效果的背景。

下图的示例画面中,红框标出的区域可以设置比剩余背景更慢的滚动速度,以模拟出深度效果。上方的 HUD 界面设为从不滚动,即使它是平整背景图像的一部分。

对于希望将其中一个背景元素出现在前景中的艺术家而言,还有另一种技巧。在红白机上,开发者可以设置精灵优先级为小于 0 的值

设置后,它会使精灵显示在任意非透明背景元素之后。精灵优先级可以即时修改和触发,使特定元素按需修改精灵的优先级。

结语

当我们开发符合复古游戏机风格的项目时,需要考虑很多现代游戏开发所不必考虑的技术问题。由于旧游戏机渲染图像的方式不同,而且 CPU 和 GPU 只有很小的处理空间,设计师必须创造性地思考如何处理硬件限制。

了解这些限制和技术变得很重要,以便真正重现那个时代的游戏外观和设计。

在下一篇文章中,我们会介绍 16 位时代的设计限制以及如何设置 Unity 来实现真正的“老电视”画面效果。

更多 Unity 精彩技术经验分享和谈论,尽在 Unity Connect 平台(Connect.unity.com)。

Unity 官方平台公众号