让我们回顾一下正确显示图形的要求:
- Virtual Boy必须显示两帧。
- 每帧的分辨率为384x224像素。
- 调色板由深浅不同的红色和黑色(即LED熄灭时)组成。
- 场景需要应用视差效果。
好消息是,所有这些都由任天堂制造的专用芯片,视频图像处理器(Video Image Processor,"VIP")进行加速。 它继承了旧版PPU的一些功能,但我认为它与前代产品完全不同。
架构
VIP初看起来可能是另一个图块(Tile)引擎,但它要比这先进得多。 首先,它不仅能处理图形数据,还能控制扫描仪。
此外,传统的图块引擎是按扫描线渲染图形,而VIP则采用帧缓冲器架构,将最终帧作为位图存储在内存中,然后发送显示。 这更接近现代3D着色器的工作方式。 事实上,Virtual Boy更进一步,采用了某种翻页(page flipping)方式,即每个显示单元存储两个帧缓冲区,扫描仪在拾取一个缓冲区的同时,VIP正在写入另一个缓冲区。 所有这些都有助于防止画面撕裂。
尽管如此,VIP可以分为三个主要部分:
- 像素处理器(Pixel Processor,"XP"):生成背景和精灵,与PPU相似。 它将最终处理过的位图发送到内存中的帧缓冲区。
- 显示处理器(Display Processor,"DP"):控制扫描仪并发送帧缓冲区以供显示。
- 接口: 提供对两个内存块的访问:128 KB的VRAM和128 KB的DRAM。 它们还在VRAM和CPU(VIP端称为"主机")之间进行访问仲裁。
总体而言,流水线非常简单:
- CPU通过写入VIP的内部寄存器和向VRAM和DRAM中填充所需的素材来设置VIP。
- 然后,XP将生成帧缓冲区并存储在VRAM中。
- DP选择所需的帧缓冲区,并将其发送到扫描仪进行显示。 具体做法是将帧每次复制四列,复制到VRAM中称为串行访问内存(Serial Access Memory,"SAM")的小型缓冲区,并自动广播给扫描仪。
硬件组织
在开发人员方面,XP和DP使用两块内存:
- 128 KB DRAM用于存储将要处理的图形数据。
- 128 KB 的 VRAM用于存储DP将寻找的帧缓冲区。
- 由于我们有两个显示单元,因此总共需要四个帧缓冲区。 生成的每个位图宽度为24 KB,因此我们需要分配96 KB内存。 剩余的32 KB被XP用于存储图块。
请注意,这个VRAM是"真正的"双端口DRAM,而不仅仅是为图形预留的RAM块(任天堂也称之为"VRAM")。 双端口DRAM允许两个设备同时读取,这就解释了为什么XP可以在扫描仪读取VRAM的同时写入它。
此外,任天堂使用的 VRAM 芯片在现成的产品目录中找不到。 有关它的文件不多,但从专利申请中描述的信息来看,SAM可能存储在该芯片内部的一个单独区域中。 该区域可能由SRAM代替,并包含额外的电路,使扫描仪能够一次读取16个位。
构造一帧
让我们深入了解一下像素处理器是如何绘制单帧图像的。 为此,我将借用Virtual Boy瓦里奥大陆(Virtual Boy Wario Land)的资产。 我强烈建议大家阅读以前的图块引擎,以便更轻松地理解讲解。
图块
我们之前已经了解过传统图块引擎是如何使用8x8位图构建图层的。 就Virtual Boy而言,图块(最初称为"字符")存储在 VRAM 中一个名为图案表(Pattern table)的区域中。 声明的每个图块占用2字节,因此有足够的空间容纳2048个图块。
在颜色方面,开发人员可以构建8个调色板,其中4个用于背景图形,另外4个用于精灵。
有人可能会问,如果LED是单色的,调色板有什么用? 这样,开发人员就可以使用不同色调的红色。 这些色调是通过改变LED的亮度获得的。 亮度设置存储在两个寄存器中,然后在调色板中引用这两个寄存器来编排不同的色调。 这样得到的调色板将包含两种自定义红色,加上根据两种红色的总和自动计算出的另一种红色,以及最后的"透明"色。
背景

背景图层1 (BG1)。
在游戏过程中,该图层大部分时间是隐藏的,而在按下暂停键后则会完全显示出来。
背景图层非常简单,选取图块组成一张512x512的地图(64x64图块,共4096个图块)。 现在,事情还没有结束,因为我们不是只有一个背景层可用...... 我们有14层!
每个单独的背景图层称为一个段(Segment)。 单个段可容纳8 KB内存,其中每个图块引用包含H/V(水平/垂直)翻转属性和调色板索引。 每个图块引用占用2字节内存。
像素处理器还允许组合不同的段来生成更大的图层,但只有一组组合可用。 最大的组合包括8个段。
精灵
精灵(任天堂称之为"对象")是具有独立坐标的单个图块,但占用更多内存。
在DRAM中有一个名为OAM的地方,分配有8 KB的内存,这里就是定义精灵的地方。 每个精灵定义占用8个字节,因此最多可声明1024个精灵。
每个精灵都有以下可用属性:
- X 和 Y 坐标。
- 一个标志,用于决定是在左侧屏幕、右侧屏幕还是同时在两个屏幕上显示。
- 视差偏移,允许应用自动视差:每个屏幕显示精灵时都会有轻微的水平偏移。
- 该值是有符号的: 如果该值为正数,则会使精灵看起来更远。 相反,如果偏移量为负值,则会使其看起来更近。
- 使用的图块索引。
- H/V翻转。
- 调色板索引。
你还会注意到,本段介绍没有显示屏幕截图,下一段将解释原因。
窗口
窗口示例有些窗口可以在两个显示器上同时显示(使用移位效果),而有些窗口只能在一个显示器上显示。
分层系统初看起来可能很简单,毕竟VIP提供了"背景"层和"精灵"层。 那么,我们还需要什么呢?
事实上,要显示前面提到的任何图层,我们都必须将它们放入一个名为窗口(也称为"世界")的"桶"中。 窗口是将被渲染到屏幕上的实际平面,它由之前构建的图层填充。 共有32个窗口,它们将重叠形成最终的画面,每个窗口声明占用32个字节。
窗口提供不同的渲染模式。 您可以抓取一个背景层或精灵层,并按原样显示。 为此,窗口必须设置为正常模式或对象模式,具体取决于您使用的图层类型。 不过,您也可以利用其他模式,在背景层上应用额外的效果:
结果
设置好一切后,像素处理器将开始渲染32个窗口。 完成后,最后一帧将被放入帧缓冲区。 其他显示单元也会重复这一过程。
由于系统采用双缓冲设计,显示处理器将始终获取像素处理器未处理的帧缓冲区,从而大大避免了撕裂。 在下一个活动时间段,像素处理器将覆盖DP之前显示的帧,以此类推。
如果需要渲染的内容不多(即很少使用窗口),在写入帧缓冲区和DP提取帧缓冲区之间会有很长的间隔。 这样,CPU就可以根据需要对帧进行额外更改。 VIP也为此做好了准备:CPU可以设置中断来检查VIP的各种状态,包括这种情况。
另一方面,如果有太多的仿射模式窗口需要渲染(例如),XP可能会"错过最后期限",从而导致掉帧。 幸运的是,也有中断可以检测到这种情况。 无论如何,官方文档都提供了每种图层所需的时间。
创意内容
如您所见,这款游戏机中的技术远不止这些。
马里奥网球(Mario's Tennis)(1995)起初,我以为Game Boy Advance是近11年后第一款能重构超级任天堂广受好评的模式7的便携式游戏机。 结果发现一直以来都是5年后的Virtual Boy。 但即便如此,我们之前已经看到,Virtual Boy中的仿射变换可以应用于32层中的每一层(尽管有一些限制)。
此外,所有这些新功能都能与视差效果一起使用,而VIP也能做到这一点。
我在想,如果这台游戏机的寿命能够再长一点,让开发人员能够更好地使用这种硬件,我们会看到什么样的游戏呢?
另一个有趣的功能是,通过允许CPU更改帧缓冲区,如果VIP无法满足开发人员的需求,他们就可以构建自己的着色器。 一些游戏就是依靠它来呈现创新图形的。 例如,红色警报(Red Alarm)采用了由CPU渲染的多边形构建的场景。
这两款游戏都尽量少使用VIP来绘制图形,而是让CPU来绘制主要图形。遗憾的是,像可见表面确定这样的基本问题并不总是能得到很好的解决,我不确定这是否是由于CPU的限制造成的。 总之,这导致场景变成了杂乱无章的网格,玩家很难分辨哪些物体在其他物体后面。















