« NDS架构 (index)

NDS架构

Chapter 4: 图形


目录

  1. 架构
  2. 使用2D图形构建帧
    1. 图块(Tiles)
    2. 背景类型
    3. 背景模式
    4. Sprites
    5. 结果
  3. 3D 加速
    1. 几何引擎
    2. 渲染引擎
    3. 结果
  4. 知名游戏比较
    1. 第一个例子
    2. 第二个例子
  5. 交互模型

这一部分有些不太寻常,因为这款游戏机不仅有多个屏幕需要绘制,而且把传统的图块(tile)引擎与现代渲染器结合在了一起。

首先说说硬件:NDS包含两个LCD屏幕,每个屏幕的都有256x192个像素,比GBA多约20%个像素点。 它们可以显示262144种颜色(18位),刷新率约60 Hz。

架构

图形子系统可以绘制2D和3D对象。 前者由二维几何图形组成,其中填充了8x8像素的位图(称为"图块"),而后者则使用顶点绘制三维对象(多边形)。

深入了解操作这些屏幕的内部芯片,我们可以观察到这个掌机具有独特的2D和3D几何图形硬件。 2D数据由我们熟悉的引擎PPU(现在只称之为2D引擎)操作,而3D数据由一个全新的子系统处理。 值得一提的是,虽然这并不是第一款推出3D图形功能的游戏机,但它仍然是第一款使用自研图形渲染器来呈现3D图形的游戏机。

Image
不同图形单元的布局。

现在,这两个引擎必须连接到两个屏幕其中之一。对于只有2D图形的游戏来说,这不是问题,因为每个屏幕都有一个2D引擎。 然而,那些想展示前沿特性的游戏却只有一个3D引擎可用。 因此,每次只能在一个屏幕上使用3D功能。 但是2D和3D对象如何混合显示? 别急,我先分别解释清楚这两个引擎,之后再讨论这个问题。

使用2D图形构建帧

在我们检查各阶段之前,我建议先阅读有关GBA PPU的这篇文章,因为在这里我只会提到构建"下一代"2D游戏的变化。 另外,由于有两个引擎,这里我们把第一个引擎称为主引擎(Main),第二个则称为辅助引擎(Sub)。 虽然这并不一定意味着哪个屏幕连接了哪个引擎, 而且主引擎比辅助引擎包含更多的功能。

我将借用新超级马里奥兄弟(New Super Mario Bros)的资源(assets)来帮助解释。

图块(Tiles)

Image
从VRAM中提取的图块。 出于演示目的,使用了默认调色板。

到目前为止,我们都知道基本的图块系统是如何工作的,但是NDS的图块处理有什么特别之处呢? 其实,总共有656 KB VRAM可用,这一块被分割成不同的bank:四个128 KB bank、一个64 KB bank、一个32 KB bank和三个16 KB bank。 开发者可以随便往bank里填充数据并将引擎指向所需数据的位置。 两个引擎都可以从这些bank读数据,但是它们不能同时访问同一个bank。

尽管如此,数据排布方式还是有一些限制。 例如,ARM7只能访问两个128 KB的bank, 这两个bank不能存储sprite;最后16 KB bank只能被"辅助引擎"访问; 等等等等......你懂得。

最后一句,3D引擎我们稍后再讨论,它可以访问其中某些bank以获取纹理(texture)。

背景类型

Super Nintendo时代开始,PPU一直致力于为构建背景图层提供更多的灵活性。 14年后,有这样一款芯片,可以获取图块并应用许多仿射变换。甚至,最终可以从frame buffer构建图层。

在我们讨论2D引擎显示背景的不同模式之前,让我们先了解一下引擎可以生成哪些类型的背景:

开发者不能任意选择背景类型。但是游戏机提供了一系列背景模式,为各类型设置了不同的组合。 尽管如此,你可以在这里看到Affine扩展模式有三种不同的风格("字符","256色"和"直接颜色")。 因此,在下一节中,当你看到X背景模式支持"仿射扩展"类型时,开发者可以选择他们想要的变体。

背景模式

Image
背景图层0 (BG0)。 这个特定的图层将在某些扫描线上水平位移以模拟云的移动。

Image
背景图层2 (BG2)。

Image
背景图层3 (BG3)。

使用的Static背景图层。

背景类型实战演示。 "主"与"副"提供多种操作模式。 所有这些模式生成四个背景图层,然而,每个图层的功能取决于所激活的模式:

此外,在模式0到5中,'主'引擎可以将第一个静态图层用作3D背景。 3D功能将在稍后讨论。

Sprites

Image
渲染的Sprite图层.

Sprites或者说"objects"继承了GBA PPU的功能,但新增两个重要功能。

首先,OAM(存储sprite条目(sprites entries)的区域)的大小现在有2 KB,使每屏每帧可以显示多达128个sprite。 因此,两个引擎都分配有1 KB。

其次,OAM现在可以引用VRAM中的位图,而不仅仅使用图块和调色板。 这是一种与tile系统不同的方法。 实际上,同一帧中可以同时存在这两种sprite"模式",因为此选项是在每个单独的 sprite 上设置的。

结果

Image
合并所有图层......是不是少了什么?

由于每个图层都是即时渲染的,最后阶段需要合并所有内容并将其发送到所选屏幕。 以前基于PPU渲染游戏机基本如此,但这是否意味着NDS也到这里结束了?

还没呢! 主引擎仍然必须从另一个引擎——最强大的引擎——获取图层。

3D 加速

如果你之前玩过NDS,那么你就知道这款游戏机可以显示一定数量的3D图形。 不同于GBA游戏,这些3D图形并非由CPU处理。 不过,CPU-NTR包括两个组件来构建3D引擎。 有趣的是,任天堂采用的设计让我想起了SGI的RCP

回顾"背景模式"部分,你会注意到每个模式都至少有一个static背景,这是因为你可以用3D引擎生成的图形来填充该图层。 唯一需要注意的是只有主引擎可以这样做,这也是模式6仅适用于主引擎的原因之一。

几何引擎

Image
几何引擎的架构。

如果读过第五代或第六代游戏机的文章,你可能会想知道...... SIMD 处理器哪去了? 这是个好问题,因为ARM9并不擅长矢量运算,而且我不认为专用除法器很够用。 这就是为什么任天堂嵌入了一个称为几何引擎的组件,负责处理顶点转换投影光照裁剪剔除多边形排序,最后一项对正确使用透明特性至关重要。

这个引擎有一些严格的限制,特别是它能够处理的多边形数量:有额外的248 KB RAM可用于存储处理过的几何体,数量可以达到2048个三角形或1706个四边形。使用多边形条带的话(而不是单个多边形)还可以存储更多。 为了对这个数字有一些概念,我建议查看之前文章中的"交互模型"部分,你会发现这个限制令人担忧,但不要忘记掌机的屏幕分辨率也要小得多......所以算是抵消了一点。

无论如何,这个引擎是通过一个Command FIFO来控制的,其数据是由CPU或DMA填充。 该FIFO可以存储256个条目,并且它还有一个叫做PIPE的缓冲区,用于存储额外的四个命令(总共260个命令)。

渲染引擎

Image
渲染引擎的架构。

渲染引擎负责将向量转换为像素(光栅化),着色(纹理映射)并应用光照和其他效果。 它依靠透视校正Gouraud 着色分别用来处理插值纹理和光照。 此外,该单元提供一些现代特性,例如fogalpha混合深度缓冲Z缓冲,或是一种被称为W缓冲的变体),模板测试抗锯齿。 虽然最后一项非常原始(将多边形的外部边缘设置透明而已),而且只能用于不透明像素。

渲染系统采用了新旧结合的方式:它没有直接渲染到frame buffer,而是采用行缓存渲染(line buffer rendering),在每一条扫描线上填充像素(类似于2D引擎),并将结果存储在一个较小的缓缓冲区中。 这是因为3D引擎必须与2D绘图器同步工作。

没有传统的frame buffer,光栅化器采用了扫描线渲染(scan-line rendering),遍历每个扫描线以处理其中的多边形边缘。 Arisotura(MelonDS模拟器的开发者)称,对于每个四边形,渲染器只能在每条扫描线上填充一个span。 这可能会有隐患,因为如果四边形是凹四边形或者有交叉的边,结果会变得一团糟。

关于效果,该单元还提供shadowing和一个被称为Toon Shading的独特功能(又称Cel Shading):该单元不可编程,但也可以通过改变照明参数达到卡通效果。

结果

Image
这就对了嘛!

渲染引擎将不会将结果写回frame buffer以供显示,而是写入一个名为Color Buffer的块中,该块可以存储多达48条扫描线。 2D引擎会按照先进先出(FIFO)的方式获取每条扫描线,以填充BG0图层。

3D渲染在2D渲染之前开始,使后者在必要时能够应用图形变换到新图层。 主引擎还允许捕获生成的2D帧、3D帧或组合帧,将其与VRAM中的另一个帧混合(blend),并将结果写回VRAM,之后可以用于显示。

在控制方面,由于采用了基于双缓冲的机制,渲染引擎还允许在帧中间改变参数,该机制可以保留旧状态的副本,直到当前帧绘制完成。 因此,不会出现图像撕裂的现象。

知名游戏比较

一些最初在NDS上发布的游戏试图模仿另一台游戏机(即N64)上的游戏。 玩家可能会看到两种版本之间存在重大差异,我想简要总结一下原因:

第一个例子

Image
超级马力欧64(1996)。
以320×240像素渲染。

Image
超级马力欧64 DS(2004)。
以256x192像素渲染。

第二个例子

Image
马力欧卡丁车64(1996)。
以320×240像素渲染。

Image
马力欧卡丁车DS(2005)。
以256x192像素渲染。

所以,为了解释这里发生了什么,我将根据一些论坛用户的说法,整理出几条不同的解释:

简要的概述这就是这些。如果想要了解更专业的情况,你可能需要深入研究两个引擎,甚至反汇编这两个游戏来研究所使用的功能以及他们的用法。

交互模型

我更新了wee model查看器,添加了"最近邻插值"功能。这样你就可以使用你自己的GPU来查看NDS模型了。

3D model 3D model 3D model
"现代版本"中可用的互动模型
任天狗狗(2005)。
750个三角形。

3D model 3D model 3D model
"现代版本"中可用的互动模型
新马力欧兄弟(2006)。
636个三角形。

尽管我们讨论了图形子系统的诸多限制,但很多游戏确实充分利用了它的功能。


Previous: 3. 中央处理器 (CPU)

Next: 5. 音频


Rodrigo Copetti © 2026 RSS Feed

切换至现代版

主页 · 文章 · 支持 · 关于作者 · 关于此网站