标签 DOOM 下的文章

1983 年和 1993 年之间的变化显著,然而从那时候到现在,变化其实并不大。

2023 年即将过去,我们来回顾一下三十年前的科技。不只是与今天进行对比,也是和更早的十年前对照。有趣的不是变化有多大:而是变化的速度有多快。

一位澳洲老极客近期指出,距离 id Software 的“最具影响力的恐怖动作游戏”问世,以及它带来的网络“死亡竞赛”,已经 三十年 了。回顾 1993 年的科技,并把它和 1983 年对比一下,真是令人惊叹。仅仅十年的时间,现代计算的大部分技术都诞生了。许多始于 1993 年的重大技术,如今依然是我们依赖的核心。

正如 DOOM 在 1993 年重新定义了电子游戏,Windows NT 也赋予了 PC 操作系统全新的定义。NT 的第一个版本在 DOOM 发布前几个月就 问世 了,其影响力甚至更为深远。1993 年我们也见证了 NCSA Mosaic 的发布,这是最初的 Web 浏览器。Mosaic 的衍生品是 Netscape。起初它开始运营的名字是 Mosaic 通信公司,不知为何,这家公司的首页现在 仍然存在。后来,Mosaic 公司 变成 了 Netscape,进而催生出了今日的 Mozilla。1993 年还有一项里程碑式的事件,那就是 Trojan Room 咖啡壶摄像头的上线,这是有史以来第一台网络摄像头。

1993 年奠定了现代计算的发展方向。一代人的时间过去了,大多数桌面电脑用户仍在使用基于 NT 系统的变体:Windows 11 仍然基于它。而 Mosaic 代码库的最后一部分随着 IE 11 的退场已经销声匿迹,但我们仍然在使用间接源于 Mosaic 的 Web 浏览器。

要想了解 1993 年带来的影响有多大,可以将其与早更的十年前做个比较。1983 年,Camputers Lynx 亮相,但它根本无法与 英国的热销机型 —— ZX Spectrum、BBC Micro 和 Commodore 64 相抗衡。而就在 Lynx 问世的同一年,另一款价格更昂贵的失败产品也在池塘边面世。虽然数以千计的苹果 Lisa 最终被扔到了垃圾填埋场,但其精简成本后的继任者 Macintosh,确立了个人电脑的新标准 —— 即便现代 Mac 中几乎找不到初代 Macintosh 的技术影子。

Lisa 之所以失败,部分原因是其售价高达 $9,995,约合今日的 $30,000。确实不菲,但对比一下,原始版 IBM PC 标配硬盘的第一代,即 IBM PC/XT,也是在 1983 年发布的。由于拥有 10 MB(注意,不是 GB)的硬盘,其价格达到了 $7,545,大约相当于今天的 $22,500。这就是为什么像 Commodore 64 这样的 8 位设备在 1983 年的市场中占据主导地位的原因:64 KB 内存、磁带存储,以及一台模拟电视作为显示器,是大多数家庭用户能负担起的全部。Commodore 64 在 1981 年发布时的定价为 $595](https://www.theregister.com/2012/01/02/commodore_64_30_birthday)。到 1993 年,按通胀计算这个价格约为 [$1,000,而这在当时可以买到一台 486 PC

转瞬十年变迁

1973 年,微处理器几乎还没有出现。那时还没有英特尔 8080 或 CP/M。我们所认为的 PC 该有的能力需要一台定制的工作站才行,其成本约合今天的 $280,000:Xerox Alto。和其相比,Lisa 看起来还算便宜。另外,1973 年,以太网 也诞生了。

在十年之后,一台售价 $10,000 的个人电脑刚刚能够实现单色的图形用户界面(GUI),但很少有人意识到其好处,买的人就更少了。再过十年,到 1993 年,Windows for Workgroups 3.11 发布,而那时连低配置的 PC 也能流畅运行它。同年,MacOS 7.1.1 也发布了,任何 1993 年生产的 Macintosh 都能毫不费力地运行它。1983 年最畅销的 电子游戏 是《 吃豆人 Pac Man 》和《 大金刚 Donkey Kong 》,十年之后,人们痴迷的是一款网络实时 3D 第一人称射击游戏 —— DOOM。

从 1983 到 1993,计算机世界从 8 位 CPU 和几十 KB 的存储,发展到拥有 MB 存储的 32 位机,并且图形用户界面成为了标准配置。NT 3.1 是首个具有完全抢占式多任务处理和内存保护功能的 Windows 版本,它取代了 Windows 3 和经典 MacOS 的原始而不稳定的协同多任务处理。NT 3.1 也是首个内置 TCP/IP 的 Windows 版本,当时以太网开始成为标准配置,图形网页浏览器也应运而生。浏览器和第一台网络摄像头的出现,是使 互联网盈利 的关键所在。

虽然对大多数人来说并不重要,但 Windows NT 的第一个版本已经支持了 双 CPU,它使用的 英特尔 MP 标准,曾出现在 Compaq SystemPro 中,其首个 386 型号发布于 1989 年。当 双核芯片 开始面世时,NT 已经做好准备,但实际上,多处理器 PC 并不是在二十世纪九十年代才出现的,它们是 80 年代末期的技术,在 1993 年已经落地并投入使用。

在屏幕图形方面,我们或多或少获得了实时 3D 技术,尽管仍然是通过软件渲染的。OpenGL 标准在前一年获得了批准,Windows 上的“视频”应用也在此时作为 Windows 3 的免费附加组件出现。

那么,后来发生了什么呢?

在接下来的十年中,许多较小的部分逐渐到位,但它们的变化更像是演进,而不是变革:是帮助而非突破。Windows 95 使得桌面界面现代化,而现在的大多数工作方式仍 与那时相同,尽管微软已经作了 大量努力。在世纪之交,英国开始全面推广 ADSL 宽带,让大部分人享受到了快速的互联网。一年之后,Windows XP 的问世,终结了基于 DOS 的 Windows 时代。 NT 发布十年后,首款 64 位 PC 芯片 问世。

从那时起……那么,你能说出哪些重大进步吗?在 PC 之前,手机就可以 听懂口语命令(尽管我们一度认为这只是个 噱头)。你的脸可以 解锁设备,但它们仍然无法读懂你的表情。手势操作仍然只限于触摸板。从 32 位转移至 64 位的进程相当平淡乏味:主要的变化就是你可以拥有更多的内存。计算机变得更小,更节能,运行更安静,拥有更多也更快的存储……仅此而已。

尽管 PC 行业绝不承认这一点,但正如在 2021 年,或者说更早的十年前也一样,计算机的速度增长已经不再那么显著。存储设备也如此,最新的耗电大户 GPU 这类半专用的特定用途芯片也依然如此……不过近来 苹果芯片 的表现显示,提升图形性能的效率秘诀并不在于在总线末端挂载一个庞大的高热 GPU 群,而是将更小的 GPU 集成到 CPU 芯片中。

现在我们已然走过 21 世纪的四分之一,但在可编程性、交互性或全新的不可预见的技术等方面却没有取得惊人的突破,三十年来,电脑容量和并行处理性能的增长,主要让操作系统和应用程序变得前所未有的臃肿。

Windows NT 3.1 操作系统的最新版本是 Windows 11 ,而 1993 年时它已经具备了 Windows 11 大部分的功能。NT 3.1 能够在两种 CPU 架构(x86-32 和 MIPS)中运行,并拥有用于 DOS、Windows 3、UNIX 和 OS/2 应用程序的子系统…… 这一切都被集成在只有 50 MB 的 ISO 文件中。而如今的 Windows 11 需要 6 GB 的存储空间。它扩大了 120 倍。如果你认为现在的功能是当初的 120 倍,那么请举手。

(题图:DA/a10b4730-ce44-48c2-aa61-d630ddca8660)


via: https://www.theregister.com/2023/12/19/windows_nt_30_years_on/?td=rt-3a

作者: Liam Proven 译者: ChatGPT 校对: wxy

比尔·盖茨称人工智能是他见过的唯二的革命性技术

比尔·盖茨称人工智能的发明 “与微处理器、个人电脑、互联网和移动电话的创造一样根本”,并在一篇题为 《人工智能时代已经开始》 的文章中预测 “整个行业将围绕它重新定位”。他称,他一生中只见过两次革命性的技术展示,一次是 1980 的图形化用户界面,这导致了后来的 Windows 的诞生;另外一次就是去年兴起的人工智能爆发。在他的要求下,OpenAI 训练的 GPT 仅仅用了几个月就以最高分 5 分通过了 AP 生物测试。

消息来源:盖茨笔记
老王点评:这篇文章中,盖茨还提出很多预测,我认为比一些其他互联网大佬的瞎说要可靠得多。

DoomLinux:一个只用来玩 DOOM 的 Linux

有些 Linux 发行版是主要用于某些用途的,但还有一些只能用于某个用途,如一位爱好者开发的 DoomLinux 就只能运行 1993 年的经典游戏《 毁灭战士 DOOM 》。它通过 BusyBox 加载 Linux 内核和标准实用程序,然后运行 fbDOOM,这是一个专门为在 Linux 帧缓冲器上运行而设计的移植版。整个发行版被放在一个可启动的 ISO 文件中,可以放在任何可启动的驱动器上。

消息来源:Hack A Day
老王点评:无用的乐趣,才是有趣的。

由于人数不足,X.org 推迟董事会选举

有些年份,他们只有 4 名候选人竞选 4 个空缺席位,而另外一些年份,他们几乎没有达到投票者参与的 25% 的法定人数。今年的 X.Org 董事会选举被推迟了两周,希望一些有能力的人提名自己参加选举,并能够承诺在董事会任职。

消息来源:Phoronix
老王点评:每每看到 X.org 的消息,都给人一种英雄迟暮的感觉。

1993 年,游戏开发公司 id Software 发行了一款第一人称射击游戏 《 毁灭战士 DOOM 》,游戏一经发行迅速爆火。在今天看来,《毁灭战士》可谓有史以来最具影响力的游戏之一。

《毁灭战士》发行之后的第十年(2003 年),记者 大卫·库什纳 David Kushner 出版了一本关于 id Software 的书,书名为《 Doom 启示录 Masters of Doom 》,后被奉为记录毁灭战士创作史的典范读物。几年前我曾读过这本书,如今内容已记得不太真切了,但是书中有一个关于 id Software 首席程序员 约翰·卡马克 John Carmack 的故事,我印象特别深刻。这里只对故事做粗略描述(具体情节请往下阅读)。实际上,早在《毁灭战士》开发前期,卡马克就发现自己为这款游戏编写的 3D 渲染器在渲染某些关卡时慢得像爬一样。对于《毁灭战士》这一对动感和速度有着相当高要求的射击游戏来说,这是一个非常严重的问题。意识到了这一问题的严重性,卡马克需要一个更加有效的渲染算法,于是他开始阅读相关论文。最后,他实现了一种叫做“ 二叉空间分割 binary space partitioning (BSP)”的技术,极大地提升了《毁灭战士》游戏引擎的运行速度,而这项技术此前从未用于电子游戏当中。

一直以来,我对这个故事的印象十分深刻。卡马克将学术前沿研究运用于电子游戏之中,我觉得这正是他之所以成为传奇人物的原因。无论从哪个角度来看,卡马克都应该是电子游戏行业中人尽皆知的典型的天才程序员,只不过上面这个故事是我最先能够想到的理由。

显而易见,“二叉空间分割”这个术语听起来就是难度相当高的课题,能够自行阅读论文并将其付诸实施实属不易,所以这个故事给我留下了深刻的印象。我一直认为卡马克的做法十分具有创见性,不过由于我既不懂二叉空间分割到底是怎样的一项技术,也不晓得这项技术在当时究竟有多么革新,所以我也并不确定自己的观点是否正确。如果按照从 霍默·辛普森 Homer Simpson (LCTT 译注:《辛普森一家人》中的那个老爹)到 阿尔伯特·爱因斯坦 Albert Einstein 的顺序为天才列出一套级别体系,那么卡马克将二叉空间分割技术运用于《毁灭战士》的做法究竟属于什么级别的天才之举呢?

同时,我也在想,二叉空间分割这个概念最初是从哪儿来的,又是怎样吸引到卡马克的?因此,本篇文章不仅仅会讲述约翰·卡马克和《毁灭战士》的故事,也会探讨二叉空间分割树(BSP 树)数据结构的发展历史。有意思的是,BSP 树和计算机科学领域其他许多技术一样,最初都起源于军事研究领域。

没错,《毁灭战士》的第一关卡 E1M1 就受到了美国空军的启发。

VSD 难题

BSP 树是计算机图形领域最具挑战性难题的解决方案之一。举个例子,为了渲染出三维场景,渲染器必须能够区分在一个特定角度下的可见物体和不可见物体。如果渲染时间比较充足,这一要求也算不上大问题;但是就理想情况来说,实时游戏引擎在 1 秒内至少需要完成 30 次区分任务。

这一问题有时被称为 可见面检测 visible surface determination (VSD)问题。后来与卡马克合作开发《 雷神之锤 Quake 》(id Software 继《毁灭战士》之后开发的游戏)的程序员 迈克尔·亚伯拉什 Michael Abrash ,在自己的著作《 图形程序开发人员指南 Graphics Programming Black Book 》 中写道:

我想探讨一下在我看来 3D 中最棘手的一个问题:可见面检测问题(在每个像素点上绘制合适的表面)以及与之密切相关的隐面消除问题(迅速去除不可见的多边形,用于加快可见表面检测速度)。简略起见,我将在下文采用缩写 VSD 来表示可见面检测和隐面消除。

为什么我会认为 VSD 是 3D 中最棘手的问题呢?尽管纹理映射等光栅化问题更让人感兴趣而且也更重要,但是相对而言,它们是范围相对有限的任务。随着 3D 加速器的出现,它们逐渐被转移到硬件中。同时,它们只随着屏幕分辨率的增加而增加,而分辨率的增加是相对温和的。

相反,VSD 却像是一个无底洞,目前应对方案也有很多。但实际上,在采用简单的方法处理 VSD 时,其性能会直接受到场景复杂程度的影响,而场景的复杂程度通常会以平方级或立方级的形式增大。所以在渲染过程中,VSD 很快就会成为制约因素。 [1]

亚伯拉什是在上个世纪九十年代末写的关于 VSD 问题的这些困难,这是在《毁灭战士》之后数年,这款游戏证明了普通人盼望着能用自家电脑玩很吃图形配置的游戏。九十年代早期,id Software 成立后发行了一些游戏。尽管当时的计算机还只是用来处理文字与表格或者执行其他任务,未尝想过要在上面运行游戏,id Software 必须对发行的游戏进行编程,使其能在计算机上流畅运行。为了实现这一飞跃,尤其是为了能让在《毁灭战士》之前 id Software 发行的少数 3D 游戏在电脑上运行,id Software 必须做出革新。在这些游戏中,所有的关卡在设计时都受到了一定限制,以便更容易解决 VSD 问题。

例如,在《毁灭战士》之前,id Software 发行了《 德军总部 3D 版 Wolfenstein 3D 版 》,该游戏的每一个关卡都是由与坐标轴平齐的墙壁组成。换言之,在《德军总部 3D 版》的游戏画面里,你看到的只有南北方向或者东西方向的墙壁。在游戏中,墙壁与墙壁之间有着固定的间隔,所有过道的宽度或是一个方格,或是两个方格等等,但绝不会出现 2.5 个方格。如此一来,尽管 id Software 团队只能设计出外观十分相似的关卡,但这也让卡马克为 《德军总部 3D 版》 编写渲染器的工作简单了不少。

通过将屏幕上的光线“齐射”入虚拟游戏世界,《德军总部 3D 版》的渲染器解决了 VSD 问题。通常来说,使用光线的渲染器叫做“光线投射”渲染器。这种渲染器的速度一般较慢,因为解决内部的 VSD 问题涉及到在光线和游戏中的物体之间找到第一个交点,这通常需要进行大量的计算。但在 《德军总部 3D 版》,由于所有的墙壁都与网格平齐,所以光线与墙壁相交的位置只能在网格线上。如此一来,渲染器只需逐个检查这些交点即可。如果渲染器先从离玩家视角最近的交点开始检查,接着检查下一个最近的交点,以此类推,最后遇到第一面墙壁时停止检查。这样,VSD 问题便轻而易举地得到了解决。光线从每一个像素点向前投射,与画面物体接触时停止,这一方法是可行的。因为从 CPU 资源来看,投射的成本很低。事实上,由于每面墙壁高度相同,因此针对同列的像素点,投射的光线只需一条。

尽管当时还没有专业的图形显卡,《德军总部 3D 版》凭借这一取巧之法得以在配置较低的个人电脑上正常运行起来。然而,这个办法并不适用于《毁灭战士》。因为 id Software 为这款新游戏增添了许多新元素 —— 倾斜的墙面、楼梯以及高低不一的天花板。光线投射的办法自然也就不好用了,于是卡马克编写出了一个新的渲染器。《德军总部 3D 版》的渲染器关注的是图像,将光线投射到屏幕像素表示的列上,而 《毁灭战士》 关注的则是物体。换句话说,《毁灭战士》 的渲染器会记录游戏场景中的所有物体,继而将其投射到屏幕当中;而非记录屏幕上的像素点,判断每个像素点的颜色。

对于强调物体的渲染器来说,可以使用 Z 缓冲区来解决 VSD 问题,比较简单。每次将物体投射到屏幕上时,需要对每个用于绘制的像素点进行检查。如果你想绘制出的物体的部分和已经绘制在目标像素点上的物体相比更加靠近玩家,可以将其覆盖。否则,必须保持像素不变。尽管办法很简单,但是 Z 缓冲区对内存的要求较高,而且渲染器可能仍然要花费大量的 CPU 资源来投射玩家永远不会看到的水平几何体。

在 20 世纪 90 年代,使用 Z 缓冲区的方法还存在着其他缺陷:IBM 兼容机(PC)搭载的是一种叫 VGA 的显示适配器系统,在这类电脑上,将图像写入帧缓冲区的成本非常之高。因此,在只会以后被覆盖的像素上绘制花费的时间拖慢了渲染器的性能。

考虑到将图像写入帧缓冲区的成本非常之高,理想的渲染器需要首先绘制离玩家最近的物体,接着是比较近的物体,以此类推,直到屏幕上每个像素点都写入了信息。这时,渲染器会停止运行,大幅缩短远处不可见物体的渲染时间。这种由近及远对物体进行排序的方法也可以解决 VSD 问题。那么问题又来了:什么才是玩家可以看到的?

最初,卡马克打算依靠《毁灭战士》的关卡布局来解决 VSD 问题。首先用渲染器绘制出玩家目前所在房间的墙壁,之后玩家冲进隔壁房间,再绘制出隔壁房间的墙壁。由于每个房间互不遮挡,这一办法也能解决 VSD 问题。而互相遮挡的房间可以分割成若干互不遮挡的“区域”。在 YouTube 上的一个 视频 中,Bisqwit 展示了自己制作出来的使用了相同算法的渲染器。可以看到,如果以超慢的速度运行,便能一睹渲染的具体过程。这一算法同样运用到了《毁灭公爵 3D 版》当中,这款游戏在 《毁灭战士》 推出三年之后发行,当时 CPU 的性能也更加强大了。1993 年,尽管在硬件上已经可以运行游戏了,但是使用这一算法的《毁灭战士》渲染器在复杂的层级结构上依旧表现吃力,尤其是在房间分割出来的各部分相互嵌套的情况下。不巧的是,这类层级结构正是构造环形楼梯等物体的唯一办法。沿着环形楼梯走下去,直到走入已经绘制好的区域,由于这其中涉及多次循环下降运动,导致游戏引擎的运行速度大幅降低。

在 id Software 团队意识到《毁灭战士》游戏引擎的速度可能过慢时,公司还面临着其他任务:将《德军总部 3D 版》移植到超级任天堂游戏机(简称“超任”)上。那时,超任的性能比 IBM 兼容机还要差。结果表明,尽管光线投射渲染器非常简单,但是想要在超任上快速运行是不可能的。于是,卡马克着手研究更为高效的算法。事实上,也正是为了顺利将《德军总部》移植到超任,卡马克首次研究了二叉空间分割技术,并将其付诸应用。由于《德军总部 3D 版》的墙壁与坐标轴平齐,所以二叉空间分割技术应用起来也比较简单直接;但是《毁灭战士》的情况则比较复杂。不过,卡马克发现,二叉空间分割树同样可以用来解决《毁灭战士》速度过慢的问题。

二叉空间分割

二叉空间分割 binary space partitioning (BSP)会提前将 3D 场景分割为若干部分,使 VSD 问题易于解决。讲到这里,你需要先了解一下为什么分割场景可以奏效:如果你在场景上画条线(对应三维空间里的一个平面),你就可以指出玩家或者摄像机视角在这条线的哪一侧,在这条线另一侧的物体无法遮挡玩家所在一侧的物体。如果多次重复这一操作,该三维场景最终会被分割为多个区域,这并不是对原始场景的改进,只是现在你知道了更多关于场景的不同部分会如何相互阻挡。

首次阐述上述三维场景分割的是美国空军的研究员,他们曾尝试向美国空军证明计算机图形已经非常先进,可以应用到飞行模拟器领域。1969 年,他们将研究发现发表在一份题为《计算机生成图像在图形仿真中的应用研究》的报告中。该报告的总结部分指出,计算机图形可用于训练飞行员,但也警告说,其实际应用可能会受制于 VSD 问题:

实时图像处理需要解决的一个关键问题就是优先级问题,或称隐藏线问题。在我们平时用眼睛观察外界时,大自然替我们轻易地解决了这一问题:不透明物体上的一个点,掩盖了同一视觉方向上、且距离较远的所有其它物体。但在计算机中,这项任务却非常困难。图像处理需要解决的优先级问题,随着环境复杂程度的增加,计算量会呈指数级增长,随即就会超过绘制物体透视图所需的计算负载。 [2]

他们在报告中提出了一项基于构造“遮挡矩阵”的方案,这一方案据说早些时候曾被应用于 NASA 的项目当中。研究员指出,平面将场景一分为二,可用来解决平面两侧物体之间存在的“任何优先级问题”。通常情况下,可能需要明确将这些平面添加到场景中,但对某些几何体,只需借助你已经拥有的几何体的表面即可。他们举了一个例子,如下图:p 1、p 2 以及 p 3 是三个不同的平面,如果摄像机视角位于其中一个平面的前方,即“正”面,p i 的值就等于 1。这种矩阵展示出基于三个不同平面和摄像机视角位置的三个物体之间的关系 —— 如果物体 a i 遮挡了物体 a j,那么 a ij 在此矩阵中的数值等于 1。

研究人员指出,这种矩阵可以应用到硬件中,对每一帧进行重新评估。该矩阵基本上可以用作大型的开关,或者一种预置的 Z 缓冲区。在绘制给定的物体时,如果在物体所在列上得出数值 1,并且所在行已经在绘制中,那么物体被遮挡的部分就不会绘制出来。

不过,该矩阵方法的主要缺点在于,为了在场景中表示出 n 个物体,你需要一个尺寸为 n 2 的矩阵。于是,研究人员们继续深入,探究将遮挡矩阵表示为“优先级列表”的可行性,该列表的尺寸是 n,可确定物体绘制的顺序。他们随即发现,诸如上图此类场景根本无法确定顺序(因为它存在循环阻塞的现象)。因此,他们花了很多时间来阐明“合适”与“不合适”场景之间的数学区别。最后,他们得出了一个结论:至少对于“合适的”场景下,优先级列表是可以制作出来的;而对场景设计师来说,避免设计出“不合适”的场景也不是一件难事。但是,他们并没有说明如何生成该列表。可以说,这份 1969 年的研究的首要贡献在于提出了:至少,在 理论上,可以采用平面分割的方法,对场景中的物体进行渲染排序。

直到 1980 年,一份题为《基于优先级树结构的可见表面生成》的论文提出了解决该问题的具体算法。在这份论文中,作者 亨利·福克斯 Henry Fuchs 泽维·凯德姆 Zvi Kedem 以及 布鲁斯·内勒 Bruce Naylor 介绍了 BSP 树。他们指出,这种新的数据结构“可以替代十年前首次使用,但由于一些问题未得到广泛发展的方案”(即前文 1969 年美国空军相关研究中的方案)。 [3] BSP 树一经生成,即可用于确定场景中物体的优先级顺序。

三人在论文中对 BSP 树的工作原理给出了相当可读的解释。但在本文,我将尝试使用更加通俗的语言,介绍给大家。

首先,在场景中选定一个多边形,将该多边形所在的平面作为分割平面。同时,该多边形充当树的根节点。场景中剩下的多边形会分散在分割平面的两侧。位于分割表面“前方”或者与分割平面相交后位于“前”半部分的多边形落在了根节点左侧的左子树上;位于分割表面“后方”或者与分割平面相交后位于“后”半部分的多边形落在了右子树上。接着,递归重复这一过程:在左子树和右子树上各选定一个多边形,作为各自空间新的分割平面,继而二分出来更多的子空间和子树。等到全部的多边形均选定之后,二叉空间分割也就结束了。

假设你想由后向前将场景中的几何图形进行渲染。(这就是所谓的“ 画家算法 painter's algorithm ”。因为在绘制时,距离摄像机较远的多边形会被距离摄像机较近的多边形所覆盖,借此正确进行渲染任务。)如果想要实现这一算法,必须按顺序遍历 BSP 树,左右子树的渲染顺序由摄像机视角与节点所在分割平面的位置关系决定的。因此,针对树上的每个节点,首先渲染距离分割平面较“远”一侧的所有多边形,接着是位于平面上的多边形,最后是距离平面较“近”一侧的所有多边形 —— “远”与“近”相对于摄像机视角而言。根据前文,距离分割平面较远一侧的多边形无法遮挡近侧的物体,所以这种方法可以解决 VSD 问题。

下图表示一个简单的二维场景的 BSP 树的构造与遍历过程。在二维中,分割平面变成了分割线,但就基本原理而言,与复杂的三维场景并无二致。

第一步:根分割线落在 D 墙上,将剩下的几何图形分为两组。

第二步:继续分割位于 D 墙两侧的空间。C 墙是其中一侧的唯一一堵墙壁,因此无需再分。另一侧,B 墙形成新的分割平面。因为 A 墙与新的分割平面相交,所以必须将其分割为两堵墙。

第三步:参照右上方视角,由后向前对墙壁进行排序,对执行画家算法很有帮助。这就是树的顺序遍历过程。

福克斯、凯德姆以及内勒多次强调了 BSP 树的优势:它只需构建一次。可能有些难以置信,但实际上无论摄像机视角位于何处,同一棵 BSP 树都可以用来渲染一个场景。只要场景中的多边形没有移动,BSP 树就不会失效。因此,BSP 树在实时渲染任务中非常实用 —— 构建树时的所有艰巨任务都可以在渲染工作开展之前完成。

同时,三人也提到了一项需要进一步深入研究的问题:究竟怎样才能构建出一棵 “高质量的” BSP 树?BSP 树的质量取决于用作分割平面的多边形的选择。我在前文跳过了这一问题,不过如果用作分割平面的多边形与其他多边形相交,那么为了让 BSP 算法发挥作用,必须将相交的多边形一分为二,这样两部分就可以分在不同的空间。但是如果这种现象反复出现,BSP 树的构建势必会大幅增加场景中多边形的数量。

内勒后来在其 1993 年的论文《构建高质量的分割树》中提及这一问题。卡马克的同事,id Software 的共同创始人 约翰·罗梅洛 John Romero 指出,这篇论文是卡马克在《毁灭战士》中引入 BSP 树时读到的论文之一。 [4]

《毁灭战士》中的 BSP 树

别忘了,卡马克首次为《毁灭战士》设计渲染器时,通过让渲染器渲染玩家所在房间之外的临近房间,试图为关卡几何图形建立一套渲染顺序。对此,BSP 树是个不错的选择,因为在玩家进入之前的房间(区域)时,BSP 树能够避免让渲染器重复劳动,从而节省 CPU 资源。

实际上,“将 BSP 树引入《毁灭战士》”意味着将 BSP 树生成器引入《毁灭战士》的关卡编辑器中。当完成一个《毁灭战士》的关卡的制作时,BSP 树就会在关卡几何图形的基础上生成。根据程序员 法比安·桑格勒德 Fabien Sanglard 的说法,在原版《毁灭战士》中,一个关卡的 BSP 树生成时间需要 8 秒,全部关卡合计共需 11 分钟 [5] 。之所以生成时间较长,部分原因在于卡马克所用的 BSP 生成算法,该算法尝试使用各种启发式方法找出 “高质量” BSP 树。在运行时,8 秒的延时可能让人无法接受;但是离线等 8 秒,时间并不算长,尤其是考虑到 BSP 树提升了渲染器的性能。为每个关卡生成的 BSP 树将在游戏启动时作为关卡数据载入。

卡马克对 1980 年论文中提出的 BSP 树算法进行了改造,因为在《毁灭战士》开始运行时,当前关卡的 BSP 树就会读取到内存中,渲染器通过 BSP 树由前向后绘制物体,而非由后向前进行绘制。福克斯三人在那篇论文中演示了 BSP 树可用于执行由后向前的画家算法,但是画家算法会造成许多重复的绘制任务,对于 IBM 兼容机来说负担较大。因此,《毁灭战士》的渲染器换了个方向,首先绘制距离玩家较近的图形,之后再绘制离玩家较远的。这种反向排序很容易通过 BSP 树来实现,因为你可以在树的每个节点都进行反向遍历。为了避免绘制出来的远处图形遮挡到近处的图形,《毁灭战士》的渲染器使用了一种隐式 Z 缓冲区,这种缓冲区不仅具备普通 Z 缓冲区的优势,而且对内存的要求也较低。这种 Z 缓冲区有两组数组,一组记录水平方向的遮挡关系,另两组记录自屏幕顶部和底部的垂直方向的遮挡关系。《毁灭战士》的渲染器就算不使用实际的 Z 缓冲区也无伤大雅,因为从技术上来看它并不是真正的 3D 游戏。BSP 树数据结构的成本虽然不高,但却能够起作用,其原因在于《毁灭战士》不会发生以下问题:水平方向的遮挡数组能够发挥作用,是因为该游戏中没有倾斜的墙体;垂直方向的遮挡数组能够发挥作用,是因为该游戏不存在有着一上一下两扇窗户的墙体。

剩下比较棘手的问题是如何将《毁灭战士》中处于运动中的角色融入到借助 BSP 树绘制的静止的关卡几何图形中。该游戏中的敌人不可能纳入 BSP 树之中,因为他们会移动,而 BSP 树只对静止的几何形状起作用。所以渲染器首先绘制静止的关卡几何图形,同时与另一个内存使用效率较高的数据结构协作,记录屏幕上分割出来用于绘制的区域。之后,渲染器按照由后往前的顺序绘制敌人,并消除被屏幕上的区域遮挡住的敌人。这一过程与使用 BSP 树进行渲染相比,效果稍差一些。但是由于关卡中能看到的敌人的数量少于几何图形的数量,所以速度并不是一个严重的问题。

将 BSP 树应用到《毁灭战士》中可谓一大成功。卡马克能够想到 BSP 树是解决 VSD 问题的最佳方案,无疑非常高明。但是这可以称得上是天才之举吗?

桑格勒德在其关于《毁灭战士》游戏引擎的书中引用了罗梅洛的话:内勒的论文《构建高质量的分割树》主要讲述使用 BSP 树消除 3D 模型的背面。 [6] 根据罗梅洛所言,卡马克认为这种算法对《毁灭战士》依然有效,所以他放手一试,将 BSP 技术应用到了该游戏中。不过这话说得有些奉承的意味 —— 意在暗示卡马克在别人仍然使用 BSP 树渲染静止的场景时,发现该技术可以用于实时游戏领域。在《Doom 启示录》中也有给卡马克戴高帽的故事。该书作者库什纳认为,卡马克在阅读内勒的论文之后,问了自己,“如果使用 BSP 技术创造一整个虚拟世界,而不仅仅是一张 3D 图像,会怎么样呢?” [7]

这些“片面之词”忽视了 BSP 树的发展历史。当美国空军研究人员开始意识到场景分割可能会加快渲染任务的时候,他们就对提升 实时 渲染的速度产生了兴趣,毕竟他们当时试图创建一个飞行模拟器。1980 年,同样的案例再次出现在了福克斯等人的论文中,他们探讨了 BSP 树如何应用于飞行模拟器中,帮助飞行员进行训练:飞行员用它来反复练习将飞机降至同一空港。由于空港的地形不会发生改变,BSP 树只需生成一次,即可一劳永逸。很明显,他们考虑的是实时模拟。在论文的引言部分,福克斯等人还谈到实时图形系统必须在至少 1/30 秒内生成一张图像,由此激励了他们的研究。

因此,卡马克不是第一个想到在实时图形模拟中应用 BSP 树的人。诚然,设想与付诸实践是两码事。但是即使在实施的过程中,卡马克受到的帮助与指导可比人们想象的要多得多。至少是到这篇文章写成之时,BSP 树的 维基百科词条 页面显示,卡马克参考了 1991 年 Chen 戈登 Gordon 的一篇论文,以及 1990 年的一本教材《计算机图形学:原理及实践》。尽管该页面并未提供引用信息,但可信度没什么问题。陈和戈登的论文介绍了运用 BSP 树由前向后的渲染方法,这种方法与《毁灭战士》中用到的方法基本一致,还包括了我称之为“隐式 Z 缓冲区”的数据结构,可用于防止远处的图形在绘制时遮挡近处的图形。《计算机图形学:原理及实践》详细介绍了 BSP 树,以及一些构建并展示 BSP 树的伪代码(非常感谢我大学的图书馆,让我能够一睹这本教材 1990 年的版本)。因为这本书是计算机图形学的经典之作,所以卡马克很可能也有一本。

然而,卡马克发现自己遇到一个新问题:如何让第一人称射击游戏在一台 CPU 甚至都无法进行浮点操作的电脑上运行呢?通过调查研究,他证明了 BSP 树的数据结构非常适用于实时电子游戏渲染。尽管 BSP 树早已提出,而且到了卡马克的时代,相关理论已经非常成熟了,但我始终认为,卡马克的做法可谓惊人之壮举。也许,得到人们称誉的应该是整个《毁灭战士》的游戏引擎,它的确非常精致。我在前文也提及过,但是桑格勒德的《 游戏引擎黑皮书:毁灭战士 Game Engine Black Book: DOOM 》 很好地讲解了这款游戏引擎的非凡之处,以及这些优势相互契合之法。要明白,VSD 问题只是卡马克在编写《毁灭战士》游戏引擎时需要解决的诸多问题之一。不得不说,面对不为大多数程序员所知的复杂的数据结构,卡马克能够查阅相关文献,将其付诸实践,仅此一点就足以说明其技术之精湛、匠心之独到。

如果你喜欢这篇文章,欢迎关注推特 @TwoBitHistory,也可通过 RSS feed 订阅,获取最新文章(每四周更新一篇)。


  1. Michael Abrash, “Michael Abrash’s Graphics Programming Black Book,” James Gregory, accessed November 6, 2019, http://www.jagregory.com/abrash-black-book/#chapter-64-quakes-visible-surface-determination. ↩︎
  2. R. Schumacher, B. Brand, M. Gilliland, W. Sharp, “Study for Applying Computer-Generated Images to Visual Simulation,” Air Force Human Resources Laboratory, December 1969, accessed on November 6, 2019, https://apps.dtic.mil/dtic/tr/fulltext/u2/700375.pdf. ↩︎
  3. Henry Fuchs, Zvi Kedem, Bruce Naylor, “On Visible Surface Generation By A Priori Tree Structures,” ACM SIGGRAPH Computer Graphics, July 1980. ↩︎
  4. Fabien Sanglard, Game Engine Black Book: DOOM (CreateSpace Independent Publishing Platform, 2018), 200. ↩︎
  5. Sanglard, 206. ↩︎
  6. Sanglard, 200. ↩︎
  7. David Kushner, Masters of Doom (Random House Trade Paperbacks, 2004), 142. ↩︎

via: https://twobithistory.org/2019/11/06/doom-bsp.html

作者:Two-Bit History 选题:lujun9972 译者:aREversez 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

无处不在的 DOOM,这次是拖拉机

在最近的 Def Con 安全会议上,安全研究人员演示了在约翰迪尔 4240 拖拉机的显示屏上运行 DOOM 游戏。研究人员花了数个月时间,来越狱该拖拉机所使用的 Linux 系统。在拖拉机上运行的 DOOM 游戏也经过了特别修改,场景被设置在玉米田里,玩家操纵拖拉机去消灭敌人。这一尝试不仅仅是好玩,其展示的获取 root 访问权限的方法,可能有助于农民绕过这类拖拉机的限制,自行维修拖拉机,这算是对“维护权”的一种努力。

消息来源:Wired
老王点评:方法已经有了,现在就缺一台可以玩 DOOM 的拖拉机了,知道这拖拉机多少钱嘛。

中国主要互联网公司向网信办备案算法

网信办上周公布了境内互联网信息服务算法备案清单,中国主要互联网公司向网信办披露了其使用的算法细节。清单包含了 30 个备案算法,其中包括网易新闻的推送算法和信息搜索算法,360 的搜索信息检索算法,微博热搜算法,美团配送调度决策算法,百度信息检索算法,抖音个性化推荐算法,淘宝推荐算法,微信看一看个性化推送算法,等等。

消息来源:Solidot
老王点评:被算法操纵下的世界,公开不公开,都无法逃避算法的操纵。

微软为 Ubuntu 22.04 LTS 提供原生 .NET 6 支持

微软和 Canonical 共同宣布了在 Ubuntu 22.04 LTS 主机和容器环境中可原生运行 .NET 应用。微软的 .NET 6 现在可以在 Ubuntu 22.04 LTS 上通过简单的命令安装使用。.NET 开发平台是微软对开源项目最早的贡献之一。Canonical 为 .NET 6 LTS 和 ASP.NET 运行时发布了新的、符合 OCI 标准的超小型设备镜像,无需 Shell 或软件包管理器。

消息来源:Ubuntu
老王点评:来自官方的 .NET 原生支持终于出现了,不知道有多少 .NET 程序会在 Linux 下运行?

谷歌表示该让小企业长期用户付费了

谷歌表示旧的免费版办公套件的长期用户必须开始每月支付费,通常是每个企业邮件地址 6 美元/月。到 6 月 27 日还未自愿切换到付费服务的企业将被自动转为付费服务。如果他们在 8 月 1 日之前没有付费,帐户将被暂停使用。受到这一变化影响的小企业主们表示,他们对谷歌处理这一问题的方式感到失望。他们忍不住会觉得这家拥有数十亿美元利润的大公司就为了一点点钱,而压榨这些最早使用谷歌应用工作的“小虾米”企业。

消息来源:纽约时报
老王点评:地主通常都会说,地主家也没余粮啊。但是让这些习惯了免费套餐的人来说,就很难受了,甚至这不是钱的事,而是心理感受不好。

智能灯的芯片就能运行《毁灭战士》游戏

一位软件工程师在阅读了关于《毁灭战士》据称可以在验孕棒上运行的新闻后,开始了这个项目。他拆下了一台 15 美元的宜家智能台灯的电脑芯片,用它建立了一个小型化的《毁灭战士(Doom)》游戏系统。它运行的是精简版的《毁灭战士》,需要较少的内存。来自宜家灯的芯片有足够的处理能力,可以在一个廉价的 160×128 像素的显示屏上以每秒 35 帧的速度进行游戏。

消息来源:PCMag
老王点评:好吧,我想象不出来下一步会在什么上面运行《毁灭战士》了,或许是在土豆上?

Cloudflare 出现宕机,1.1.1.1 无法解析域名

北京时间 6 月 20 日下午,Cloudflare 出现了宕机的情况。根据监测信息显示,包括 Discord、Shopify、Medium、Register 等诸多网站和服务都出现了故障。对于使用 Cloudflare 的 DNS 查询服务的用户来说,影响最为严重,他们在中断期间根本无法访问任何网站。

消息来源:Tech Crunch
老王点评:Cloudflare 的防 DDoS 服务是很好,但是这种大型服务总断网也受不了啊。

Doom 游戏被移植到 BIOS 中运行

Coreboot 是一个自由开源的 BIOS 实现,支持许多被称为“载荷”的扩展。用户可以通过选择不同载荷来自定义 BIOS ROM 所包含的功能。在刚刚发布的 Coreboot 4.17 中,除了支持新的主板、提供新的启动程序、支持 AMD 平台安全启动、有一些修正之外,还有……一个 1993 年的移植版 Doom(毁灭战士)游戏。虽然有些“小小”的不足,比如没有声音、不能保存游戏、退出游戏时系统会挂起,但是他们说,“如果你厌倦了太空入侵者和俄罗斯方块等游戏载荷,将 3D 游戏带入你的 BIOS,是一个很棒的新选择!”

消息来源:Phoronix
老王点评:嗯,我启动机器是准备干什么来着?为什么我一直玩游戏……

UNISOC 固件中的一个关键缺陷可阻断通讯

研究人员发现,攻击者可以向附近带有 UNISOC 固件的设备发射一个特别设计的无线电数据包,可以使固件崩溃,在设备重新启动之前,会终止该设备的蜂窝网络连接。事实证明,这个缺陷不仅适用于低端智能手机,而且也适用于一些智能电视。研究人员说该漏洞是在 UNISOC 芯片组的固件中,而不是在安卓操作系统中。UNISOC 是一家有 21 年历史的芯片设计公司,总部设在中国,是世界上第四大智能手机芯片商,仅次于联发科、高通和苹果。

消息来源:The Register
老王点评:最糟糕的就是这种硬件中的安全缺陷,无论是升级还是替换,都非常麻烦。

谷歌助手正在失去基于位置的提醒

这些是非常有用的命令,你可以告诉谷歌助手,比如,“提醒我回家后把垃圾倒掉”,而你的手机一直在追踪你的位置,当你进门时就会提示你。现在谷歌正在发出通知,告诉用户这项功能已经失效,而建议采用定时重复的提醒替代。目前还不清楚为什么谷歌突然要砍掉一个有用的、易于使用的功能。

消息来源:Arstechnica
老王点评:看来不是好的功能都能留下,有时候你不知道厂商在想什么,如果产品是开源的会怎么样?