NES 复合视频画面为何抖动?从干扰、色同步信号到独特设计揭秘
NES 复合视频画面抖动之谜:从干扰、色同步信号到 NES 独特设计
2026 年 7 月 5 日
任天堂娱乐系统(Nintendo Entertainment System,NES)是 8 位视频游戏系统的理想典范,其影响力大且取得巨大成功,但从可扩展性和设计方面看,它 有点特立独行。此外,它通过复合视频输出的画面存在抖动问题,下面来深入探究复合视频的细节。
这篇博客文章仅讨论 NTSC 编码和时序,PAL 编码是另一回事,50Hz 信号的时序差异很大。我拥有支持 PAL 输出的游戏机不多,对其不太熟悉。
现在没那么稳了吧
若这里不支持视频标签,就看不到《炸弹人杰克》(Mighty Bomb Jack)标题画面的视频了,挺可惜。
《炸弹人杰克》是 NES 上有代表性的炸弹收集平台游戏,场景设定在金字塔中。和很多游戏标题画面一样,这里标题画面静止。但我用的是经复合视频改造的系统,它直接放大图像处理器(PPU)输出的视频信号,画面却在抖动。
你或许会说:“等等,这可是复合视频。你还 专门写过一篇文章 讲它!复合视频不如其他信号,因为它本质上是一种视频信号压缩形式。”没错,但复合视频的每一帧之间本不应有差异,对吧?看看我那台运行《上海麻将》(Shanghai)的苹果 ][ 电脑(参考 最近一篇文章)。
若这里不支持视频标签,就看不到《上海麻将》标题画面的视频了,挺可惜。
那画面很稳定!
猜测 1:干扰
干扰没你想的那么严重。你可能会想到干扰问题,但干扰通常表现为随机图案,而非 NES 截图中那种周期性的噪点。实际上,苹果电脑的视频是用一根很长的线录制的,线放在我堆满电子设备的桌子上,图像白色部分能看到一些噪点,但这些噪点与输入信号无关。
这是从《炸弹人杰克》原始录制画面中截取的字母“B”。注意字母“B”左侧白色与蓝色天空交界处的锯齿状图案,它是重复出现的。若只是外界信号干扰,不应与图像如此紧密相关。
猜测 2:色同步信号
用约 3.57 MHz 的色同步信号频率除以 NTSC 的行频 15.734kHz,会得到接近 227.5 的数值。这并非巧合,美国无线电公司(RCA)有意让色载波频率是行频的半整数倍。因为若相邻扫描线的信号相似,其频率就会接近行频,而电视信号中出现半整数倍频率的成分很罕见,这样更容易滤出色信号。我在 2021 年的文章 中也稍有提及。
你可能会注意到,色同步信号应是连续 3.57 MHz 信号的一部分,但这个信号与行频不匹配,所以每条扫描线上的色同步信号应不同。这会是画面抖动的原因吗?
另一方面,苹果电脑的沃兹(Woz)意识到,若每条扫描线的像素排列都不同,使用他的 高分辨率模式 会很困难,因为仅在一条扫描线上每隔一个字节就有差异已够麻烦。所以在这种罕见情况下,他增加额外硬件来延长时钟周期。在苹果电脑上,行频被调整为每条扫描线有 228 个色周期,即打破了 RCA 的优化,使得亮度更容易干扰色度,这正是伪彩色的来源。
所以苹果电脑是个不太合适的例子。我的日本世嘉 Master System 也是每条扫描线有 228 个色周期,尽管在其他方面它的信号被认为更符合标准。实际上,要找到一款标题画面静止且背景不是黑色的 Master System 游戏挺难,我选了《王牌空战》(Ace of Aces)。
雅达利(Atari)说过,黑色背景只能用来表示太空。
若这里不支持视频标签,就看不到《王牌空战》标题画面的视频了,挺可惜。
在滚动画面中,会看到扫描线伪像的变化。看看上面《亚历克斯小子 梦幻世界》(Alex Kidd in Miracle World)截图中的地面,尤其是地面上的伪像,它们在每一帧中的位置都不同。更准确地说,伪像位置不变,而地面在移动,从而产生闪烁效果。
那么,每条扫描线实际有 227.5 个色周期的系统是什么样的呢?那就是 PC Engine(在这个例子中是 SuperGrafx,但这应该不影响)。
若这里不支持视频标签,就看不到《魔法桃子》(Wonder Momo)标题画面的视频了,挺可惜。
“嘿,这看起来比那些不符合标准的版本还糟糕,怎么回事?”
复合视频并非为计算机生成的图像设计,而是为现实世界的图像设计。此外,它更适合动态物体,而非静止物体。
若放大一点,这一点可能更明显。这是《太空阿瓦 201》(Space Ava 201)标题画面的截图(参考 2020 年文章),它恰好处于 SuperGrafx 模式,不知为何噪点更多,但今天先忽略这一点,因为画面已极度放大。
尤其注意蓝色背景与黄色字母的交界处。由于视频捕捉的宏块效应,可能有点难看清,但每隔一个像素都有点偏移。这是因为颜色分辨率低于像素分辨率。
但与上面的字母“B”对比,NES 呈现的是三行图案,而非两行图案,挺有意思。
猜测 3:NES 与众不同
世嘉 Master System 本质上支持 RGB。它的视频显示处理器(VDP)没有复合视频输出,只输出 RGB 图像,然后由外部芯片将其编码为复合视频。我的 法国版 Master System 2 甚至没有这个编码器,所以只能输出 RGB 信号。可以说,至少从 20 世纪 80 年代后半期开始,这是视频游戏机的常见情况。上面 Master System 截图中的彩虹条纹来自索尼 CXA1145 视频编码器,若使用不同的编码器,效果可能不同。
红白机(Famicom)诞生于 20 世纪 80 年代初,它没有单独的视频编码器,实际上从未以 RGB 模式工作过。PPU 不仅输出复合视频信号,而且整个处理过程都基于此,或者使用根本未进行颜色编码的数字视频数据。缺乏 RGB 中间环节,使得从红白机获取 RGB 信号 有点复杂。
1994 年的 PC-FX 也不以 RGB 模式工作,但它内部采用的是分量视频,所以先不考虑它。
这意味着什么呢?以 NES 的调色板为例(请允许我这么做),这是 FirebrandX 的“Digital Prime”调色板。
为何提及调色板的来源呢?因为这是一张 RGB 格式的 PNG 图像,而 NES 对 RGB 一无所知。可以看到,这里有四种不同的亮度(最后一列有点奇怪)和十二种不同的色调。第一列没有色调,只有纯粹的亮度。NES 内部直接将调色板索引转换为这些色调和亮度,它甚至没有 S-Video 中间环节,更不用说 RGB 了。
雅达利 2600(Atari 2600,参考 2023 年文章)的工作方式与此类似,但它有 S-Video 中间环节,而且有十六种不同的色调。那么,为何 NES 只有十二种呢?
NES 有一个 21.47727 MHz 的晶体振荡器,正好是 3.579545 MHz 色同步信号频率的六倍。PPU 在生成颜色信号时,可以利用这个时钟的上升沿和下降沿,因此它能获得色同步信号频率十二倍的基本速率,自然而然就有了十二种可能的相位。
雅达利 2600 使用 3.579545 MHz 的色同步振荡器,显然它产生相位偏移的方式不同,但这超出了本文的讨论范围,留给读者自行研究。
现在开始明白 NES 的时序是怎么来的了。NTSC 版红白机只有一个 21.47727 MHz 的振荡器,其他所有时钟都由此派生。将其除以 12,就能得到一个漂亮的 1.7897725MHz 时钟速度,用于 2A03 处理器。在 PPU 内部,主振荡器除以 4 得到 5.3693175MHz 的点时钟,每条扫描线有 341 个点(包括水平消隐间隔),这样行频就是 15.7458kHz,这个精度已经足够。
现在发现了问题所在。六分频后的色同步信号频率与四分频后的像素时钟之间的关系,使得每条扫描线有 227.33 个色同步信号周期。这就是为什么会出现每三行重复一次的图案,现在明白字母“B”的情况了。
但再看看那个标题画面,似乎是在两帧之间交替,而非三帧,为什么呢?
若这里不支持视频标签,就看不到《炸弹人杰克》标题画面的视频了,挺可惜。
理光(Ricoh)的工程师注意到行频和色同步信号之间的这种关系意味着,在 262 条扫描线(包括垂直消隐间隔)中,会出现三种可能的色同步信号/扫描线对齐模式。显然,这种情况不可接受。在 NESdev 上,用户 lidnariq 有一张很好的图表,展示了这种情况如何在屏幕上产生移动的对角线图案。
于是,NES 采用了一种可以说是世界上最偷懒的隔行扫描方式。在隔行扫描中,场与场之间的最后一条扫描线是正常扫描线长度的一半。在 NES 上,这条扫描线的长度在 341 个点和 340 个点之间交替,即“少一个点”。实际上,这意味着只能看到三种可能对齐模式中的两种,它们每隔一帧交替出现,从而产生一种表面上与“标准”的 227.5 产生的两种对齐模式相似的效果。
需要再次强调,以上情况仅适用于 NTSC 版游戏机。PAL 版游戏机自然有完全不同的时序系统,主振荡器和分频器都不同,而且它根本不会采用“少一个点”的技巧。不过,这里对细节的关注还是很令人印象深刻的。PPU 在当时真的是一款非常出色的芯片!
罕见的例外情况
“少一个点”的情况只在 PPU 实际进行渲染时才会出现。如果背景和精灵渲染都关闭,PPU 就不会这么做。我不太清楚原因,但猜测可能是由于某些实现细节。不进行渲染的屏幕上不会有复杂的内容,也就不会出现伪像。
那么,为什么要关闭屏幕呢?PPU 虽然有很多优点,但也有一个重大缺陷:在屏幕进行有效渲染时,根本无法写入视频随机存取存储器(VRAM)。相反,必须在垂直消隐间隔期间批量写入。但如果关闭渲染,PPU 就会一直允许完全访问 VRAM,这在使用 CHR-RAM 并需要将所有图块上传到游戏卡带内存时特别方便。
Rare 公司的《战斗蛙》(Battletoads)就是这样一款游戏,它属于他们的 AxROM 游戏。它比大多数游戏做得更极端,为了获得最多的 CHR-RAM 访问时间,它每一帧都关闭渲染,通过精确的时序控制,在几行空白后再打开渲染,这样就能多加载一些图块用于动画。让我们来看看,这不是标题画面,而是游戏内画面,但大部分屏幕仍然是静止的。别在意我的青蛙被打得很惨,我相信它没事。
若这里不支持视频标签,就看不到我在《战斗蛙》里被打的视频了,挺可惜。
画面确实更嘈杂了一些。为了确认这就是实际情况,这里有相邻四帧的部分 HUD 画面。就像上面《亚历克斯小子 梦幻世界》中的情况一样,你可以在彩虹条纹中清楚地看到这种效果,在这个例子中,彩虹条纹出现在部分心型图标上,我们基本上看到的是该点上色同步信号的快照。
注意第一帧和第四帧几乎完全相同,这是一个三帧重复的图案,正是“少一个点”技巧想要解决的问题。Rare 又一次做到了。