术语表

旧格式

术语表已迁移至 新版文档open in new window 并应用新格式。

插件提示

此页面使用了 LaTeX 公式,第一次进入该页面时公式可能不会正确渲染。
你应该看到下方有一行类似 y=ax2+b 的公式:

$$ y = ax^2+b $$

若你看到的是以 $$ 开头的代码,请刷新页面,或点击

这篇文档列出了整个文档中可能会出现的术语,这些术语或常见或罕见,我们会尽可能多地收录。
在遇到不能理解的专有名词时,可以到此文档中进行查阅。

如果你有更多想要提供的术语,或者发现了术语中的疏漏,可以在 GitHubopen in new window 上为我们提交建议。

约定

  • 粗体:表示强调
  • 斜体:表示引用关键词,有时候会和粗体一起使用。
  • 跳转:作为跳转链接,跳转到文档内其他位置,当链接后跟有 open in new window 时,表示跳转站外链接。偶尔会替代掉斜体
  • 角标:表示这只在对应环境中有效。
  • 代码:表示这是程序运行时显示/日志/代码内容,或计算机行为。
  • 代码块内容 的约定:
    • <尖括号> :由尖括号括起来的内容表示在这个区域内应该填写的内容。例:<文件名>.jpg ,其中 <文件名> 部分可以使用任意符合尖括号内定义的内容替换,例:图片.jpg
      • 在替换时应当将尖括号一同替换
    • [方括号] :由方括号括起来的内容是一个可填的数字,例:vec[N] 可以替换为 vec3
      • 在数组中,方括号不需要被一同替换,此时,例:float[a][b] 可以替换为 float[1][3]
      • 我们约定替换方括号的字母使用大写不替换方括号的字母使用小写
    • 函数() :函数分为原型和调用两种情况。
      • 当函数和参数含有 变量类型 时,表示这是函数的原型。例:float floor(float num)
      • 当函数内参数不含变量类型且含有 <尖括号> 时,表示我们调用函数时会在这个函数内填何种参数。例:max(<numA>, <numB>)
        • 有些函数有多个可以传入的变量类型,此时会在变量类型处使用 <尖括号> ,这种情况下仍然表示为函数的原型。例: min(<int | float> numA, <int | float> numB)

游戏相关

JE

Minecraft Java Edition,即 Java 版游戏,在本文档中,也可以表示只能在Java版渲染模组下有效

  • 原主机版 事实上基于 JE,也称之为 CE
BE

Minecraft Bedrock Edition,即基岩版游戏。

  • 这其中也包含了原 Pocket Edition 版本,也就是通常所说的 PE
  • 现在的主机版也基于 BE
NE

网易 代理的中国版(China Edition)游戏,也称 网易版(Neteast Edition),表示为网易版独占,例:防沉迷 NE,延迟着色 API BE(NE)

这些版本主要用作角标,自此开始无特殊说明的名词均以 Java 版为准。

模组和文件包体

模组/模组加载器

MODMOD Loader,由第三方提供的接口在原版游戏基础上运行由玩家编写的扩展内容,目前主流的加载器有 ForgeFabric ,此外还有 Fabric 的分支版本 Quilt 以及自 JE 1.12.2 停止更新的 LiteLoader ,现在还有从 Forge 独立出来的 Neo Forge ,它的目标是做一个可以通用的加载器。

  • Fabric 的接口(API)和加载器本身是独立的,而其他加载器均内置了接口。

早期的模组由于没有加载器,需要将文件全部覆盖入游戏源文件,因此如果出现两个模组同时需要覆盖同一文件时,这两个模组的兼容性就崩塌了。加载器和接口的出现缓解了这一问题。

资源包

Resource Pack,即通俗所说的材质包,详见:资源包 基本概念

光影包

Shader Pack,由一个或数个 着色器 组成的一套流水线工程,用以渲染画面。

整合包

Modpack,由多个模组整合而成的文件包。

  • 国内的整合包通常是懒人包,即:将游戏本体启动器模组以及其他配置和资源文件打包,玩家解压之后即可启动游玩。
  • 国外标准的整合包是 MultiMC 格式,这种整合包只包含了需要调用的模组的信息,顾名思义,其由 MultiMC 启动器 发起建立,是如今很多启动器都支持的格式,在启动器上在线安装好后即可启动,这通常需要正版账户,由启动器在下载安装模组接口模组其他外围资源时同时下载游戏本体和资源库。
    • 国内的启动器如 HMCLPCL 2BakaXL 等启动器也均跟进支持了此格式。
数据包

DatapackJE 1.13 加入的由官方支持的可以修改世界内数据的文件包,自 JE 1.16-pre1 起可以在创建世界之前加载数据包。

渲染模组和引擎

Blaze3D JE

Java 版现用的渲染引擎。

Render Dragon BE

渲染龙,基岩版现用的渲染引擎。

它的名字来源于末影龙(Ender Dragon)和渲染(Render)。

GLSL Shader Core

光影核心模组最早的 Java 版光影模组。

  • OptiFine 集成后其更新频率明显下降,不再提供新功能支持。
  • 作为一个用于运行老旧光影的备选项,光影核心已于 JE 1.12.2 停止更新。
OptiFine

高清修复,简称 OF ,老牌 Java 版优化模组。作者为 sp614x

  • 最早是提供更大纹理分辨率支持的模组,这也是中文名被翻译为高清修复的原因。
  • JE 1.8 之后集成了 GLSL Shader Core 的功能,开始提供光影支持。
  • 在某一版本中整合了动态光源模组,让世界中的实体光源可用于照明。
Sodium Fabric

意为,伴随 Fabric 出现的新兴优化模组,旨在优化 JE 1.14 后的游戏性能。

  • 伴随钠而出现的许多优化模组开始仿效其使用化学元素来命名自身,被玩家们称为元素周期表/元素全家桶
Iris Fabric

伴随 Fabric 出现的新兴光影模组。由于 OptiFine 闭源导致很多模组无法兼容,而很多玩家想要在整合包中运行光影,Iris 由此而生。

  • 如今 Iris 已经在着手支持独占功能,并且与 Sodium 深度绑定。然而 Sodium 本身的兼容性并不好,通常需要依靠额外的模组如 Indium(铟)来确保其兼容性。
Oculus Forge

IrisForge 分支,旨在提供与 Iris 一样优秀的模组兼容性。

Canvas Fabric

另一新兴渲染模组,完全独立于 OptiFine 之外,通过 资源包 进行加载。具有极强的兼容性和很多独有特性。

Blaze4D Fabric

使用 Vulkan 的实验性渲染引擎。

  • OptiFineSodium 不同,它的目的不是优化,但是也包含了一定的性能改进。
    • 其唯一真正制作的优化工作是 baked-entity-models(烘焙实体模型),并将其提交给了 Sodium 以供所有人使用。
  • 未来将允许开发者将 DLSSFSR 乃至硬件加速光线追踪引入到光影开发中,但是目前来说仍旧遥遥无期。

它的名字来源于目前 Java 版所使用的渲染引擎 Blaze3D

Focal Engine Forge/Fabric

Continuum 研发的渲染模组。

  • 目前是 OptiFine 的增强模组,主要用于他们自己的光影包 Continuum 2.1/RT 的代码支持、加密和联网验证,同时支持 Stratum 的安装。
  • 更长远的目标是独立于 OptiFineVulkan 上实现光影渲染,给其他作者提供加密和联网验证及其他支持,并引入硬件加速光线追踪

它有一个前身名为 Nova Render。由于核心开发人员的离开,这个模组独立了出来,但是很快没了下文。

Advanced Shader Forge

是一个 OptiFine 辅助模组,旨在让 JE 1.12.2 兼容更高版本的光影。

计算机相关

数学基础

标量

也称数量,一个数字就是一个标量。

区间

即取值范围

  • x∈[a, b] 表示 a ≤ x ≤ b;
  • x∈(a, b) 表示 a < x < b;
  • x∈[a, b) 表示 a ≤ x < b。
向量

也称矢量,多个标量构成的有向的量。

  • GLSL 中,我们使用形如 vec3(1.0, 0.2, 3.5) 的方式来表示三维向量。
模长

向量的长度。

单位向量

模长为1的向量。

归一化
  • 对于标量:将特定范围内的数据映射到 [0, 1] 的过程。
  • 对于向量:将一个非零向量转换为单位向量的过程。
点乘

两个向量运算为一个标量,得到的值称为内积。 $$ \vec{\boldsymbol{a}} \cdot \vec{\boldsymbol{b}} = n $$

算法详见 矩阵乘法

叉乘

向量之间的有序乘法,得到的向量称为外积。 $$ \vec{\boldsymbol{a}} \times \vec{\boldsymbol{b}} = \vec{\boldsymbol{c}} , |\vec{\boldsymbol{c}}| = |\vec{\boldsymbol{a}}| |\vec{\boldsymbol{b}}| \sin(\theta) , \vec{\boldsymbol{c}} \bot \vec{\boldsymbol{a}} , \vec{\boldsymbol{c}} \bot \vec{\boldsymbol{b}} $$

其中 θ 为向量 ab 的夹角,方向遵循右手螺旋定则

向量的普通四则运算

将两个同维向量的对应分量或一个向量的所有分量与一个标量进行四则运算。 $$ (a, b, c) \begin{bmatrix} + \\ - \\ \times \\ \div \end{bmatrix} \left[ \begin{array}{c|c} (x, y, z) & p \end{array} \right] = \left[ \begin{array}{c|c} (a + x, b + y, c + z) & (a + p, b + p, c + p) \\ (a - x, b - y, c - z) & (a - p, b - p, c - p) \\ (a \times x, b \times y, c \times z) & (a \times p, b \times p, c \times p) \\ (a \div x, b \div y, c \div z) & (a \div p, b \div p, c \div p) \end{array} \right] $$

矩阵乘法

矩阵乘法中左侧矩阵的必须等于右侧矩阵的,做积所得矩阵为右侧矩阵的左侧矩阵的,即:一个 a x b 的矩阵与一个 b x c 的矩阵,所乘得的矩阵是 a x c 的矩阵。
当向量与矩阵做积时,应该将向量视作一个1列的矩阵: $$ \begin{bmatrix} a & b & c \\ d & e & f \end{bmatrix} (x, y, z)^T = \begin{bmatrix} a & b & c \\ d & e & f \end{bmatrix} \begin{pmatrix} x \\ y \\ z \end{pmatrix} = \begin{pmatrix} ax + by + cz = u \\ dx + ey + fz = v \end{pmatrix} = (u, v)^T $$ 当向量与向量进行点乘时,实际上就是进行了矩阵乘法: $$ (a, b, c) \cdot (x, y, z)^T = \begin{pmatrix} a & b & c \end{pmatrix} \begin{pmatrix} x \\ y \\ z \end{pmatrix} = ax+by+cz $$

计算机基础

像素

Pixel,二维位图的最小显示单位。

在实际渲染或计算中,有子像素(Sub-Pixel)的概念,因此像素仅为位图的最小显示单位。

体素

Voxel,对应像素的定义,作为一种三维图形的表示方法,在此类空间中定义的三维图形,体素是最小坐标单位。

位图

也称标量图,最小单位为像素的图像。计算机中存储的图片大多是位图,如 .jpg.png.bmp 等。

矢量图

顶点位置和连接顶点的线段信息所组成的图像。.svg 就是其中一种矢量图格式。

分辨率

视频文件和显示器中常用的分辨率 1080p 意为 纵向 1080px逐行扫描

  • px 为像素的缩写。
  • p 意为 逐行扫描 ,而 i 则为 隔行扫描
    • 扫描:即从上至下显示画面的过程,这个名词沿用自 CRT 显示器时代 的画面显示方式。从左至右一排像素为一条扫描线
      • 逐行扫描 为从上至下依次显示每排像素,也是现代显示器和视频文件大多数情况下的显示方式。
      • 隔行扫描 以两条扫描线为一组,上面一条称 上场 ,下面一条称 下场上场下场 依次更新,每一轮画面显示只会更新一个场。
        • 这种方法可以减轻 GPU 压力,同时提高画面流畅度,然而其所带来的伪影也较为严重。
  • 伴随此种简写的分辨率出现的还常有 画面比例(也称画幅)。
  • 你可以使用这个公式来计算 横向分辨率 : $$ 纵向分辨率 \times 画面比例 = 横向分辨率 $$
  • 2k4k 等的定义:
    • 由横向分辨率决定,k 的换算公式为: $$ 1\text{k} = 1024$$
    • 标准的 4k 分辨率为 4096 * 2160 ,在 16:9 下为 3840 * 2160 ,由此我们可以知道 $$ N\text{k} = \frac{横向分辨率\text{(16:9)}}{960} = \frac{纵向分辨率}{540} $$
    • 从这个公式还可以知道,所谓 2k 指的实际上是 2048 * 1080,而 2560 * 1440 是 2.67k
      • 这在大多数时候是适用的,然而对于超宽屏,我们通常直接将其横向分辨率视为 Nk

关于资源包分辨率,参阅:资源包 基本概念 - 资源包分辨率

离散和连续

像素和体素都是一种离散的记录方式,它们依照特定的分辨率进行记录。通常使用整数值来表示像素和体素坐标。
与之对应的,矢量图是一种以浮点精度为最大精度记录信息的方式。通常使用浮点值来表示顶点坐标。

颜色通道

颜色通道的数量表示色彩类型的数量,显示器的颜色通道为 RGB ,也就是光学三原色红绿蓝。在此基础上再加上 A 通道,也就是不透明度,就构成了我们常用的 RGBA 格式。在没有特殊说明的情况下,我们都以 RGBA 格式为准。

应用程序接口

API,应用程序接口提供特定的方法,让第三方代码通过它们修改程序。

具象化来说,这就好比给手机(游戏本体)扩展存储(想要达到的光影效果),需要 SD 卡(第三方代码),并且手机需要有 SD 卡槽(接口)才能插入。

编程类

作用域

表示程序和变量可以被调用的范围,在下面这段代码中

[...];
int a = 0;

float function() {
  int b = 0;
  a = 1; // 可行
  [...];
}

void main() {
  a = 2; // 可行
  b = 1; // 不可行
  [...];
}

 


 
 




 
 


a 可以被 function()main() 调用,而 b 只能在 function() 内被调用。
当作用域在最外层(位置形如 a )时,我们称其为全局变量;与之相对的(位置形如 b ),我们称其为局部变量

变量类型和修饰符

在许多语言中,我们都需要在定义一个变量的时候同时定义它的类型。如 int a 前面的 int 就是变量 a 的变量类型,这决定了计算机如何处理它们。

  • 这里列出了一些 C 语言 中常见的变量类型(不包含扩展):
    • int :整数。
      • long:长整数,长度是 int 的两倍。
        • longlong int 表示一个长整型,long longlong long int 表示一个超长整型。
      • short:短整数,长度是 int 的一半。
    • float :浮点数,计算机中可以表示小数的类型。
      • double :双精度浮点,长度是 float 的两倍。
      • half :半精度浮点,长度是 float 的一半。
    • char :单个字符。

除了数据类型以外,我们还可能会用到一些修饰符,它们可以用来对控制变量类型或改变变量的行为,例如 const int b;

  • 这里列出了一些 C 语言 中常见的修饰符:
    • auto :默认的变量修饰符,不指定存放位置,不指定生命周期。通常省略
    • static
      • 修饰函数时:表示该函数只能在此文件内被调用。
      • 修饰 全局变量 时:表示该变量只在此文件内有效。
      • 修饰 局部变量 时:表示退出作用域之后变量不会被销毁,重新进入作用域时变量也不会被初始化(除非在声明时进行了赋值)。
    • register :表示尝试把该变量放入 CPU 寄存器而不是内存中,以获得更快的访问速度,特别是那些经常会访问的变量。
    • const :表示该变量值不能被修改,此时我们可以把其视为恒量
指针

在变量类型后紧跟 * 表示声明一个指针类型的变量,它的值是对应变量类型的内存地址

  • 要对它进行进行赋值,我们需要使用取地址符 & 紧跟一个对应类型的变量。
  • 要想调用它所指向的值,我们要在调用此变量时在前面加上取值符 *
数组

许多同类型数据的集合。通常在数据类型后加 [a] 来定义。[]的数量代表了数组的维度

  • 我们使用形如 int a[][][]...[] 来声明一个数组变量,使用 int[][][]...[] 来直接表示数组类型。
  • 声明出来的数组变量本身是一个指针,我们可以使用形如 a[0] 来访问数组 a[] 中第一维上的第一个元素。
代码示例

在这个示例中,我们使用 C 语言 对前面的说明进行了实践,
为了降低阅读门槛,我们省略了除变量相关外的具体代码,并以 [...] 表示:

[...];
float glva = 0; // 声明一个全局的浮点型

float func1(float para) { // 声明函数,需要传入一个浮点型参数
  static float stva = 1.414; // 声明一个不会被销毁的变量,它只会初始化一次
  stva += para + glva; // 全局变量可以随时使用
  return stva; // 返回计算后的值
}

void main() {
    float pi = 3.14; // 声明一个浮点型
    float* f_ptr = &pi; // 声明一个浮点指针,指向pi
    const float e = 2.7182818; // 声明一个数据不可更改的恒量
    long int g[2][3][3]; // 声明一个长整型数组

    [输出两次 func1(e) 的值];
    [输出数组 g 的值];
    [输出指针 f_ptr 的值,输出指针(取值)*f_ptr 的值];
    [输出全局变量(取地址)&glva 的值];

    [...];
}

 


 
 




 
 
 
 








它的输出结果是:

第一次调用函数的值为:4.13228
第二次调用函数的值为:6.85056
数组变量的地址为:0000008a3d6ff650
指针所指的变量的地址为:0000008a3d6ff6a8,值为:3.14
在主函数中调用了全局变量,它的地址为:00007ff7cf687098
  • 我们可以注意到两次调用函数返回的值不一致,但是我们没有对全局变量 glva 做任何赋值操作,传入的变量 e 是一个恒量,所以只能是没有被销毁的 stva 变化了。
  • 直接输出 g 的值,注意到它输出的是一个16进制的地址。
  • 直接输出 f_ptr 的值,发现它也是一个地址,我们对其取值 *f_ptr 并输出,最终成功得到了 pi 的值。
  • 我们还成功在主函数中输出了全局变量的地址 &glva

图形学(3D)

图形基础

着色器

Shader,光影中包含一个或数个着色器。着色器定义了如何处理传入的三角形,以及向何处输出何种信息。常见的着色器类型见:着色器 技术科普

  • 我们约定,着色器指单个着色器文件,而光影指着色器、配置文件等打包而成的 光影包
渲染管线

Rendering Pipeline,规定了着色器处理画面的顺序。

三角形和法线

不同于前文所述的 体素 ,3D图形更常用的是类似 矢量图 的渲染方法。

  • 计算机图形学约定,三角形的三个顶点以逆时针顺序所形成的平面就是这个形状的正面
    • 垂直于这个面朝外的方向就是这个三角形的面法线(Surface Normal)。
视平面

在场景中所有能看到的内容可以构成一个平头锥体,或者说视锥体。最近能看见的位置所成的平面称为近平面,同理最远可见的位置所成的平面称为远平面。为了保证近处不被意外遮挡或剔除,通常会将近平面设置为一个小值,沿摄像机朝向在Z轴上小于这个位置的几何体都会被剔除。而归一化就是在基于摄像机的坐标系下,将近平面到远平面的坐标映射到 [0, 1] 上。

远平面在 Java 版中被设置为了最大方块渲染距离,即区块渲染距离的一半。

平行光源

也称无限光,距离玩家无穷远处的光源。

太阳和月亮的光照可以近似看作平行光。

点光源

从自身向所有方向发射光照的光源。

在MC中不存在严格意义上的点光源,但 OptiFine 提供的动态光源和一些光影提供的手持光源(实际上是摄像机光源)可以被认为是点光源。Iris 还提供了一个独占特性,让手持光源可以进行投影。

渲染方法

现代常用的渲染方法有两种,向前渲染法延迟渲染法

向前渲染法

顾名思义,在每个着色器中,立即在传入的几何体上计算诸如阴影和反射等效果,然而这会导致在场景几何体较多、几何体之间相对于视角的遮挡较大时产生不必要的开销,因为每个着色器都会将所有传入的几何体计算一遍,即使在之前或之后的着色器中这个几何体会被更靠前的几何体遮挡。

延迟渲染法

不再在传入几何体的阶段立即计算大多数效果,而是分为两个阶段:

  1. 将纯色场景和诸如法线贴图和反射贴图等全部作为纹理映射到几何体上,再分别写入多个缓冲区,并通过颜色附件在着色器之间进行传递,这就是所谓的 几何缓冲阶段
  2. 之后的着色器读取对应缓冲区的这些信息,在铺屏四边形上统一计算光照、反射等其他效果,这就是所谓的 延迟处理阶段
缓冲区

Frame Buffer,可以理解为一张图片,在延迟渲染法中,先在几何缓冲阶段将原始信息写入缓冲区,再在延迟处理阶段调用信息进行运算。

深度缓冲区

Depth Buffer,也叫深度图,是一种特殊的缓冲区,它只有一个通常是 32 位的 R 通道。它所包含的信息是相对垂直于摄像机朝向的平面的归一化距离,越远的地方值越趋于 1.0 ,反之越趋于 0.0

高度图也可以被视作一种反转的深度图。(越高的地方越亮)

几何缓冲(阶段)

Geometry Buffer (Stage),这种阶段的着色器因传入的顶点数据是场景中实际的几何体而得名,它还接受所有原始纹理的传入,并将其映射到几何体上。在这个阶段我们使用的纹理坐标是指原始纹理上的坐标,每个几何体的三角形上的每个点都有其对应的纹理坐标,它们在 OptiFine 管线中以 gbuffers_ 前缀表示。

延迟处理(阶段)

Deferred / Composite (Stage),这种阶段的着色器所使用的信息都是之前的几何缓冲上一个延迟处理着色器绘制到缓冲区的画面。在这个阶段,着色器从缓冲区中读取信息,并将计算结果绘制到铺屏四边形上,不同于几何缓冲中场景三角形的纹理坐标对应原始纹理,铺屏四边形的纹理坐标对应缓冲区。

  • 此阶段无法引入原本场景中额外的几何和颜色信息,不能改变原本的纹理映射坐标。
  • 在这个阶段可以通过各种深度图逆矩阵重建各种坐标。
颜色附件

Color Attachments,是着色器间传递数据的方法,每个颜色附件包含两个缓冲区,以逻辑名称 main )和 alt )标记,在不同系统和 GPU 上,颜色附件的数量可能有所差异。得益于双缓冲区颜色附件,着色器可以读取 缓冲区中的信息进行计算,最后再输出回同附件的 缓冲区。在 OptiFine 中,阴影颜色附件有 2 个,而屏幕颜色附件至多有 16 个。几何缓冲阶段不会翻转缓冲区延迟处理阶段则在每个着色器结束后都会翻转

纹理坐标

Texture UV,以二维纹理为例,对于三维空间中任意三角形的表面上的任意点,都有一个在二维纹理上对应的坐标,这个坐标就是这个三角形此处的纹理坐标。纹理坐标可以在着色器中进行各种变换。

  • 将二维纹理坐标上的颜色映射到三维空间中三角形上的过程,就是纹理映射,而三角形获取纹理上的颜色,就称为纹理采样。

二维纹理坐标所处的空间也被称为 ST空间

OpenGL 相关

OpenGL

Open Graphics Library开源图形库,Java 版所使用的图形函数库。

GLSL

(Open)GL Shader LanguageOpenGL着色语言,顾名思义,它是 OpenGL 的着色器所使用的语言,语法类似 C 语言

  • 其它的图形库还有如 Vulkan ,它的着色器语言也是 GLSLDirectX ,它的着色器语言是 HLSL(High-Level Shader Language,高级着色语言)。
GLSL 类型

除了 前文 所提到的类型外,GLSL 还有新增了一些数据类型:

  • bool :布尔值,可以是 true (1) 或 false (0)。
    • C 可以使用 stdbool.h 引入这个类型。
  • vec[N] :浮点向量,N 是属于区间 [2, 4] 的整数,表示该向量的维度。
    • ivec[N] 为整数向量,bvec[N] 为布尔值向量。
    • 例:vec3 ivec4
    • OpenGLGLSL 中,一个 vec4 类型可以被看做一个 float[4] 类型,但是需要注意:我们声明 float[] 类型的变量时,本质上是声明了一个指针,所以我们不能像 vec[N] 一样直接进行 向量四则运算
    • 我们可以使用 xyzw / rgba / stpq 来访问向量中特定的分量。
  • mat[N] mat[N]x[M] :浮点矩阵,NM 可以为 [2, 4] 的整数,表示该矩阵的大小。
    • mat[N] 表示 N * N 大小的矩阵,mat[N]x[M] 表示 N * M 大小的矩阵。
    • 例:mat3mat2x4
    • 假设我们现在有一个矩阵 mat3 M 我们可以使用 M[1][2] 来访问对应位置上的量。
  • sampler[N]D :样本,可以通过纹理采样函数来获取样本的信息,N可以为 [1, 3] ,表示该样本的维度。
    • samplerCube :六面包围盒式的样本。
    • 例:sampler2D
  • 此外,除了 auto(默认)和 const ,GLSL无法使用其他修饰符。
GLSL 函数

这里列出了一些常用的 GLSL 函数:

  • texture(sampler[N]D texture, vec[N] texcoord) :纹理采样函数
    1. sampler[N]D texture :与函数维度相等的样本,通常是 纹理
    2. vec[N] texcoord :与函数维度相等的向量,通常是 纹理坐标
      • N 应该一致。
      • 旧的 GLSL 还有一个 texture[N]D() 的函数,在新版本中已弃用。
  • dot(vec[N] a, vec[N] b)点乘
  • cross(vec[N] a, vec[N] b)叉乘
  • normalize(vec[N] a)归一化
  • smoothstep(float a, float b, float x),将 x 从 [a, b] 平滑地映射到 [0, 1]。

贴图相关

灰度图

仅有一个 颜色通道 的图片。

深度图高度图都是灰度图的一种

阴影贴图

Shadow Map,是深度图的一种,其运作原理大致如下:

  1. 光源视角绘制深度图并从其方向上投射到玩家视角作为距光源的最近距离
    • 这里所说的最近距离是指从光源出发,沿该点与光源连线上最近可以遇到的物体。
  2. 将其与玩家视角里每个像素实际到光源的距离做比较;
  3. 如果实际距离比最近距离更大,就是阴影。
    • 由于其算法特性,阴影精度与阴影贴图大小直接挂钩,同时会大幅影响性能
法线贴图

Normal Map,偏移物体表面的朝向,这样就可以影响每个纹理像素的光照强度,从而产生额外的表面细节。

  • 在计算机渲染中,我们通常使用法线信息与光源方向做 点乘 dot(lightDir, Normal) 来获得该像素被光源照亮的程度,法线贴图在此时的作用就是偏移了 Normal 这个量。所以实际上法线并没有真正偏移表面,而只是让该纹理像素的信息被改写。

渲染技术相关

POM

Parallax Occlusion Mapping,即视差遮蔽映射,简称视差

  • 和法线相似,视差贴图通过偏移表面的采样坐标,让玩家从不同角度感觉到表面上某些纹理被其他纹理遮挡,从而创造凹凸的观感,这也是其名字中映射的含义。
PBR

Physically-Based Rendering,即基于物理的渲染

  • 它是一种着色和渲染的方法,更准确地表现光线如何与材料性质相互作用。
  • 它有一些传统着色中没有考虑到的部分,如能量守恒光电效应等。
GI

Global Illumination,即全局光照。是直接光照和间接光照的集合。

直接光照

Direct Lighting,直接来自光源的光照。在 OptiFine 光影 中,直接光照的光源有且仅有太阳和月亮。

  • 更准确地说是太阳和月亮的方向
  • 在计算机图形学中,我们把可以投射阴影贴图的光源称为直接光源。

Iris 提供了一个独占特性,让手持光源可以投射阴影贴图,因此手持光源也可以算作一个直接光源。

间接光照

Indirect Lighting,光照经过物体内的散射最终离开物体,并打在周围其他表面上形成的照明。

AO

Ambient Occlusion,即环境光遮蔽,也称间接光吸收。由于性能问题,很多游戏中通常使用了各种欺诈和近似来模拟间接光照。为了让本应或者似乎应该为暗处的地方暗下去(通常是夹角)而产生的技术。

  • 绘制在 着色贴图 上的 AO 被称为 纹理环境光遮蔽(Material AO)或 材质环境光遮蔽(Texture AO)。
SSS

此简写包含以下两种概念

次表面散射

Sub-surface Scattering,模拟光线进入物体在其内部经过多次散射后射出的效果。

  • 散射是漫反射、镜面反射、次表面散射的集合。
  • 折射是散射的一个特解
屏幕空间阴影

Screen-space Shadow,由于阴影贴图的精度不足,容易在物体与地面接触的边缘产生锯齿和偏移。屏幕空间阴影就是用于这些地方来补足阴影的效果,因此也称为接触阴影(Contact Shadow)。

焦散

经过一次或数次散射后,经由漫反射表面反射最终到达观察者视角的光线,可以称之为焦散。
—— Tahnass

通俗来说,焦散可以理解为经由曲面反射和折射所聚焦的光线打到表面上而成的局部更亮的现象。

抗锯齿/升采样技术相关

DLSS

英伟达开发的一种升采样技术。通过降低分辨率并调用其张量核心(Tensor Core)来猜测原始分辨率下该处像素的内容。

  • 在 2.0 以前,DLSS 主要是靠已有画面内容来“猜”剩下的场景应该是何样
  • 自 2.0 开始,DLSS 主要是根据场景运动信息和历史帧来判断剩下的场景是何样,其计算方法从单一的空间域上升到了时空域,不再依赖于针对单个游戏的训练,产生的效果也比 1.0 好得多。
DLAA

原始分辨率下进行 DLSS 来平滑边缘的抗锯齿方法。

FSR

AMD 开发的一种升采样技术。相比较 DLSS 来说更为常规,但效果要比其他传统升采样方法好。

XeSS

英特尔开发的一种升采样技术。在其他平台上和其本家含有特定核心的平台上所使用的算法有所区别,因而在其本家平台上能够获得更好的效果。