RTR4 中文翻译

仅作学习交流,侵删

译者序

其实在这个时间点(2021-10)开这么一个坑并不是一个明智的选择,国内大佬的中文版再有几个月就要出版了。而且这本书也是真的厚,八成坚持不到全部翻译完。 前两天抽时间看了看前面渲染管线的部分,或许是因为之前研究过 DirectX 的原因,读起来还不算特别费劲,所以一咬牙想想还是开一个坑,就算是记录自己的阅读过程,等中文版出了再对比一下找找和大佬之间的差距吧。

暂时不想把图片也 copy 出来,所以以图为参考的时候我可能会变通一下

Chapter 1 Introduction

实时渲染顾名思义就是一门专注于让计算机快速渲染图片的技术。因此它也是计算机图形这门学科里交互性最强的一个领域。交互性我们可以简单理解为计算机构造出一张图片,用户据此做出自己的反馈,然后基于这个反馈计算机再生成下一张图片这么一个循环。而实时渲染要做的就是把这个循环做的足够快,从而让用户看到的不是一张张独立的图片,而是一个动态的场景。

图片渲染的频率我们一个用 FPS(一秒有几帧图片)或者 Hertz(Hz)来表示。如果一秒只渲染一帧(1 FPS),那我们体会不到任何交互的感觉。大概 6 FPS 的时候,我们能有种“交互”的感觉。电子游戏的目标帧率一般是 30,60,72 或者更高。一般在这些帧率下,玩家能够获得相对沉浸式的体验。

视频的帧率一般是 24 FPS,然后通过一个快门系统每帧显示 2-4 次来避免跳帧(flicker)的问题。刷新率与前面提到的 FPS 不同,它用 Hertz(Hz)来表示。每帧显示 3 次那就是 72 Hz 的刷新率。LCD 显示器还会把刷新率和 FPS 代表的显示频率区分开。

译者注: 前文提到的视频的“快门系统”据个人查资料得知主要原因还是传统视频的生成方式(有快门的曝光时间)和目前电脑默认的渲染方式不同,不过自己对这块并不了解就不给概观定论了,感兴趣的可以自己搜索一下。

如果只是看的话,其实 24 FPS 已经足够了,但是更高的帧率会直接缩短交互的响应时间。15 毫秒的延迟就会影响我们交互的体验。例如头戴的 VR 设备一般都会要求至少 90 FPS。

不过实时渲染并不只是强调交互性。如果渲染速度是唯一标准,那么任何能够快速处理用户命令并渲染图片的应用都可以说是实时渲染了。我们所谈的实时渲染一般讲的是生成三维场景图片。

除了前面提到的交互和三维场景以外,实时渲染领域还包括“图形加速硬件”这个部分。一般认为在 1996 年出现的 3Dfx Voodoo 1 是真正意义上的第一片消费级 3D 图形显卡。随着市场的迅速拓展,几乎每台电脑,平板和手机都搭载了图形处理模块。

图形硬件的进步也推动了交互式计算机图形学的发展。本书提供一些用于改善渲染速度和渲染质量的方法,还介绍一些加速算法和图形 API 的功能和限制,由于篇幅限制,不能把每个主题都讲的很深。所以我们的目标介绍一些关键技术和概念,还有该领域里的成熟算法,如果你想了解特定主题,我们也提供了一些参考。我们希望为你提供一把了解这个领域的钥匙,让你觉得读这本书是值得的。

1.1 Content Overview

  • Chapter 2, The Graphics Rendering Pipeline

实时渲染的核心就是一系列用于从场景描述转换称可视内容的方法和步骤。

  • Chapter 3, The Graphics Processing Unit

现代 GPU 通过固定功能和可编程单元组合来实现渲染管线。

  • Chapter 4, Transforms

变换是处理物体位置,方向,大小,摄像机位置,视角的基础工具

  • Chapter 5, Shading Basic

以材质和灯光的定义为切入点,还讨论写实/风格化中它们的运用。与渲染相关的抗锯齿,半透,伽马校正也有介绍。

  • Chapter 6, Texturing

实时渲染中将贴图映射到物体表面最重要的一项技术。

  • Chapter 7, 阴影

添加阴影会使场景更加真实和立体。本章介绍几种应用最为广泛的阴影算法。

  • Chapter8, Light and Color

在介绍 PBR 之前,我们首先要知道如何量化光和颜色。基于屏幕和环境的后处理效果也在这章介绍。

  • Chapter 9, Physically Based Shading

PBR

  • Chapter 10, Local Illumination

  • Chapter 11, Global Illumination

  • Chapter 12, Image-Space Effects

  • Chapter 13, Beyond Polygons

  • Chapter 14, Volumetric and Translucency Rendering

  • Chapter 15, Non-Photorealistic Rendering

  • Chapter 16, Polygonal Techniques

  • Chapter 17, Curves and Curved Surfaces

  • Chapter 18, Pipline Optimization

  • Chapter 19, Acceleration Algorithms

  • Chapter 20, Efficient Shading

  • Chapter 21, Virtual and Augmented Reality

  • Chapter 22, Intersection Test Methods

  • Chapter 23 Graphics Hardware

  • Chapter 24, The Future

1.2 Notation and Definitions

Chapter 2 The Graphics Rendering Pipeline

本章主要介绍“图形渲染管线”,它是实时渲染的核心部分,一般我们简称它为“渲染管线”。它的主要功能包括:生成或渲染图片,操作虚拟相机,三维对象,光源等。所以我们也可以认为渲染管线是实时渲染的底层工具。以一个具体三维场景为例,它最后的位置和形状是由其本身的形状和位置,还有其所处的环境特征还有虚拟相机的位置共同决定。 它最后表现出的外观由材质,光源,贴图,和阴影算法决定。

下面会介绍渲染管线的不同阶段所承担的具体功能,至于具体的应用会在之后的章节中具体说明。

2.1 Architecture

在真实世界中,流水线的概念有很多具体的展现形式,例如工厂的流水线,或者快餐店的后厨。在图形渲染中也有这个概念。渲染管线包括多个阶段,每个阶段承担整个渲染流程的一部分。某个阶段依赖上个阶段的结果,但不同阶段之间是并行执行的,理论上把一个非渲染管线的系统分成 n 个部分并行处理,可以提高 n 倍的速度。这也是我们选择使用渲染管线的主要原因(后面的举例略)。虽然是并行,但因为之间的依赖关系导致整个管线的运行效率是有最慢的那个阶段决定的,也可以说这个阶段是整个系统的瓶颈,因为其他执行快的阶段都会停下来等它处理完才行。

实时渲染管线可以大致分为四个阶段:应用程序处理几何体处理光栅化像素处理。这四个阶段就是实时渲染的管线的核心,也是我们理解本书其他章节的基础。其中的每个阶段都包含一系列的处理步骤,可以把每个阶段看成一个小的管线。在这里我们是有意的把功能与具体实现的方式分开。每个功能都代表某项需要执行的任务,但是具体这项任务在管线中如何执行并没有准确的描述。有可能两个功能被合并到一个单元执行,也可能一个功能被拆分成多个单元执行。

用来衡量渲染速度的 FPS 表示一秒内渲染的图片数量。它的倒数 1/FPS 就是屏幕的刷新率,也可以代表渲染一帧的时间(一般会以 ms 为单位)。渲染每帧的时间不是固定的,它取决于每帧渲染场景的复杂程度。平常我们提的帧率是可以是特定帧的速率,或者特定时间范围内的平均帧率。而刷新率 Hertz 一般用于显示硬件上,这时它表示的是固定频率。

应用程序阶段(application stage)是由应用程序驱动的,也就是说它在 CPU 端的具体软件中运行。CPU 一般都是多核所以能够并行执行大量应用程序阶段的任务。 像物理检测,加速算法,动画,物理模拟等都是运行在 CPU 上。

接下来是几何体处理阶段(geometry proccessing stage)。它主要处理几何体的变换,映射等工作。这个阶段决定我们需要在哪个位置,渲染哪些东西还有具体渲染方式。运行该阶段的图形处理单元包含可编程部分还有固定管线部分。

光栅化阶段(rasterization stage)以三个顶点构成三角形,然后找出所有包含在该三角形内部的像素,并把它们转发给下一个阶段。

像素处理阶段(pixel processing stage)该阶段针对每个像素运行处理程序,决定该像素的具体颜色,还会运行深度测试,判断像素的可见性。它还可以基于原始颜色进行混合处理(blend)。

光栅化阶段和像素处理阶段都发生在 GPU 上。所有这些阶段我们都会在接下来的章节详细介绍。

2.2 The Application Stage

因为这个阶段完全在 CPU 上执行,所以开发者对其拥有完全的控制权。开发者可以按需修改和优化,它也能间接影响接下来管线的运行效率,比如我们可以在这个阶段使用算法减少需要渲染的三角形的数量,来减少之后管线的工作量。

应用程序还可以利用计算着色器(compute shader)把 GPU 当作高效的并行处理器使用。这个过程可以忽略 GPU 作为图形加速器的功能。

这个阶段最后会把需要渲染和管线需要的的几何图元(点,线,三角形)喂给几何处理阶段。这也是这个阶段最重要的任务。

通过软件实现这个阶段的一个副作用就是没有像其他阶段那样分出子步骤,一般都是在 CPU 的几个核上并行执行。在 CPU 的设计中叫做 superscalar construction(目前理解的就是和 GPU 一样把执行过程分解为多个阶段从而运用并行算法提高效率,和渲染管线有些相似),它允许在该阶段同时运行多个处理进程。18.5 章节提供了几种方法来充分利用多核。

物理检测一般就在这个阶段实现。检测到两个物体的碰撞后我们可以反馈给碰撞的物体,也可以施加一个力。我们还可以在这个阶段实现输入检测,然后根据不同的输入触发不同的行为。一些加速算法,例如裁剪算法也可以在这里面实现。总之接下来管线处理不了的东西都可以在这里面处理。

2.3 Geometry Processing

几何体处理阶段发生在 GPU 上,它基于每个三角形和每个 Vertex(Vertex 和几何体的顶点不用,不同面共享的顶点有不同的 Vertex) 进行迭代处理。这个阶段一般会分成多个阶段:

  • vertex shading
  • projection
  • clipping
  • screen mapping
2.3.1 Vertex Shading

这个阶段主要做两件事:

计算 Vertex 的位置和数据结构,例如一个顶点中包含的法线和 UV 信息。一般物体会基于光源和顶点的位置和法线计算出阴影颜色保存在顶点上,并在顶点着色器中对顶点相关的三角形做插值处理。也因此这个可编程的顶点处理单元叫做顶点着色器。随着 GPU 的技术的发展,可以支持更多的顶点(例如 UE5 的 nanite)屏幕上每个像素可能都要执行一次或者几次着色,所以现在很少用它来直接计算着色方程。如今的顶点着色器更多是被当作一个基于每个顶点配置相关数据的独立阶段。在 4.4 和 4.5 章节我们就用它来让对象动起来。

想要计算出最后顶点位置需要把模型在不同的空间/坐标系之间进行转换。最初模型顶点的位置是基于自己的本地坐标系,场景中每个模型都可以用 model transform 来表示。这样的好处是一个模型可以有多种变换(Transform)。这样在相同场景中一个模型的多个副本(instance)可以拥有自己的变换,而且不用复制基础的几何体。

我们所说的模型变换主要指的是变换顶点和法线。模型对象的坐标叫做 model coordinates(本地空间),变换之后模型就处于世界空间之中。世界空间是唯一的,并且场景的所有所有模型都处于该空间中。

只有摄像机看到的模型才会被渲染出来。摄像机在世界空间中有位置和方向两个属性分别表示摄像机的位置和朝向。为了方便做屏幕映射和剔除我们会把摄像机和模型都变换到视图空间(视锥体空间)。视图空间会把摄像机放在原点,视角看向的方向是 Z 轴方向,向上的方向为 y 轴,向右方向为 x 轴。我们默认朝向摄像机的方向是 -z 轴方向,因为很多文章喜欢这么做,不过这不重要,如果反了转一下就完了并不难。变换后的视图空间是什么样的依赖于具体的应用程序实现。变换可以用 4x4 矩阵(matrices)来实现,不过顶点的位置和法线方向我们是完全可以自定义的。

构建一个真实场景只靠模型的位置和形状显然是不够的,还包括模型的材质和光照。从简单的只有颜色到物理正确的精美场景都已经有有很多种实现方式。

这个在材质上决定光照效果的处理过程叫做着色(shading)。