EP.004 / TRANSCRIPT

虚拟逐字稿

John Carmack(下):购买未来的人

FINAL MASTER / release-approved

没有画完的屏幕

0:00

上期结束时,我们留下了几个没有打开的技术问题。

为什么一块屏幕可以少画?为什么一张地图能提前计算?为什么缓存、预测和工具链,可以让玩家先看到结果?

这一次,我们不再追踪 John Carmack 换过哪些工作,也不再从一家公司里谁等待谁开始。

我们打开机器,看那些被省下来的等待去了哪里。

先回到一九九零年。

Commander Keen 向右奔跑,地面从脚下连续经过。新的砖块、敌人和平台从屏幕边缘出现。玩家看到的像是一个早已存在于屏幕外面的世界。

可那台 PC 没有在每一帧重新画完整画面。

如果它没有完成我们以为它完成的工作,那它交给玩家的,究竟是什么?

这里是《原代码》第三期,《虚拟-John Carmack》的下半部分,《购买未来的人》。

先把屏幕想成一扇窗。

窗外有一张比窗口更大的纸。人物往右走,不需要重新画整张纸。程序移动窗口,再处理右边刚刚露出来的窄条。

EGA 显示控制器允许程序改变屏幕从显存的什么位置开始读取。还可以用更细的像素平移,让窗口不必一次跳过整块字符或整组字节。屏幕上的同一个位置,不需要永远对应显存里的同一个地址。

这些能力在 Carmack 写 Commander Keen 以前已经公开存在。

一九八七年,程序员和技术作者 Michael Abrash 在文章中解释过 EGA 的 Start Address、pel panning、虚拟页面、write mode 1 和 page flipping。后来,Carmack 为 Abrash 的《Graphics Programming Black Book》写前言,明确说,是 John Romero 让自己注意到 Abrash 的文章。他从那些文章里学会显示控制器的细节,再发展出自己的技巧,其中一部分成为 Commander Keen 的基础。

知识不是突然出现在一个人的脑中。它先被写成文章,再被同事递进办公室,最后才在另一个具体问题里改变用途。

[001]

引用 [001]

supports

同期文章与本人后见前言共同支撑公开机制和知识传递;不能把 Abrash 的公开知识、滚屏实现或 Keen 全部归给任何一个人。

定位 Abrash 1987 Inside the EGA pp.36-42 on Start Address, pel panning, virtual pages, write mode 1 and page flipping; Carmack 1997 foreword paragraphs on Romero, learning the EGA controller and developing further techniques

查看完整证据关系

真正昂贵的不是让窗口移动,而是给窗口后面准备内容。

最直观的方案,是每移动一点,就把整幅画面重新写入显存。对当时通过总线传输数据的 PC 来说,这一步付不起。

Carmack 后来把 PC 平滑滚屏形容成一种“感觉不可能”的东西。

John Carmack(原声): It's like, if you want to scroll, you can just redraw the whole screen. But then it turns out, well, you're going five frames per second. That's not an interactive, fun experience. You want to be going thirty or sixty frames per second or something. And it just didn't feel like that was possible. It felt like the PCs had to get five times faster for you to make a playable game there. And interestingly, I wound up with two completely different solutions for the scrolling problem. And this is a theme that runs through everything, where all of these big technical advancements, it turns out there's always a couple different ways of doing them. And it's not like you found the one true way of doing it. And we'll see this as we go into 3D games and things later.

第一代办法后来被称为 adaptive tile refresh,适应性图块刷新。

视窗先在有限缓冲区域里移动。走到边缘以后,显示起点会回到原来的位置。画面看起来本该突然跳回去,可程序比较回到原位前后的 tile,只把真正不同的部分写入显存。

天空可以重复,砖块可以重复,一些背景可以在不同位置继续使用。只要内容愿意服从这些规则,大量像素就不必重新穿过总线。

这里的突破不是终于找到了一个更快的完整重画。

方向恰好相反。

程序先决定哪些地方根本不用画,再让显存布局、关卡和美术一起服从这个决定。

[002]

引用 [002]

supports

本人后见口述与参与者项目史支撑第一代方法的局部更新直觉;Vorticons 原源码未取得,不据后期实现补写逐行机制。

定位 Lex #309 01:43:50-01:47:13 on full redraw limits and adaptive tile refresh; Romero DDICI history on the tiled EGA demo

查看完整证据关系

这不是免费运动。

如果每一块背景都不同,第一代办法能复用的东西会减少。屏幕看起来更自由,关卡却在别处接受了约束。

后续技术又换了一种方式。现存的 Keen Dreams 源码里,三份 screen origin 会在六十四 KiB 的显存地址空间中持续漂移。窗口向右走,只补右边新进入的一列;向上走,只补上方新进入的一行。显卡的 write mode 1 可以帮助显存内部复制,dirty tile 记录真正变化的区域,page flip 则让另一页画面准备好以后再显示。

这里必须把时间分开。

Keen Dreams 保存的是后续 drifting 路径,不是一九九零年第一组三部曲的原源码。它能证明第二代结构存在,不能把两代办法合成同一夜完成的发明。

硬件差异还会把假设重新拖回画面。有些 Super VGA 无法按预期回绕,程序到达边缘时只能搬移整屏。Carmack 后来估计,那次停顿大约会持续两百毫秒。

平时被隐藏的代价,会在窗口边缘突然露出来。

[003]

引用 [003]

supports

源码与后见口述支撑后续 drifting 和兼容 fallback;不能把 Keen Dreams released source 冒充 1990 Vorticons 原码。

定位 Keen Dreams id_rf.c screen-origin and /comp paths, id_rf_a.asm dirty-tile/write-mode-1/page-flip paths; Lex #309 01:57:19-02:01:36 on 64 KiB drifting, anomalous SVGA and roughly 200 ms copy hitch

查看完整证据关系

可只要窗口继续正确移动,边缘继续及时补上,玩家感觉到的就不是地址、page 和 tile。

他感觉屏幕外面还有路。

这个结果也不是渲染程序单独完成的。Tom Hall 要用关卡和角色接住滚屏,Adrian Carmack 等美术成员要让有限图块组成有辨识度的场景。技术选择了当前必须更新的信号,内容团队决定这些信号能不能成为一个值得继续前进的世界。

屏幕没有保存或重画完整世界。它只是持续给出与玩家行动相符的变化。

虚拟首先不是一张静止图像有多像现实。

而是玩家行动时,图像能不能及时、连续地回答。

[004]

引用 [004]

supports

参与者与同期报道支撑技术、关卡、美术和产品的复数分工;连续世界的解释是节目分析,不把全部结果归给 renderer。

定位 Apogee Keen history pages 2-4 and Romero DDICI history on team roles; Game Developer 1994 report on id engine/content production

查看完整证据关系

Carmack 后来回看这一时期时,说,如果愿意再等大约五年,更多算力会让程序员用直接得多的办法完成相似滚屏。那个 hack 的价值,在于技术还只是勉强可行时,把结果交给当时的玩家。

“五年”只属于 PC 横向滚屏这个例子。

它不意味着 Keen 以后每一款游戏都精确提前五年,也不是年轻的 Carmack 当时已经公开宣布的人生哲学。

再等五年,机器会追上来。

可一九九零年的玩家没有等。

[005]

引用 [005]

supports

编辑后本人访谈支撑横向滚屏的约五年后见判断;不扩大到所有 3D 游戏,也不反投射成 1990 年的公开使命。

定位 Masters of Disruption installment published 2022-01-11, edited answer on side-scrolling, waiting about five years, brute force and barely possible hacks

查看完整证据关系

为了速度,世界先收窄

6:38

少画像素,很快变成另一个问题。

如果玩家不再从侧面看角色,而是站进画面里,机器需要回答多少空间?

最完整的答案可以非常昂贵。任意方向的墙、不同高度的地面、坡面、弧线、彼此穿插的多边形,都意味着更多几何关系、更多遮挡判断和更多像素工作。

早期 id 没有先追求任意世界。

它先让世界收窄。

Hovertank 3-D 的地图可以理解成一张规则方格。程序从玩家位置追踪视线,寻找墙体命中,再把有限墙面投影到屏幕。墙还没有纹理,视窗也不大,但玩家已经能在简单迷宫里向前、转身、射击。

Catacomb 3-D 延续相近的 grid tracing 和裁剪骨架,又为屏幕上的墙面列选择纹理来源。每一列命中墙以后,根据距离决定应该画多高,再从一张六十四乘六十四的墙面纹理中取出对应的竖条并缩放。

Wolfenstein 3D 把这套思路推成高速行动。屏幕每一列沿玩家视线穿过规则网格,第一次撞到墙,就知道这一列要显示哪种纹理、多高、在什么位置。

近处的墙高,远处的墙低。大量复杂三维问题,被收窄成重复而稳定的列式工作。

[006]

引用 [006]

supports

三份后建 released source 支撑规则网格、追踪、列式纹理和缩放机制;它们不是原开发 commit history,也不提供逐行单人作者证明。

定位 Hovertank HOVTRACE.C/HOVDRAW.C grid TraceRay and projected wall paths; Catacomb C3_DRAW.C/C3_SCALE.C 64x64 texture-column paths; Wolfenstein WL_DRAW.C WallRefresh/tilehit/wallheight paths

查看完整证据关系

速度来自一份空间合同。

墙沿着网格排列,通常不能斜着切过房间。地板和天花板的关系有限,复杂高度与任意多边形被排除。敌人和物体也常用只有有限朝向的二维图像,也就是 sprite,来表示。

这些不是玩家启动游戏以前才会读到的技术限制。它们直接决定设计者能修建怎样的走廊、房间和伏击,也决定玩家为什么能高速奔跑。

引擎少回答了一些关于世界的问题,才能更快回答玩家最常提出的那个问题:我现在转身,会看见什么?

从 Hovertank 到 Catacomb,再到 Wolfenstein,团队不断扩大画面,却没有放弃约束。技术给出一组可承受的空间动词,关卡、敌人、武器和节奏再让这些动词变成游戏。

[007]

引用 [007]

supports

来源支撑受限 renderer 与团队产品化;节目据机制说明关卡自由度交换,不说引擎自动决定全部玩法。

定位 Game Developer 1994 id report on simple rendering, speed, tools and content roles; Wolfenstein released source grid/column renderer constraints

查看完整证据关系

Doom 想把不同高度、开阔房间和更复杂连接放在同一张地图里。

规则网格已经不够。

可早期引擎留下的判断没有消失:不要让运行中的每一帧重新理解整个世界。

如果当前机器付不起这件事,就让玩家进入以前,先有人替它做完。

玩家进入以前,地图已经工作

9:09

先站在 Doom 的走廊里。

前方是一扇门,拐角外有怪物,墙的另一边还有房间。地图的大部分区域,此刻不在屏幕上。

最直观的方案,是每帧把所有东西拿出来判断:它在不在视野里,会不会被墙挡住,最后占据哪些像素。

如果机器每次转身都从头回答完整世界,玩家只会停在原地。

Doom 的一部分答案,发生在玩家进入以前。

地图在制作阶段被切分,组织成一棵树。这种方法叫 BSP,binary space partitioning,二叉空间分割。

它不是 Carmack 发明的。

一九八零年,Henry Fuchs、Zvi Kedem 和 Bruce Naylor 已经发表用 BSP 组织静态场景的论文。Carmack 后来回忆,自己从 Foley 等人的计算机图形教材接触这项方法,先把它用于 Super Nintendo 版 Wolfenstein,再带回 Doom。

学术方法、知识入口和产品实现,是三个不同的环节。

把它们压成“Carmack 发明 BSP”,会同时抹掉前人的工作,也看不见 id 真正解决的工程问题。

[008]

引用 [008]

supports

论文直接排除 Carmack 发明 BSP;2013 开放专著保存本人后见顺序,但无原始录音或逐字稿。

定位 Fuchs/Kedem/Naylor SIGGRAPH 1980 BSP paper; Pinchbeck Doom: Scarydarkfast ch.4 edited Carmack testimony on Foley textbook and SNES-to-Doom sequence

查看完整证据关系

id 的 doombsp 工具接过编辑器导出的地图,把线段继续切分,形成凸的子区域,再把 SEGS、SSECTORS 和 NODES 写进 WAD。

这些大写名字不需要记。

重要的是动作:地图还在制作机器上时,工具已经决定哪些线段属于哪个子区域,这些区域怎样分叉,运行时可以从哪里开始走。

游戏开始以后,渲染程序根据玩家位置先遍历较近的一侧。一个区域的包围盒如果不可能进入当前视野,可以提前拒绝;屏幕上的一整段横向范围如果已经被实心墙遮住,后面的空间也不必继续画。

BSP 没有独自解决 Doom 的全部可见性。solidsegs 这样的屏幕列遮挡、受限高度模型和其他裁剪路径同样参与结果。可离线构建已经把“怎样组织地图”从最昂贵的现在搬走。

流畅的一帧,制作机器提前等过。

[009]

引用 [009]

supports

工具与 released source 支撑制作期建树和运行时遍历;公开包 / 源码不是完整 1993 开发历史,BSP 也不是 Doom 全部 hidden-surface removal。

定位 id doombsp README/source on DoomEd .DWD input and WAD NODES/SEGS/SSECTORS output; Doom r_bsp.c near-first traversal, bbox rejection and solidsegs-related clipping paths

查看完整证据关系

Quake 把空间进一步打开。

墙、地面、台阶、敌人和武器都成为可以从更多角度观察的多边形。真正三维的房间可以上下叠放。玩家转身时,机器面对的不再只是二维地图里的墙面顺序。

Michael Abrash 此时加入 id。他不再只是 Carmack 读过的文章作者,而是参与 Quake 可见性与性能方案的图形程序员。

他们尝试过多条路线。

有的方案会漏掉本该看见的表面。有的提取可见区域本身就太贵。有的平均表现很好,最坏的一帧却会突然失控。还有的理论上漂亮,落到内存访问、缓存和裁剪以后不再合算。

Abrash 的同期技术文章保留了这些被实现、测试、再放弃的过程。失败不是为了给最终答案增加传奇色彩。它说明“什么不必在当前计算”本身也需要经过大量计算和判断。

[010]

引用 [010]

supports

参与者同期技术文支撑多轮方案与 Abrash / Carmack 等人的协作;记者驻场只补生产语境,不替代算法来源或逐行作者记录。

定位 Abrash 1996 Inside Quake and Black Book ch.64-70 on failed VSD approaches, memory/performance behavior and team work; Wired 4.08 production context

查看完整证据关系

最终进入 Quake 的关键选择之一,是 PVS,potentially visible set,潜在可见集合。

地图被切成许多末端区域,叫作 leaf。对每一个 leaf,制作工具提前计算:玩家站在这里时,哪些其他 leaf 有可能被看见。

注意,是“有可能”。

PVS 不追求一份每帧零浪费的完美答案。它宁可把一些最终仍会被遮住的表面留在候选里,也要避免运行时搜索整个世界。

结果是一种保守交换:多画一点,换取更稳定的最坏情况。提前生成的数据还会压缩保存,运行时只需取出玩家所在 leaf 对应的集合。

Abrash 把这种做法称为 time shifting,也称为 caching。

不是让工作消失,而是把它从最昂贵的现在,搬到玩家到来以前。

[011]

引用 [011]

supports

技术文与代码物证支撑潜在可见集合和运行时取用;PVS 不是精确可见集,不保证零 overdraw。

定位 Abrash 1996 article / Black Book ch.64-66 on PVS, conservative overdraw, time shifting and compression; Quake model source on leaf PVS decompression

查看完整证据关系

PVS 减少的是空间候选。

Quake 还有另一种缓存,处理表面本身。

一块墙的最终颜色,不只来自基础纹理,还要结合 lightmap,也就是预先保存的明暗信息。最直观的做法,是每一帧、每一个像素重新把纹理和光照组合起来。

surface cache 会按表面和 mip 层级,也就是纹理的不同精细度,保存已经组合过的结果。墙没有变化、光照条件仍允许复用时,渲染程序可以直接取缓存,再把它画到屏幕。

代价被换成 RAM、cache miss、管理逻辑和失效条件。动态光照影响表面时,一部分结果仍要重做。缓存也不是越大越好:它必须和当时 CPU、内存带宽、屏幕分辨率一起平衡。

PVS 回答“哪些空间值得继续看”。

surface cache 回答“已经算过的表面能不能继续用”。

把两个名字都叫作缓存很容易,把它们听成同一个技巧。真正重要的是,它们分别把不同工作搬出了当前帧。

[012]

引用 [012]

supports

参与者技术记录与 released source 支撑 surface cache 模型;缓存代价依当时软件 / 硬件条件,不推广为现代 renderer 的固定结论。

定位 Abrash Black Book ch.68 on Quake surface cache, texture/lightmap composition, mip levels and cache behavior; Quake r_surf source paths

查看完整证据关系

玩家端得到更稳定的帧。

制作端得到的是另一张时间表。

关卡改动以后,BSP、PVS 和光照数据需要重新构建。工具可能运行几十分钟,复杂地图甚至更久。设计师做出一个空间判断,却要等到完整结果回来以后才知道它是否成立。

Abrash 记录,Carmack 一贯主张把运行时代码搬到 utilities 和 preprocessing,却也认为 Quake 可能走得太远,伤害设计师的工作流。

这不是优化的反面。

这是同一项优化从另一张桌子上看过去的样子。

玩家不必等待每一帧重新理解地图,因为内容与工具团队已经把那段等待放进制作期。

[013]

引用 [013]

supports

参与者文字支撑预处理和前沿技术对设计工作的代价;不把所有 Quake 返工、构建时间或延期归给 Carmack。

定位 Abrash Black Book ch.64-70 on preprocessing and design workflow; Electric Playground 1997 answer on bleeding-edge engine changes, discarded content and designer costs

查看完整证据关系

Doom 和 Quake 还把另一种边界交给了玩家。

Doom 的 WAD 让地图和数据可以被替换。Quake 进一步提供 QuakeC、PAK 搜索路径、loose files 和 -game 参数。底层可执行文件可以留在原处,新增内容只覆盖自己改变的部分。

这些接口不是完整商业源码已经公开。

它们更像一份产品合同:这里可以改地图,那里可以改规则,这些路径负责寻找新数据,底层剩余部分仍由引擎保持。

开放一个接口,会降低一类创作门槛,也会固定另一类限制。mod 作者不必重写渲染程序就能制造新世界,但接口以外的能力、兼容责任和工具学习仍然存在。

虚拟世界因此不只是程序向玩家输出画面。其他开发者也开始在稳定边界里增加内容、规则和新的行动后果。

[014]

引用 [014]

supports

同期报道与开发者邮件支撑数据 / 规则扩展接口;WAD、QuakeC 和数据路径不等于完整商业源码发布。

定位 Game Developer 1994 report on Doom mod / level information; Carmack developer mail 1996-06-26 on progs.dat, PAK search paths, loose files and quake -game

查看完整证据关系

服务器还没有同意

15:59

你按下前进键。

角色立刻向前走。

然后才有一个问题出现:服务器还没有同意。

离线预处理适合一张基本静止的地图。网络状态不能在游戏发行以前算完。

在一九九六年的 modem 连接里,玩家的命令先传到服务器。服务器更新权威世界,再把结果送回来。如果客户端什么也不做,角色就会拖在输入后面。

你按下方向。

等待。

然后才移动。

QuakeWorld 选择先行动。

客户端先在本地运行刚刚产生的移动命令,用和游戏相同的规则预测位置。服务器消息到达以后,客户端从最后一个已知正确状态重新开始,再把尚未确认的命令重放一遍。

released source 里的 CL_PredictUsercmd 会把过长的移动命令拆开,再调用 player movement;CL_PredictMove 则围绕最新服务器 frame 组织本地预测。

这不等于客户端获得了世界主权。

服务器仍然拥有最终裁定权,决定哪一个状态算数。客户端只是先借用一个与现有规则一致、随后可以校正的现在。

[015]

引用 [015]

supports

released source 与同期文字支撑本地命令预测和服务器权威;代码公开时间不是 1996 开发 commit history。

定位 QuakeWorld cl_pred.c CL_PredictUsercmd / CL_PredictMove; Carmack .plan 1996-08-02 on client-side movement simulation, last known good server message and authoritative response

查看完整证据关系

在两百多毫秒的链路上,本地移动可以接近单机感觉。

可门不会因此更早打开。

投射物不会因此更早命中。

其他玩家也不会因为你的电脑先猜了一次,就自动做出同样选择。

Carmack 在八月初的 .plan 里说,延迟没有消失。客户端不模拟其他对象,所以玩家可能已经跑到门前,门才打开;横向移动时发射的投射物,看起来也可能从刚才的位置出现。

几天后,他继续收紧预测。模拟三百毫秒时,missiles 和 interactions 会出现严重矛盾。想继续修正,就要在客户端猜投射物、碰撞和其他玩家输入,而最后一项根本无法可靠猜测。

于是预测退回小于一百毫秒的平滑范围。

“The latency isn't gone.”

“延迟没有消失。”

[016]

引用 [016]

supports

同期文字支撑具体失败与退回边界;300 ms / <100 ms 属于 Quake-style twitch game 的当时判断,不推广为所有网络游戏固定阈值。

定位 Carmack .plan 1996-08-02 paragraphs on remaining door/projectile latency and 'The latency isn't gone'; 1996-08-10 technical addendum on 300 ms inconsistency and <100 ms smoothing

查看完整证据关系

这一次,被推迟的不是像素,也不是空间计算。

是“哪一个世界状态算数”的一致意见。

本地预测让一个玩家先行动,权威服务器让所有玩家最终回到同一套规则。两者缺一不可。

如果只保留即时反馈,每台客户端都可以拥有自己喜欢的结果,游戏就不再是共同世界。

如果只保留最终一致,所有动作都等服务器回来,世界又会失去手感。

工程选择发生在中间:允许短暂分歧,准备不断校正,并在分歧开始破坏规则以前停下来。

一个尚未确认的状态,可以先作为可用接口出现。

但接口背后的网络事实,迟早会回来。

QuakeWorld 让玩家端的现在变快了。

它没有回答另一个问题:如果开发工具本身也能立刻给出结果,完整游戏会不会终于不再等待?

三十分钟消失以后

19:07

想象关卡编辑器里的一盏灯。

设计师把它从门边拖到房间中央。旧的制作路径可能需要重新构建 lighting 和 visibility,再等大约三十分钟,才知道阴影是否落在正确位置。

Doom 3 的编辑器让灯光移动以后,结果当场出现。

这不是隐藏进度条。

那段局部等待真的被删除了。

[017]

引用 [017]

supports

本人演讲支撑旧构建等待与实时编辑变化;约三十分钟是项目观察,不推广为所有关卡和工具的固定值。

定位 GDC 2004 Eurogamer transcript sections on roughly 30-minute visibility/lighting builds and real-time editor feedback

查看完整证据关系

Doom 3 的画面目标,是让静态和动态物体都进入更统一的实时光照关系。

一盏灯与一块表面相遇,渲染程序不只贴上一张已经烤好明暗的图片。它会处理表面的凹凸信息、漫反射和高光,再按照灯光颜色、投影与材质阶段组合结果。

动态阴影还需要另一层结构。

程序从光源方向寻找模型轮廓,把轮廓沿背离光源的方向延伸成封闭的影子体,再通过深度和模板测试判断哪些像素处在阴影里。灯移动、物体移动,阴影关系也可以跟着改变。

这套模型让同一房间不再只能依靠预先烤好的光照成立。

它也没有变成物理现实。

不同硬件后端、材质处理阶段、精度、裁剪范围、模板缓冲和每帧预算仍然决定结果。多一盏会影响很多表面的灯,多一组锯齿状轮廓,都可能增加工作。

[018]

引用 [018]

supports

released source 与本人演讲支撑实时 light/surface interaction 和动态 shadow 结构;统一不等于物理正确,GPL source 不自动证明 2004 binary 逐行相同。

定位 Doom 3 GPL tr_render.cpp / draw_common.cpp light-surface interaction and depth/stencil paths; GDC 2004 rendering model and hardware-path discussion

查看完整证据关系

实时光照首先改变了关卡设计师的动作。

过去可以用大量小灯在 lightmap 上填出想要的明暗。新的路径要求内容团队重新学习主光、补光和表面复杂度。模型不仅有多少多边形重要,轮廓有多少细碎边缘也会改变影子体的成本。

画面获得新的自由,内容生产也接受新的规则。

这和 Keen 的 tile 并不相同,却有熟悉的关系:渲染程序决定玩家此刻必须收到什么信号,美术和关卡再把限制变成风格。

[019]

引用 [019]

supports

来源支撑灯光 / 轮廓成本和内容工作变化;不把所有美术选择、工期或项目结果归因于单一 renderer。

定位 Doom 3 GPL shadow / interaction structures; GDC 2004 and associated 2002-2004 interview notes on level-design lighting and content constraints

查看完整证据关系

按最直观的推算,编辑器快了,项目应该缩短。

Carmack 在二零零四年 GDC 演讲里给出的结果却不是这样。

团队已经进入第四年开发。相同的核心图形结果,早在更早一代硬件上就已经有效出现。期间几代显卡能够运行这套技术,玩家仍然没有拿到完整游戏。

他还说,内容制作没有因为即时反馈而变短。

过去一个房间可以在几十分钟里完成。新的关卡从制作到第一次试玩,要以人月计算。有时只为打通一面墙、重新连接空间,也可能再花一周。

工具消除了一种等待,更高的内容标准又把时间吸收回去。

这不是说实时编辑没有价值。设计师不必离开座位再回来,才发现灯放错了。他可以拖动、观察、再拖动,认知和结果之间的距离确实缩短。

可团队也因此愿意尝试更复杂的灯光、更精细的表面和更密集的内容。

优化一个反馈环,不等于优化完整产品。

[020]

引用 [020]

supports

本人演讲支撑图形原型、实时工具和内容周期之间的差异;不把 Doom 3 全部工期归给 Carmack、renderer 或任何单一因素。

定位 GDC 2004 Eurogamer transcripts on fourth-year development, earlier GeForce-era graphics, three hardware generations, Wolfenstein room time, man-months to playtest and a week to alter connectivity

查看完整证据关系

Doom 3 证明,局部等待可以真正消失,完整生产仍会长出新的时间。

下一代技术把这个问题放大到另一种尺度。

一张纹理不再只来自美术工作站上的一张图片。

运行时,它要穿过存储、缓存、内存和 GPU,也就是显卡上的图形处理器。制作时,它又要穿过构建机器和多个平台。最后,它还要在十六点六七毫秒的帧预算里及时出现。

一张纹理背后的工厂

22:35

传统游戏经常把一小块砖墙、泥土或岩石纹理重复铺开。

重复本身,是一种非常专门的数据压缩。同一份图案被用来代表许多表面,显存只保存一次。

可现实中的两块砖,即使看起来相似,也不会拥有完全相同的裂纹、污渍和磨损。

MegaTexture 想让艺术家面对一张巨大的逻辑画布。地表可以留下独特痕迹,而有限显存不必同时装下整张画布。

二零零六年,Carmack 在一份 MegaTexture 问答中先把边界说清楚:如果当时已经有四 GB 显存和更多 RAM,这套技术可能根本不需要存在。

它不是无限资源。

它是为资源限制而存在的安排。

[021]

引用 [021]

supports

本人问答支撑技术存在的具体显存 / RAM 语境;MegaTexture 只是图形资源的一小部分,不扩写成人生哲学。

  • MegaTexture Q&AGamer Within via John Carmack Press Interview Collection / 2006-05-01 / excerpt

定位 MegaTexture Q&A 2006 preserved text pp./text lines 6331-6358 on four-GB graphics cards, more RAM, repeated textures as specialized compression and unique terrain

查看完整证据关系

可以再次想象一扇窗。

应用看到一张非常大的逻辑纹理。系统把它切成页面,按照距离和视点准备不同细节层级。物理显存只保留当前需要的页面,也就是工作集。

玩家移动,视野内的页面继续复用;新页面从更慢的地方读取,上传到更快的位置;已经离开的页面则可以让出空间。

Doom 3 后来公开的源码里保存了一条较早 MegaTexture 路径:每个层级维持四乘四个 local tiles,视点改变以后,仍映射到相同位置的 tile 留下,变化的 tile 才从 .mega 文件读取并上传。

这不是完整 id Tech 5,也不能证明 Doom 3 基础游戏使用了 MegaTexture。它只把工作集的物理动作留在代码里:逻辑世界可以很大,真实驻留窗口始终很小。

[022]

引用 [022]

supports

问答与代码物证支撑逻辑纹理 / 物理 working set;Doom 3 released-source path 不是完整 id Tech 5,也不证明 base game 使用。

定位 MegaTexture Q&A 2006 on paged virtual texturing; Doom 3 GPL MegaTexture.cpp/.h 4x4 local tiles per level, view-centered global mapping, tile reuse/read/upload

查看完整证据关系

在同一份回答里,Carmack 说出一句很容易被单独摘走的话。

“So much of programming, and graphics programming in particular, is just trying to pretend that we've got hardware that's five or ten years more advanced than what we've got right now, by making various algorithmic trade-offs.”

“编程,尤其是图形编程,很大一部分,就是通过各种算法权衡,假装我们拥有比现实先进五到十年的硬件。”

先不要急着把这句话变成标题答案。

此刻我们只知道,应用可以面对一张大得多的纹理,显存只保留当前窗口。

我们还不知道,这个窗口背后需要多大的机器、多少人的工作,以及玩家转身太快时会发生什么。

[023]

引用 [023]

supports

保存文本已核对完整上下文;引文只解释 MegaTexture / 图形资源权衡,不证明 Carmack 所有工作共享同一单一原则。

  • MegaTexture Q&AGamer Within via John Carmack Press Interview Collection / 2006-05-01 / excerpt

定位 MegaTexture Q&A 2006 preserved text lines 6337-6349, full answer from four-GB graphics-card premise through algorithmic trade-offs

查看完整证据关系

Rage 给这套技术加上另一项要求:每秒六十帧。

六十帧意味着每帧大约只有十六点六七毫秒。玩家开车、转向、瞄准和射击,输入到画面的链条必须持续服从这个预算。

Carmack 后来把 Rage 的目标并列为六十帧,以及被逐处画过的世界。

这两个目标会彼此争夺资源。

独特纹理需要更多数据和传输,六十帧不允许渲染程序等待所有高细节都到齐。系统必须决定:什么现在交付,什么可以稍后补上,什么画质可以在负载高时暂时降低。

虚拟纹理没有单独制造六十帧。动态分辨率、阴影数量、平台路径、输入与模拟同样进入结果。六十帧更像一份产品合同,整条系统都要围绕它安排工作。

[024]

引用 [024]

supports

本人主讲自动稿与同期实测支撑产品目标和系统代价;自动稿未复听的精确措辞不作额外直引,60 FPS 不归为 virtual texturing 单项结果。

定位 QuakeCon 2011 keynote/Q&A routing on 60 fps and painted worlds; Digital Foundry Rage Face-Off on near-locked 60 fps, dynamic horizontal resolution, input latency and shadow trade-offs

查看完整证据关系

最初的纹理虚拟化实验,可以在几天里看见。

再用数周或数月,demo 可以证明页面能够按需移动,巨大逻辑纹理不必全部驻留。

产品必须面对不同平台、不同存储、不同驱动程序、完整关卡、长时间运行和玩家不会按演示路线行动的视角。

John Carmack(原声): So all of this complexity comes in when you go from kind of the initial cool, elegant demo of something to getting it through, delivering what your artists and designers want, and getting it out onto a shipping project. So lots and lots of work went into doing that, about making this thing that originally really was not that complicated. The initial, you know, it was only a small number of days to do the first sort of virtualization of texturing, and a few weeks to a few months to get something where, like, okay, look, this level is running with virtual textures, it doesn't load anything at the start. But it's taken years and years to get to the point where we have all the capabilities that we really want.

几天出现的东西,花了多年才穿过产品。

这不是因为第一个想法是假的。

而是从“这个办法能运行”到“数百万人能依赖它”,中间还有一整套系统。

[025]

引用 [025]

supports

旧版片段已完成人工核查,但新版上下文需重新门禁;时间描述属于 Carmack 本人产品化回顾,不是独立工时审计。

定位 QuakeCon 2011 aligned old-version candidate 00:18:10.35-00:18:51.20 and GameSpot part-local transcript route on days-to-technique, weeks/months-to-demo and years-to-shipping

查看完整证据关系

玩家眼前的一块纹理,可能先躺在光盘或其他发布媒体上,再进入硬盘缓存,再进入内存,最后成为 GPU 可以采样的纹理。

每跨过一级,容量更小,速度更快。

最慢的位置可以保存更多世界,最快的位置只能保存当前真正需要的部分。

如果系统正确预测玩家视点,页面会在被看见以前抵达。

如果预测失败,低细节表面先出现,更清晰的页面随后补进来。画面已经转过去,世界的细节还在路上。

这时,等待没有进度条。

它直接出现在墙面和地表上。

玩家得到及时动作,也可能短暂看到资源层级的接缝。

[026]

引用 [026]

supports

主讲路由与发布实测支撑多级数据路径和迟到页面;具体严重程度随平台 / 条件变化,不把每次 pop-in 归为同一原因。

定位 QuakeCon 2011 keynote locality sections; Digital Foundry Rage Face-Off texture path from optical media through hard-drive cache, memory cache and on-screen texture

查看完整证据关系

运行时窗口越小,制作端不一定越简单。

Carmack 在二零零七年的 .plan 里写,Rage 的开发环境在最终裁剪和压缩以前,会生成大约一 TB 的原始数据;完整游戏的媒体数据大约二十 GB。

这不是“一 TB 压成二十 GB”的完整测量。两项数字属于不同阶段,也不能与后来问答里的数百 GB 中间数据直接相加。

它们共同说明的是尺度。

艺术家不再只是制作一小块可以重复铺开的泥土。独特纹理允许对世界逐处绘制,也允许投入近乎没有自然上限的细节劳动。原始素材要加工、压缩、切页、构建,再为不同平台生成结果。

玩家机器不必一次装下完整世界。

公司的生产系统必须知道每一块内容在哪里、怎样构建、怎样送到目标平台,又怎样在玩家需要以前抵达。

[027]

引用 [027]

supports

不同年份 / 阶段数字只共同支撑生产尺度,不合并为单次压缩率或统一测量;Q&A 无媒体级时间码。

定位 Carmack .plan 2007-11-02 on roughly 1 TB raw data and 20 GB media; QuakeCon 2011 Q&A text on hundreds of GB, server rooms and content pipeline

查看完整证据关系

这套生产方式还改变了谁能够制造世界。

Keen 的小团队还能把代码、关卡和美术放在一条短链上。Doom 和 Quake 的数据 / 规则接口,又让玩家与 mod 作者继续扩展产品。

到了 Rage,普通创作者面对的不只是文件格式,还有巨量素材、构建、压缩、缓存、跨平台验证和公司级基础设施。

二零一一年 QuakeCon 的问答里,一位听众把问题从“能不能显示这样的世界”转向“普通 modder 还能不能制作这样的世界”。Carmack 随后谈到通用工具包的性能成本、数百 GB 数据和服务器机房。

id 可以继续公开旧引擎源码,却不能因此让当前生产管线、资产和构建机器重新变得个人可及。

引擎源码、编辑工具、原始资产和工业化构建,本来就是不同的门。

[028]

引用 [028]

supports

文字材料支撑 modability 与生产门槛;真实提问媒体 / 说话人未闭合,不写伪逐字引语或原声时间码。

定位 QuakeCon 2011 Q&A first-question text route on mod tools, general-purpose toolkit, performance, data and server rooms; MegaTexture Q&A 2006 on content-creation mindset and small mod-team cost

查看完整证据关系

玩家端确实得到了东西。

Digital Foundry 在 Xbox 360 上测到大约八十三毫秒的输入延迟,抽样片段接近锁定六十帧。为了守住反馈,横向分辨率会根据负载下降,再在条件允许时恢复。

同一时期的实测也看见纹理迟到。

有的场景只在边缘轻微补入,有的快速转身会让高细节延迟明显。平台、安装方式、存储、CPU、缓存和驱动程序,都会改变结果。

PC 首发还叠加了错误驱动程序,让大量用户遇到近乎无法正常运行的问题。

所以,不能把所有纹理迟到和 PC 故障都单因归给虚拟纹理。

也不能因为因果复杂,就说调度成本不存在。

Rage 同时让两件事成立:玩家可以得到低延迟、高帧率和大量独特表面;边界条件下,纹理页面、画质和平台差异也会露出价格。

[029]

引用 [029]

supports

同期实测与本人主讲路由支撑收益和发布边界;不同评测条件不一致,不能用最坏录屏代表所有玩家或把故障全归算法。

定位 Digital Foundry Rage Face-Off pages on Xbox 360 roughly 83 ms input lag, near-locked 60 fps, dynamic resolution, install/cache and PS3/Xbox texture differences; QuakeCon route on PC driver distance

查看完整证据关系

现在,可以回到二零零六年那句“假装拥有未来五到十年硬件”。

这不是说算法从机器里免费拿走了五年或十年。

应用确实获得了一个更大的逻辑纹理空间,玩家确实看见了更少重复的表面,车辆和枪战也确实围绕六十帧响应。

价格同样真实。

显存省下来的容量,在存储和缓存里重新出现。

玩家省下来的等待,在构建、压缩和内容生产里提前发生。

独特画面扩大了艺术家的空间,也扩大了可以投入的劳动。

商业团队获得一套能出货的系统,普通 modder 面前却多出工具、资产和基础设施门槛。

预测正确时,页面在被看见以前抵达;预测失败时,交换关系直接出现在画面上。

这就是“购买未来”。

不是从未来偷走一台机器。

而是先把一种体验带到现在,再让存储、工具、内容劳动、兼容路径、系统复杂度和一部分用户,承担不同份额的价格。

[030]

引用 [030]

supports

标题定义是节目从多项材料得出的分析;事实前提由三组来源分别支撑,不冒充 Carmack 为整个人生建立的正式术语。

定位 MegaTexture Q&A future-hardware and content-cost answers; QuakeCon 2011 demo/shipping/locality/mod pipeline routes; Digital Foundry release measurements

查看完整证据关系

回到玩家的现在

31:44

现在,再把这几台机器放在一起。

Keen 没有完整重画屏幕。窗口移动,新的边缘及时补上。被省下的像素工作,变成显存 bookkeeping、tile 规则和内容约束。

Hovertank、Catacomb 和 Wolfenstein 没有回答任意三维世界。规则网格和列式渲染收窄空间自由,换来玩家转身时的速度。

Doom 和 Quake 没有在每一帧重新组织完整地图。BSP、PVS 和 surface cache 让空间提前计算、让表面继续复用。玩家没有等,制作机器和关卡设计师先等过。

QuakeWorld 没有让服务器答案提前到达。客户端先借来一个本地状态,再接受权威世界回来校正。

Doom 3 真的消除了灯光编辑中的局部等待,可更高精度又把时间吸收到内容生产。

Rage 没有把巨大纹理全部装进显存。工作集在存储层级之间移动,制作端则扩大成更复杂的内容工厂。

这些不是同一项算法。

它们共享的是一个判断:玩家此刻最不能失去什么?

可以晚画一些像素。

可以早算一些空间。

可以缓存已经完成的表面。

可以短暂借用一个尚未确认的位置。

可以让高细节页面稍后抵达。

但屏幕必须连续回应方向键,第一人称转身必须保持行动感,网络世界最终必须回到共同规则,工具必须让内容团队看见自己的决定,产品也必须在市场仍然存在时交付。

技术能改变计算发生的时间和地点。

它不能删除工作本身。

更不能保证局部节省,会自动缩短完整产品。

两期标题里的“虚拟”,到这里才完整。

它不是“假的”同义词。

也不只是 VR 的缩写。

它是一个并未完整存在于当前机器中的世界,依靠经过选择的信号、被重新安排的计算、及时反馈和人与人的关系,逐步成为可以看见、可以行动、可以进入,并可能被共同维持的现实。

Keen 的屏幕选择必须更新的信号。

Doom 和 Quake 重新安排空间与像素工作。

QuakeWorld 保护动作反馈,也维持多人世界的共同规则。

WAD、QuakeC、内容工具和玩家创作,让世界在原作者之外继续变化。

这些结果都不是幻觉的反义词。

它们是物理机器、代码、内容和人的行动,共同维持出来的另一种现实。

“图形世界的王”,讲的是一种工作位置。

Carmack 曾经能够划定当前机器允许什么、暂时放弃什么,让同事、公司和外部开发者围绕一套技术边界安排工作。

“购买未来的人”,讲的是这个位置背后的方法与价格。

他和同时代的开发者把尚未拥有的算力、显存、网络确定性和制作时间,用局部更新、受限空间、预处理、缓存、预测、实时工具和团队劳动,提前变成玩家可以使用的经验。

上期的“王”不是世界的唯一作者。

下期的“购买”也不是一个人独自付款。

Hall、Adrian Carmack、Abrash、关卡与美术、工具与平台工程、mod 作者和玩家,都在不同位置让这些边界成立,也承担边界带来的限制。

最后,再回到一九九零年的方向键。

玩家按下去。

世界必须现在移动。

为了这个“现在”,别处已经开始工作。

片尾

35:21

你刚刚收听的是《原代码》第三期下篇,《虚拟-John Carmack(下):购买未来的人》的重写版本。

本期使用的源码、论文、.plan、技术文章、演讲、访谈和发布期实测,会整理在 show notes 与公开证据页中。

你可以访问《原代码》的官方网站。网站地址是,原代码三个字的全拼,点 X Y Z。在那里,你可以查看本期逐字稿、证据引用关系和证据快照,也可以收听往期节目。

感谢你的收听。

我们下期再见。