雷神之锤的3D引擎:迈克尔·阿布拉什(Michael Abrash)的概貌(2000)

2020-11-30 04:44:47

如果您想成为一名游戏程序员, 还是任何类型的程序员,这都是成功的秘诀 仅用两个词:发货。完成产品并将其送出门,然后 你会成为英雄。听起来很简单,但是却是一项令人惊讶的罕见技能,而且 多数民众赞成在软件公司之中。这是为什么。

我的朋友David Stafford,联合创始人 游戏公司Cinematronics的负责人表示,运输软件是不自然的 行动,他是对的。软件项目中的大多数有趣的事情都是较早发生的 在任何可能的情况下,都有大量新代码要编写。由 在项目结束时,设计是用石头雕刻的,大部分工作涉及 修复错误,或试图弄清楚如何在另一个功能中拔腿 在原始设计中从未计划过。所有这些都少了很多乐趣 而不是开始一个项目,而且通常是非常艰苦的工作-但必须先完成 该项目可以发货。我的前任经理喜欢说, 完成项目的前90%,则必须完成其他90%。它的 那第二90%就是成功的关键。

即使是最有趣的情况也是如此 项目。我花了三年半的时间来编写三个程序员 id Software上的Quake游戏,我们竭尽全力推动状态 多人游戏和3D游戏技术的艺术先于市场, 正在研究有史以来最受期待的游戏。令人兴奋 实际上,到最后我们遇到了与其他软件相同的粗糙补丁 项目。我很认真地说,在发货前一个月,我们 因在Quake上工作而病死。

许多程序员可以做到这一点 第二90%的人会变得疲倦,无聊和沮丧,换工作或失去专注力, 或找借口拖延。有上百万种方法无法完成 项目,但只有一种方法可以完成:低下头并磨碎它 直到完成。这样做,我向您保证编程世界将 成为你的。

它为戴夫工作;电影电子 成为一家成功的公司,并被Maxis收购。它对我们有用 id,以及。 《毁灭战士》是历史上最成功的游戏之一, 我们想顶。对于程序员而言,目标是设定新标准 适用于DOOM的3D和多人游戏(尤其是Internet)技术 风格,而Quake就是这样做的。让我们看看它是如何工作的。

DOOM具有同步的点对点 网络架构,其中每个玩家机器运行一个并行游戏引擎, 机器同步进行。这对于两人游戏来说相当不错 现代游戏,但很难支持许多来来去去的玩家 会且不太适合互联网,因此我们采用了另一种方法 为雷神之锤。

Quake是客户端服务器 应用程序,如图一所示。所有游戏和模拟均已执行 在服务器上,所有输入和输出都在客户端上进行,这基本上是 无非就是一个专门的终端。每个客户都收拾键盘, 每个帧的鼠标和操纵杆输入,并将其发送到服务器;的 服务器从所有客户端接收输入,以固定的时间片运行游戏, 并将结果发送给客户;客户显示结果 在收到它们的下一帧中。即使是单人游戏也是如此 模式,但是这里的客户端和服务器实际上不能是单独的进程, 因为Quake必须在非多任务DOS上运行;相反,在每个 框架运行客户端的输入部分,然后服务器执行,并且 最终,客户端的输出部分显示当前帧,其中包含所有 客户端和服务器之间通过通信进行的通信 使用内存缓冲区作为传输层。在多人游戏中,客户端 和服务器是独立的进程,在不同的计算机上运行( 侦听服务器的特殊情况,其中多人服务器和一个 个客户端在一台计算机上以相同的进程运行)。

客户服务器具有明显的优势 用于多人游戏,因为它极大地简化了同步问题 各个玩家之间。也许不太明显的是客户端服务器是有用的 甚至在单人游戏模式下,因为它强制执行模块化设计,并且具有 客户端和服务器之间的单个通信通道,简化了调试。 对单人游戏和多人游戏使用相同的代码也有很大帮助 模式。

客户服务器的一个有趣的问题 架构就是互联网。 Quake从一开始就为 多人游戏,但是互联网游戏,这在早期并不是主要问题 游戏引发了一些有趣且独特的问题,因为通信延迟 在Internet上的时间比在LAN上的时间更长,甚至比 直接连接的调制解调器,并且因为数据包传递的可靠性较差。

在发展的初期, Quake对所有内容都使用了可靠的数据包传递。用这种方法 数据包被发送出去,并且确认被送回,如果确认 如果没有收到,一切都会停止,直到重新发送成功为止。这个 这是必要的,因为仅向客户发送了更改为当前状态的信息, 而不是当前状态,以便减少 需要发送,而当发送任何更改时,其实质是 会收到所有更改,否则累积状态将不正确。

可靠数据包的问题 传递是,如果数据包丢失,则需要很长时间才能找到 (从服务器到客户端至少一次往返),然后需要很长时间 重新发送它的时间(至少是另一个往返)。如果ping到客户端 是200毫秒(大约是PPP连接可能的最佳状态),然后是丢包 会导致几百毫秒的毛刺-足够长 引人注意和烦人。

相反,Quake现在使用可靠的 数据包传递仅用于分数和级别更改之类的信息。当前 每个时间片都会发送游戏状态(例如玩家和对象的位置) 不是变化,而是整体压缩,因此不会占用太多 带宽。但是,此信息的发送并不可靠。那里 不是确认,服务器和客户端都不知道也不在乎 这些数据包是否到达。每个更新包含与每个更新相关的所有状态 该帧的客户端,因此所有丢失的数据包意味着整个世界的冻结 对于一个服务器时间片;服务器时间片以恒定的速率进入 每秒10或20秒,因此丢包导致的毛刺不超过 100毫秒,这完全可以接受。

客户端服务器施加了潜在的 玩家动作之间的较大延迟,例如按下跳转键,以及 玩家看到所产生的动作,例如他的观点跳入 空气。该动作必须往返于服务器并返回,因此延迟 在LAN上可能几乎从没有时间变化到数百毫秒 在网上。较长的等待时间可能会使游戏难以玩。由 玩家实际跳跃时,他可能已经向前移动了许多英尺并跌倒了 进一个坑。此问题增加了运行部分或全部 客户端上与服务器并行或与其他服务器并行的游戏逻辑 对等体系结构中的客户端,因此客户端可以具有更快的响应速度。

更好的响应就是一切, 但是在客户端上进行仿真存在一些严重的问题。对于一个 事情使通讯和游戏逻辑变得更加困难,因为 服务器上的一个中央主模拟,现在可能有一个 十几个或更多需要同步的模拟。只有一个结果 可以允许任何事件,因此在客户端模拟中必须有一种机制 用于确定在发生冲突时谁的决定胜出,并撤消操作 被另一个模拟否决了。更糟糕的是,不可避免地存在悖论, 例如,一名玩家发射火箭并​​看到它击中了对手-但 然后在当地客户被推翻后看到对手神奇地复活。 虽然Quake有滞后性,但没有悖论,这在很大程度上帮助了 使体验变得真实。

雷神之锤确实使用了一种快捷方式 帮助滞后;如果玩家转向另一个方向,那会发生 立即,无需等待服务器处理输入并返回 新状态。没有自相矛盾或同步问题 与Quake一起转弯,即时转弯使游戏感觉更加丰富 反应灵敏。 (在QuakeWorld中,目前正在进行多人跟踪 开发方面,我们走得更远,并模拟了玩家的移动, 但在客户端上没有别的,我们发现这确实可以改善 上网的感觉相当好,尽管偶尔会有未成年人的损失 悖论。)

Quake服务器维护 游戏的时基和状态,执行对象移动和物理操作,并运行 怪物AI。服务器最有趣的方面是 其数据驱动。每个级别(当前世界)均已完整描述 按对象位置和类型,墙壁位置等存储在数据库中 从磁盘加载。物体和怪物的行为同样在外部 可编程的,由以内置解释语言编写的功能控制, 雷神之锤C. Quake在一定程度上受其外部数据库控制 人们不仅能够创造新的水平,而且他们已经 能够添加新的游戏元素,例如跟踪人员,飞机的智能火箭 可以爬进并飞行,并且警报器会粘在玩家身上并发出刺耳的声音 我来了!-全部都无需编写C或汇编代码的任何一行。这个 灵活性不仅使Quake成为创造力的绝佳平台,而且 在开发游戏时也有很大帮助,因为它使我们能够 尝试更改,而无需重新编译程序。确实,水平和 Quake-C程序可以重新加载并试用,而无需退出Quake。

如果您好奇,那里有很多 Internet上可用的Quake-C代码集。 Quake Developers是一个出色的网站 页面(http://www.gamers.org/dEngine/quake/)。您可以找到有关的信息 也在那里制作自定义的怪物和关卡。

服务器和通信层 是《雷神之锤》的关键元素,但它是玩家的客户 真正地互动,并且其具有魅力成分的客户- 3D引擎。客户端还处理键盘,鼠标和操纵杆的输入,声音 混合和二维绘图,例如菜单,状态栏和文本消息,但是 这些很简单; 3-D是动作所在。面临的挑战 Quakes 3-D引擎具有双重优势:允许在各个方向上进行真正的3-D观看 (与DOOMs 2.5-D不同),并通过照明提高视觉质量,更多 精确的像素放置或其他所需的像素-都具有出色的性能, 当然。

与服务器一样,3D引擎 是数据驱动的,工程图数据分为两类,即世界 和实体。每个级别都包含有关墙壁几何形状的信息, 地板等等,还有关于绘制到这些地板上的纹理(位图)的信息 面孔。 Quake数据库还包含三角形网格和纹理 描述玩家,怪物和其他移动物体(称为实体)。本来, 我们计划通过一个渲染管道绘制Quake中的所有内容, 但事实证明,这两种方式都无法获得良好的性能 由一条管道中的数百个微小多边形组成的墙壁和怪物, 因此世界和实体是通过完全不同的代码路径绘制的。

世界存储为数据结构 被称为二进制空间分区(BSP)树。 BSP树非常复杂 解释一下,所以我在这里不做详细介绍,但是如果您有兴趣,我会写 关于多布斯博士资料手册中的BSP树;看五月,七月和十一月, 1995年发行。出于Quakes的目的,BSP树做了两个非常有用的事情: 它们使从前到后或从后到前遍历一组多边形变得容易 有序,然后将空间划分为凸卷。

如果需要,从后到前的订单很方便 您可以绘制完整的多边形,因为您可以从头到尾绘制所有多边形 并获得正确的遮挡,这个过程称为画家算法。在地震中 但是,我们从前到后绘制多边形。确切地说,我们将所有多边形 并将他们的优势纳入全球名单;然后我们栅格化此列表并绘制 仅可见(最前面)部分。这种方法的最大优点是 我们只绘制一次世界上的每个像素,从而节省了宝贵的图纸 复杂场景中的时间,因为我们不会在另一个之上重叠绘制多边形。 (有关DDS的进一步讨论,请参见1996年5月和7月的DDS问题 地震边缘列表。)

但是,边缘列表并不是很快 足以处理视图金字塔中的数千个多边形; 如果将这么多的边缘放入边缘列表,则得到的帧很慢 率,因为有太多的数据需要处理和排序。所以我们限制 利用多边形必须考虑的多边形数量 BSP树的凸分区属性以计算潜在可见 设置(PVS)。将关卡处理为Quake格式时(单独 通过实用程序在构建地图时执行一次预处理步骤) 从层构建树,然后为每个凸子空间(称为叶)构建树 在BSP树中,执行可见性计算。对于给定的叶子, 该实用程序会计算从该位置的任何位置可见的其他子空间 叶子,并且该信息与叶子一起存储在BSP树中。其他 话说回来,不管你站在楼下厨房的什么地方,你都做不到 可能看到楼梯进入卧室,省略了卧室多边形 从厨房叶子PVS;如果你能从角落看到客厅 在厨房里,厨房里的叶子让PVS记得客厅的鸽子是 潜在可见。我们可以确定叶子的PVS包含所有 我们是否需要考虑玩家是否站在该多边形中 叶,因此在渲染时,而不是处理成千上万的多边形 在一个级别中,我们只需要处理-剪辑,变换,投影和插入 边缘列表-当前叶子PVS中的几百个多边形。这减少了 多边形加载到边缘列表可以处理的水平,PVS和 边缘列表共同为各种应用提供了快速,一致的性能 场景。 DDS(1996年1月)更详细地介绍了PVS。

关于PVS的一点:它可以 计算起来非常昂贵。 PVS测定可能需要15或20分钟 完成-在四处理器Alpha系统上!幸运的是,奔腾Pro系统 变得足够快,可以很好地处理工作,并且毫无疑问,代码可以 速度更快,但要意识到PVS的功能是有代价的。

一旦边缘列表完成 处理所有边缘,剩下覆盖屏幕的一组跨度 一次。我们将此列表传递给光栅化器,该光栅化器将相应的纹理映射 位图到这些跨度上,说明了透视图(这需要昂贵的 每16个像素进行除法,然后进行插值 在这些点之间线性变化。 (这是实现真正的3D观看的关键步骤 在任何方向上。)

照明涉及真正的光源 和阴影,与DOOM的原油照明不同。这是执行 通过具有单独的光照贴图(基本上是纹理贴图,但具有光照值) (而不是颜色)的每个多边形,并在16像素网格上采样光, 然后根据网格将每个多边形的纹理预照为纹理 被绘制到内存缓冲区中;实际的纹理映射从这些预照明工作 纹理,在纹理贴图本身期间不发生照明。我不 有空间来解释这与普通照明有何不同,或为何如此 理想的选择,只是说它可以产生详细的高质量照明 和良好的性能,但是您可以在11月找到详尽的解释, 1996年,DDS。

DOOM使用了平面海报-精灵- 怪物和其他移动物体,以及雷神之锤的重大进步之一 切换到多边形实体,它们是真正的3D对象。但是这个 引起了新的关注;实体可以包含数百个多边形,并且可以 使其一眼可见,因此快速绘制它们是我们的主要任务之一 挑战。每个实体由一组顶点和一个三角形网格组成 跨越那些顶点。实体中的所有顶点都经过变换和投影 作为一组,然后使用仿射(线性)绘制所有三角形 比透视正确的纹理映射;仿射更快,实体多边形 通常很小而且很远,仿射arent的缺点 显。此外,实体抽屉针对小三角形进行了优化, 而不是为世界抽屉优化的大跨度图纸;事实上, 有一个特殊的超快抽屉,用于远处的实体,您可以阅读 大约在1997年1月,DDS。

但是,最大的不同是 使用z缓冲绘制实体;即每个像素的距离 将要绘制的图像与要绘制的像素的距离进行比较(存储 在称为z缓冲区的内存区域中),并且只有当新像素 靠近。这使实体可以与世界以及彼此无缝地排序,没有 无论他们在哪里移动或以什么角度观看。有一个成本 确定; z缓冲比非z缓冲绘图慢,并且z缓冲 必须初始化以匹配可见的世界像素,其成本约为 Quakes性能的10%。但是,这笔费用远远超过了偿还的费用 通过z缓冲的简单性和准确性,这使我们不必 执行复杂的剪切和排序操作以正确绘制实体, 并在所有情况下为我们提供完美的绘图。

PVS有助于改善实体绩效, 因为我们只需要为当前叶子绘制PVS中的实体。 就客户而言,其他实体不存在;服务器没有 甚至不愿发送关于PVS之外任何东西的信息,这不仅 有助于减少图纸负荷,但也可以最大程度地减少信息量 必须通过调制解调器或Internet发送。

最后,我们希望 在Quake中具有烟雾痕迹和巨大爆炸的效果,但无法 弄清楚如何使用标准Sprite快速,良好地完成它们(尽管 爆炸的核心是精灵)或多边形模型。解决的办法是 使用数百个正方形,彩色,z缓冲矩形缩放的云 与距离,称为粒子。火箭后面散布了几百个粒子 看起来像火焰和烟雾的痕迹,特别是当它们开始时 黄色并逐渐变成红色,然后变成灰色,并且作为一个整体,它们表现出色 让眼睛相信它们代表了真正的3D对象的工作。

颗粒和不可靠的包装 交付,以及动态照明,可实现爆炸和枪口闪光 雷神之锤引擎的最新成员之一是点亮世界 这些功能使一个渲染良好但有些不育的世界活跃起来。 这些以及菜单等详细信息,大量优化

......