本文编译自VGHF游戏历史基金会网站文章SEGA VR REVIVED: EMULATING AN UNRELEASED GENESIS ACCESSORY(https://gamehistory.org/segavr/),作者为Rich Whitehouse,文中的“我”均指原作者Rich Whitehouse。
自诞生以来,虚拟现实经历了几波被称为视频游戏“Next Big Thing”的浪潮。
90年代初期,虚拟现实的潜力给大众带来了充分想象空间。报纸、杂志、电视新闻频道甚至包括《The Lawnmower Man》等主流电影都在描绘VR引人注目的功能。包括任天堂在内的不少公司都在尝试将VR技术用于新的产品,但最终真正推向市场的仅仅只有少数。
这一时期,世嘉也在积极探索如何设计一套价格合适的VR外设,来拓展家用主机世嘉MD(即SEGA Genesis)的游戏性。与一些VR街机设备动辄5位数的价格不同,世嘉VR头显的目标售价仅200美元,配备高频惯性测量单元和两个LCD屏幕,与如今的VR头显设计十分相似。1993年世嘉向记者和经销商公布了这一全新的外设,期望在VR的前沿领域取得新的突破。得益于当时一家初创公司One-Sendai的专利授权,世嘉VR头显的追踪解决方案仅需1美元的生产成本,这也是其价格能够低至200美元的关键。
尽管世嘉官方对于最终取消VR头显上市给出的理由是:因为VR体验过于逼真和沉浸,玩家可能在使用这款VR头显时因为四处走动而面临极高的伤害风险,但这一理由十分牵强。因为世嘉从斯坦福研究所获得的反馈称,使用世嘉VR头显可能导致头昏眼花甚至头痛,特别是对于儿童和青少年有更高的风险。而世嘉前首席执行官Tom Kalinske也在Retro Gamer Podcast的一集中证实,后者才是世嘉放弃VR项目的主要原因。
迄今为止,我们对于世嘉VR的了解大部分来源于早年CES展示的外观原型、世嘉的广告、专利文件以及来自内部工作人员的部分资料,但这也意味着我们对于世嘉VR许多技术细节的了解大多基于推测,甚至根本是未知的。想要回顾和研究这样一款在当时来说突破了许多技术界限的产品,这些细节十分重要。无论世嘉VR是否实现了世嘉的野心,它在VR的历史上依然是一款耀眼的产品。
如果你想了解世嘉VR到底是一款怎样的产品,最佳的选择当然是找到世嘉VR头显硬件,其次则是从世嘉VR的配套游戏入手,研究出游戏运行时对硬件的需求,这样我们也能够获取足够多的信息来模拟真正的世嘉VR头显。通过软件来推测出世嘉VR的真实体验,正是我的研究目标。
世嘉VR这款产品公开时,有多款为这一VR外设开发的游戏正在研发中,但由于世嘉VR取消了发售,这些游戏也随之被埋入了历史的尘埃。不过令人惊喜的是,来自 Gaming Alexandria的Dylan Mansfield努力联系上了Futurescape Productions的联合创始人Kenneth Hurley,他们曾为世嘉VR开发了一款名为《Nuclear Rush》的第一人称动作游戏。
《Nuclear Rush》的背景设定在2032年,化石即将枯竭,而世界对于电力的需求仍在不断增长。玩家在游戏中需要进入拥有老式核反应堆的秘密区域,收集放射性燃料。由于画面和背景较为相似,这款游戏常常被和另一款世嘉VR游戏《Iron Hammer》混淆。1993年的夏季CES上,《Nuclear Rush》放出了部分未加入最终版本HUD的游戏画面,更加清晰的展示了游戏本身的内容。
在Dylan联系上Hurley并表明了自己对于世嘉VR的兴趣后,Hurley拿出了一张1994年8月6日制作的CD-ROM光盘,这张光盘包含了《Nuclear Rush》的完整源码,并且历经26年依然没有任何的数据丢失。
这张光盘正是对世嘉VR探索的起点。我们首先要做的是编译《Nuclear Rush》并让其能够正常运行,然后通过这款游戏,在世嘉VR废弃超过25年后的今天,重建世嘉历史中值得被铭记的一页。
构建光盘源码
尽管Hurley的光盘中包含了《Nuclear Rush》的完整源码,却没有包含任何已经编译好的二进制文件。为了能够将源码很好的组织起来,Dylan找到了我。乍一看,我们已经收集齐了编译游戏所需的全部资料,包括所有的美术资源和大部分需要的工具,尽管其中有部分数据来自光盘上另一款世嘉游戏《Monster Hunter(怪物猎人)》
大部分《Nuclear Rush》的游戏代码是用C语言写的,需要使用Sierra 68000 C语言编译器进行编译,其中包含了一些样板代码(例如世嘉VR头显驱动)以及其他零碎的汇编代码。游戏代码编译最耗时的部分是缩放工具(scaler),同样用C语言编写,但是进行了一些改造。编译器会按照需要根据C语言代码生成本地M68K代码,供游戏运行时调用。
除标准的构建(Build)工具之外,构建过程还需要一些专有工具来提取美术资源数据并将其转换成游戏直接使用的格式。例如CVTSCE.EXE用来提取静态背景以及UI;ANM2FPA用来提取可选RLE的缩放化精灵和动画;最后LZSSC.EXE用标准的LZSS压缩算法(12-bit偏移,4-bit长度)来压缩CVTSCE.EXE生成的资源。
在我首次尝试构建时,发现有一个工具DUMP.EXE缺失了。查找该工具可能的作用时,我发现它只是打开了一个文件,然后使用stdout逐个字节将信息写入该文件中,以便汇编程序能够读取该二进制文件。在花费了宝贵的时间用Borland C ++ 3.0编写一些代码后,我生成了一个替换的可执行文件,最终成功完成了源码的构建。
源码构建成功后生成了一个COFF格式文件,但游戏ROM最重要的部分被分成了数个额外的文件。我希望在相同的MS-DOS环境下将这些文件打包成可运行的游戏ROM,因此向好友Borland寻求帮助让他帮忙写了另一个程序来分析COFF文件,从而生成正确包含其他文件的二进制ROM,并在该ROM的头部写入校验数据。
首次运行ROM文件
当我在MD模拟器中首次运行构建出的ROM文件时,模拟器的欢迎画面让我非常开心:至少游戏已经进入了正常的执行步骤。
但显而易见的是,我并没有头部追踪器。游戏成功识别了头部追踪器的缺失,进入了非VR的运行模式。随着背景音乐的播放,游戏似乎运行的非常正常,直到我按下开始按钮并进入主菜单。菜单字体使用的调色板似乎损坏了,所有的菜单文字都很难辨认。我尝试着加载游戏的第一关,但程序计数器开始报错,整个程序崩溃了。
像往常一样,Debug的时间到了。我从COFF文件中转储(dump)出了全部的Debug符号,然后使用这些符号的地址加入了一些新的断点,来查看关卡加载出错前程序都做了写什么。
经过一段时间的反复尝试,我发现游戏成功的加载了第一关,甚至在崩溃前还显示了1-2帧的画面,然后缩放器为一个精灵设置了一个错误的偏移,并造成了后续一系列的程序错误。前文提到过,我从另一个游戏的数据中提取了一些工具,这就是问题的所在。这些工具可能在完成《Nuclear Rush》后更改了部分代码,最终我在缩放器主入口代码前几行发现了导致问题的代码:
后两行指针的累加是为了跳过一些完全无用的数据,而这些数据不知什么时候似乎已经从ANM2FPA.EXE的输出中被移除了。既然这些数据已经完全被移除,我只需要删除这两行指针累加的命令即可。
完成改动后,关卡终于能正常加载了,但背景中一些图块和一些HUD精灵依然显示为乱码。这看起来应该和之前是同样的问题,由于《怪物猎人》游戏的数据格式发生了改动导致工具代码发生变化,只不过没有像之前的代码那样造成灾难性的后果。最终在一个忙碌的周六,我排查解决了之前遇到的问题并重新构建了一版正确的ROM,最终成功进入了游戏的关卡中,享受我的首次《Nuclear Rush》之旅。
寻找游戏源码BUG
当游戏能够正常运行后,我还需要回头去解决一些之前碰到的其他BUG。我并不知道到底有多少BUG是由于工具的混用引起的,有多少是游戏“最终”版本的遗留BUG。这里的“最终”指的不是最终零售版本,尽管游戏已经有效的完成了开发,但显然没有经历过经典的debug过程来保证游戏的质量。
根据整个代码中出现的少量WCES94预处理程序检查,我推测《Nuclear Rush》原本计划在1994年冬季CES上再次进行展示。而Kenneth1994年8月6日刻录的CD-ROM尽管包含了游戏接近开发完成时的源代码,但显然还不是能够作为商业发行的版本。
在整个游戏中泛滥的调色板错误很可能还是和构建时用到的工具集有关,这是一个很有意思的问题。CVTSCE.EXE文件很可能在《Nuclear Rush》开发完成后也被修改,同时在文章前半部分的图片中你也能够看到,CVTSCE.EXE打包资源其实还有很多参数可以进行设置,这些参数影响了资源打包成为二进制文件的方式。调色板的错误可能和CVTSCE.EXE的默认参数有关,但还存在着更深层次的问题。
CVTSCE.EXE提取的许多基于图块的源图像都用到了多个调色板,数量和偏移也不尽相同。例如,一幅图像可能使用调色板1和调色板2,而另一幅图像可能仅使用调色板0,依此类推。CVTSCE.EXE输出的文件格式旨在为文件中的第一个调色板指定索引,并设定调色板的数量。加载图像后,它将使用该索引和计数来确定当前使用的调色板并将其加载到CRAM中。这里的问题是调色板索引/计数的默认值对《Nuclear Rush》中的所有图像来说可能都是错误的,而且我没有看到任何文件数据帮助说明工具针对目录之外的内容使用时如何进行设置。
最终我不得不修改CVTSCE.EXE工具。我添加了一个选项来扫描图块地图,找出图块引用的调色板,并使用该数据确定调色板范围和要输出的计数。我不知道这一工具最初如何处理《Nuclear Rush》的图块资源,但按照我目前的方法进行处理已经不再出现问题。
在硬件上进行实机测试时,我还遇到了一个大问题。《Nuclear Rush》将画面的水平滚动与基于滚动表的垂直滚动相结合,较新的MD主机型号可以通过这种方式正常处理画面的滚动,但是较旧的机型可能会导致背景的左侧出现空白列。发生这种情况时,游戏画面看起来像这样:
《Nuclear Rush》会尝试通过检查硬件的版本(寄存器$ A10001)来避免此问题,如果版本检查返回0,程序会强制截断水平滚动,这意味着实际上画面背景一次只能滚动一个图块,避免了空白列的问题。但这样就造成了画面的水平滚动十分不平滑,给玩家的感觉很迟钝。由于该问题在特定MD机型上的出现毫无征兆,因此仅仅截断水平滚动显然不是最理想的解决方案。我碰巧有一台第二版的MD主机,在进行版本检测时返回值大于0,但后续的MD主机才进行了VDP(Video Display Processor)的改进从而解决了这一问题,因此我在自己的MD上运行游戏时也碰到了背景出现空白列的状况。
《Nuclear Rush》利用垂直滚动表来实现围绕Z轴的旋转(Roll)效果。通过为滚动表中的每个列条目累积一个小的偏移量,并通过应用对象所属列的偏移量来补偿Sprite的位置,可以达到下图中的显示效果:
相比对程序进行大的改动,我通过加入在菜单中加入一个选项进行了简单的修复。该选项设置游戏画面的四种渲染模式,第一种模式会禁用垂直滚动表(允许在较旧的硬件版本上进行平滑滚动),第二种模式会强制进行平滑滚动(即使因为硬件不支持会导致空白列的出现),第三种模式则会强制截断水平滚动,第四种模式模式将恢复原始的硬件版本检查。该选项不是万能的,但可以改进游戏在第二版MD主机上的运行情况,也能够适配后续更新型号的MD主机。
之后,我还对游戏进行了少量其他的debug工作直到对游戏状态感到满意为止,其中包括了修复DMA计时错误和一些崩溃,使输入密码的功能再次生效,并且修复了一堆仅在游戏以立体模式运行时出现的问题。
通过模拟器模拟世嘉VR
工作终于进行到模拟世嘉VR头显这一步了。这也是最让我兴奋的一步。如果我只有一个预先构建的ROM镜像而不是源代码,我可能还需要进行大量的拆装筛选,以找出游戏想要从VR头显中获得什么样的数据。但是,有了源代码,这一过程就容易得多了。
《Nuclear Rush》的源代码有两个文件可供参考世嘉VR头显的通信数据。HEADSET.ASM是由Sega of America提供的原始驱动程序源代码,而VRDRV.ASM是《Nuclear Rush》基于原始驱动修改后的版本,两套源代码处理VR头显数据的核心方法是相同的。驱动程序源码还引用了“VR.DOC/VR.TXT”,其中可能包含关于接入VR头显的一些有趣的技术信息,但不幸的是,该文件是缺失的。不过我已经有足够多的信息可以仅从源代码来让VR功能正常运行起来。
读取VR头显数据是通过多路复用方案进行的,就像普通的世嘉MD手柄一样。实际上,与VR头显的所有交互都是通过游戏手柄2号端口进行的,驱动程序会假定VR头显已经正常接入游戏主机。
软件方面,VR头显的初始化从握手开始。该软件将TR和TH引脚都设置为通过寄存器$ A1000B写入。与仅将TH引脚设置为写入的标准手柄不同,这种设置让我们通过两位(2 Bits)来区分通过寄存器$ A10005向VR头显发送的不同命令类型。例如发送$60(TR+TH)给VR头显表示让头显进入闲置模式,$ 40(TH)则让VR头显进行复位。我正是利用了复位命令来让世嘉MD模拟器进入VR模式。当发出闲置模式的命令后,软件会触发$ 20(TR),以推进可从$ A10005读取的数据。软件空闲命令后会立即读取$ 70作为响应的确认,并验证TH,TR和TL是否按预期设置。软件确认之后会发送VR头显标识$ 08,$ 00,并将其后半部分作为保留数据。如果初始化过程中的任何部分没有按预期进行,驱动程序就会认为初始化出错,然后游戏就会以非VR模式运行。
▲模拟器VR模式初始化成功
初始握手完成后,程序将顺序读取所有VR头显数据,请求当前的偏航角(Yaw),俯仰角(Pitch)和左/右眼的位数据。Z轴旋转数据的缺失意味着世嘉VR头显只能用于跟踪两个旋转轴。同时,我不知道程序会从IMU读取怎样的位置漂移数据,也不知道在累计角度运动之前应用了哪种滤波器,因为VR头显需要向程序提供绝对坐标和角度。这意味着游戏仅仅读取了VR头显的输出数据并按原样应用它,而不会对数据进行其他处理。虽然这样一来仅凭软件我很难知道硬件内部发生了什么,但是考虑到世嘉MD的处理能力时,这种实现细节很有意义。
现在,我需要了解VR头显初始化后的数据流格式,幸运的是,驱动程序源码的注释很好地列出了所有内容:
上图是VR头显读取功能返回的数据格式,x位是32位寄存器头部的未使用位,其中包含了读取函数返回时VR头显数据的累加值。
这样的数据格式表示我们需要分别使用9Bit来表示VR头显的360度左右转动角度和60度的俯仰角度。L/R位指定VR头显下一步要扫描的眼睛。在我的实现中,我使用32位浮点值来储存角度数据,以保持敏感的高精度输入。当将角度返回给世嘉MD时,我会首先对浮点数据取整然后进行量化和编码。
uint32_t encode_headset_angles(const float *pAngles)
{
//assumes angles have already been clamped
const uint32_t pitch = (pAngles[0] >= 0.0f) ? (uint8_t)pAngles[0] : ((uint8_t)-pAngles[0] ^ 0xFF) | (1 << 16);
const uint32_t yaw = (uint32_t)pAngles[1];
return pitch | ((yaw & 0xFF) << 8) | ((yaw & 0x100) << 9);
}
该函数的输出将与双眼位数据的模拟进行结合,接下来的工作就是更有意思的显示同步了。
《Nuclear Rush》如何进行双眼画面渲染?
《Nuclear Rush》被设计为按照锁定的15Hz帧率运行,这意味着完整的游戏循环每秒将运行15次。但是VBlank仍然会以60Hz的频率进行。
注:CRT显示器通过将电子束发射到荧光屏上来显示图像。显示画面时,电子束将按照从左到右、从上到下的顺序来扫描整个屏幕从而显示一幅完整的画面。VBlank是指电子束从瞄准屏幕右下角调整到重新瞄准屏幕左上角的时间段。
在VBlank中断结束时,程序会读取了VR头显的数据,但在下一个VBlank开始时,我们还要从前一个VBlank中读取VR头显数据,以确定要对哪只眼睛对应的屏幕(可能会启动DMA)进行扫描输出画面。因此尽管世嘉VR头显的驱动程序源码显示其支持以60Hz运行,但《Nuclear Rush》仅在每隔一个VBlank的末尾时读取VR头显的数据。
如果你将世嘉MD连接到旧的NTSC显示器时,假设VDP不在隔行模式下运行,它将以大约60Hz的频率扫描生成新的画面帧。通常,由于VR头显需要显示双眼的画面,以60Hz的频率生成新的画面帧意味着每只眼的画面都会以30Hz的频率更新。但《Nuclear Rush》读取VR头显数据并扫描帧的方式实在有点怪异。
《Nuclear Rush》输出帧的方式:
1.进入VBlank
▪读取上一帧VBlank时的头显数据。设置左眼位。
▪设置左眼屏幕为下一次扫描目标。
▪VBlank结束时再次读取头显数据。设置右眼位。
2.扫描左眼屏幕。
3.进入VBlank
▪读取上一帧VBlank时的头显数据。右眼位已设置。
▪设置右眼屏幕为下次扫描目标。
▪跳过头显数据读取。这是一次异常的VBlank。
4.扫描右眼屏幕。
5.进入VBlank
▪读取上一帧VBlank结束时的头显数据。右眼位已设置。上一个VBlank结束时跳过了头显数据的读取。
▪设置右眼屏幕为下次扫描目标。
▪ VBlank结束时再次读取头显数据。设置左眼位。
6.扫描右眼屏幕。
7.进入VBlank
▪读取上一帧VBlank时的头显数据。左眼位已设置。
▪设置左眼屏幕为下一次扫描目标。
▪VBlank结束时跳过读取头显数据。又一次异常VBlank。
8.扫描左眼屏幕。
9.回到第1步重复整个循环。
所以按照上文的序列,《Nuclear Rush》实际上是按照“左、左、右、右”的顺序来扫描显示游戏画面。以立体模式直接查看游戏输出的画面也证实了这一点。下图从左到右展示的是游戏连续4帧的画面,顺序正是左左右右。
这样的渲染方式令我感到奇怪,因为通常来说世嘉VR头显在扫描显示画面时应当采用左右交替的顺序,而且世嘉VR头显的硬件设计也不太可能围绕让每个显示屏仅以15Hz帧率显示特定画面来而开展。唯一的解释是,VR头显仅在读取数据时会更改其显示目标,这样的方案也更加通用,无论我们每个VBlank结束时都读取头显数据还是每隔一个VBlank才读取头显数据都能够正常工作。
世嘉VR头显期望游戏在每个VBlank结束时读取自身数据,并告诉游戏在下一个VBlank结束时期望为左眼还是右眼生成画面。这是我对于世嘉VR头显画面显示方式的理论。而我在尝试运行《Nuclear Rush》时也成功实现了这种方式,仅在读取VR头显数据后切换显示目标,取得了很好的显示效果。
同时我还尝试着实现让游戏输出画面立体化。为此我专门编写了3D立体画面的后处理代码,该后处理在将颜色映射为亮度后会将左右眼的输出组合在一起。我在模拟器配置中自定义了双眼的颜色,并对当时我使用的眼镜做了改造。最终的成果看起来很漂亮:
但运行游戏时,我还是注意到了一些异常,在转动头部时,双眼的画面偶尔会不同步,这在3D立体模式下尤其明显:
最初,我以为我的代码出现了问题,重新进行了调试。我连续截取了4帧画面,并设法找到了画面不同步的地方:
上图4帧的渲染顺序为左左右右,但是你能够明显的看到右眼第二帧实际上前进了很多距离。当截取这些画面时,我在VR头显中向左转动了头部,但这里游戏实际上在右眼的两帧画面之间向前移动了很长的距离。
目前还没有发现如何阻止这种情况发生,同时它也可能出现在任何时刻,甚至是左右眼画面切换的时候。游戏在每一帧画面后都会等待4次VBlank来保持15Hz帧率锁定,但偶尔的卡顿可能导致意外出现,游戏可能在未与VR头显同步的情况下就设置了下一次为哪只眼睛生成画面。这一问题可能同样会出现在真正的世嘉VR头显上。由于实际显示画面时,世嘉VR头显主要依靠视觉的持久性来补偿低分辨率、低刷新率以及时序的限制,在其他状况都比较糟糕的情况下,这一问题很可能不那么明显,甚至不能被称为问题。
最终我在游戏源代码中添加了一些内容,让游戏每次循环结束时都会和头显进行同步,解决了这一问题。我很好奇这样做会不会真的能改善世嘉VR头显的体验,还是说每个VBlank结束时对VR头显进行采样会带来额外的开销,但这一问题可能永远都没法得出答案。
全新的世嘉VR体验
既然游戏已经能够显示3D影像,我也可以通过摇杆来模拟VR头显的转动,自然而然我开始想真正的把《Nuclear Rush》搬到VR中。
我制作了一个特别版本的《Nuclear Rush》,并进行了一些修复使游戏在非立体模式下能够以30Hz运行,更改了每个VBlank上VR头显的采样,并启用了上一章节中提到的修复以使VR头显能够和游戏画面同步。在立体声模式下,VR头显也可以始终保持15Hz的帧率。为了增强这一特殊的游戏版本,我还为世嘉VR模拟器添加了一个选项,实现了模拟器对M68K的超频。
尽管以30Hz刷新率运行会导致游戏逻辑的实际运行频率比最初高出两倍,游戏的感觉仍然不错。另一方面,由于摆脱了ROM不能超过2MB大小的限制,我还能够通过静态的扩展更多精灵数据,并加入针对性优化。
既然游戏准备好在要求更高的VR环境中运行,现在我应当将重点转移到复原世嘉VR体验上了。我的下一步工作将是在模拟器中添加对现代VR头显的支持。我基于OpenVR编写了MD模拟器对于HTC Vive Cosmos的支持。
要实现模拟器对于VR的支持,主要工作在于从模拟器获取立体的画面输出并直接传输到VR头显中。这看起来似乎很简单,但并不是一个普通的用例,还有一些特殊事项需要注意。我必须对模拟器提供的“原始”正交投影画面进行处理,来适应眼睛/镜头的畸变。我还必须去掉OpenVR库中全部的运动平滑或插帧算法,这意味着要在维持VR头显内部刷新率的同时,保证MD模拟器锁定60Hz的输出。
当我解决了OpenVR的时序问题后,还要处理更多世嘉VR时序问题,世嘉VR头显似乎并未尝试对眼前的屏幕进行同步。为了能够在不对ROM进行任何更改的情况下正确运行《Nuclear Rush》,我在模拟器中添加了一个名为dgen_openvr_eyes_sync的选项。如果启用此选项,并尝试运行未修复同步问题的《Nuclear Rush》版本,会经常发现自己变成了斗鸡眼。这实际上就是前文提到的问题:游戏本身并没有什么机制来阻止双眼显示画面不同步。
为了尽量逼真的再现世嘉VR头显体验,我会在双眼画面扫描生成后立刻更新缓冲区数据,也正是因为双眼的画面全部都会立即传输给VR头显,如果这些画面并不是来自游戏的同一帧,就会导致画面闪烁的情况发生。
不过只要你打开模拟器的同步选项并运行游戏的同步版本,显示就会变得一切正常!
画面的长宽比和视角是另外两个要处理的重要问题。默认情况下,我会处理每只眼睛的图像,将其调整为适合MD的宽高比,但是玩家也可以禁用默认设置并将其更改为所需的任何相对宽高比例。
由于我并不了解世嘉VR头显所用屏幕或镜片的确切物理参数,因此我只能猜测世嘉VR头显的有效视野,失真数据。我向模拟器添加了一个名为dgen_openvr_imgpscale的选项,该选项可用于更改人眼投影空间中图像的大小。
之后,我为模拟器添加了自定义镜片形状的功能。通过Noesis脚本,玩家可以将最常见的模型格式文件导入作为镜片的模型数据,然后模拟器会将该数据用在人眼投影空间中渲染全部的画面。上图是对鱼眼镜头测试,也图中显示了镜片的模型。
这种方法使我们能够在数学上生成我们想要的任何透镜形状而不必考虑模型的计算成本。除了自定义镜片外,还可以使用选项dgen_openvr_bilinear启用双线性过滤。尽管我通常不喜欢在模拟器中使用双线性滤波进行画面缩放,但它在这种情况下可以帮助减轻迷失感。
到这里为止,我们终于可以使用一台现代VR头显来模拟世嘉VR头显的体验了,还开发了一整套用于微调的工具。尽管这样的模拟无法做到100%还原,但这确实非常接近世嘉VR的体验。
刷新率仅15Hz的VR游戏可玩性却比我预期的要好得多,虽然视角转动有所限制,但也不会太令人讨厌。这种体验不是所有人都能够接受,不过我在其中度过了一段愉快的时光!即使游戏本身的采样率有限,我们也可以从低延迟的头部跟踪中受益匪浅。
从这里开始,我们还可以继续进行更多有趣的后续开发。我可能会尝试基于现有的世嘉VR代码来增加对房间规模跟踪的支持,或创建一个接口用来在真实的硬件上模拟世嘉VR头显。目前的模拟相较真实的世嘉VR头显也仍然还有很大的提升空间,通过调整不同的视角和运动滤镜,我们可能得到更逼近真实的体验。
源代码和下载
我为这个项目在GitHub上创建了两个仓库,你可以在其中找到源代码和二进制文件。
支持世嘉VR的模拟器
Github仓库:https://github.com/DickBlackshack/SegaVR-DGenSDL。
Windows可执行程序下载:https://github.com/DickBlackshack/SegaVR-DGenSDL/releases/tag/1.0。
《Nuclear Rush》可直接构建的源代码和所有必需的工具
Github仓库:https://github.com/DickBlackshack/SegaVR-NuclearRush。
ROM映像下载:https://github.com/DickBlackshack/SegaVR-NuclearRush/releases/tag/1.0。
上面的游戏ROM可以在大多数模拟器或MD实机上运行,但必须使用提供的模拟器才能获得真正的世嘉VR体验。该模拟器还增加了很多选项,你可以仔细阅读配置文件来探索更多模拟器配置。你可能还需要对配置进行一些更改才能选择匹配VR头显的旋转参数。
如果您想要使用自己的VR头显进行体验,可以在这方面进行多种调整尝试。如果你发现自己感到迷失方向或在默认设置下很难跟踪运动,可以尝试减小int_openvr_imgpscale的值,直到感觉VR体验更舒服为止。
电科技(www.diankeji.com)是一家专注于全球TMT行业的领先资讯媒体。
作为今日头条青云计划、百家号百+计划获得者,2019百度数码年度作者、百家号科技领域最具人气作者、2019搜狗科技文化作者、2021百家号季度影响力创作者,曾荣获2013搜狐最佳行业媒体人、2015中国新媒体创业大赛北京赛季军、 2015年度光芒体验大奖、2015中国新媒体创业大赛总决赛季军、2018百度动态年度实力红人等诸多大奖。
投稿、商务合作请联络微信公众号
声明:本站原创文章文字版权归电科技所有,转载务必注明作者和出处;本站转载文章仅仅代表原作者观点,不代表电科技立场,图文版权归原作者所有。如有侵权,请联系我们删除。