kizumi_header_banner_img

不自由であることを誇れるだろうか

文章导读

计算机图形学学习笔记


avatar
Misaya2314 2026年2月18日 12

光栅化(lecture5-6)

lecture5-6 光栅化

卷积:

用一个小函数(卷积核)去扫描另一个函数,并在每个位置做加权求和,从而提取结构信息。

卷积的核心意义是:

提取局部结构信息

空间域的卷积=频域的乘积

我们通过傅里叶变化将空间域转换为频域

image.png

反走样(anti-aliasing)

也就是抗锯齿,降低图形边缘锐度。通常的方法是将图像模糊后再进行采样。

对应的频域上来说,就是使用低通滤波,去除高频信息。防止波纹重叠。

目前常见的抗锯齿方法有:

多重采样抗锯齿 MASS(MultiSampling Anti-Aliasing)

  • 一个像素多个子采样点

并对图像的边缘处加大采样

快速近似抗锯齿 ****FXAA(fast approximate antialiasing

模糊像素边缘 来减少锯齿

时间抗锯齿 TAA(Temporal Anti-Aliasing

每帧抖动采样位置

跨帧累积

重投影历史帧

深度缓存(Z-Buffer)

它解决的问题是:

谁应该被看到?

渲染时,每个像素不仅存:

颜色值

还存:

深度值(离摄像机多远)

渲染流程:

  1. 初始化深度缓冲为“最大值”(无限远)
  2. 每画一个像素:
    • 计算它的深度
    • 和当前深度缓冲里的值比较
  3. 如果更近:
    • 更新颜色
    • 更新深度
  4. 如果更远:
    • 丢弃

当在视图中看见两个面闪烁的时候

  • 深度值接近
  • 精度不足
  • GPU 无法稳定判断谁在前

就会闪烁。这就是Z-Fighting

Lecture7-8 Shading(着色)

漫反射

  • I/r² 表示有多少光到达了ShadingPoint(因为光会随着传播距离而衰减)
  • Kd表示了该点颜色的反射率

如果Kd=0,那么该点完全没有反射光出去,该点吸收了所有光,那么该点表现为黑色

如果Kd=1,那么该点反射了所有光,那么该点表现为白色

如果用RGB三个通道表示Kd,那么Kd就是Color

  • Max(0,n·l)表示反射角度,nl都是单位向量,n·l = cosθ,当入射光从表面下面照入,θ>90°,cos<0,这种情况没有意义,因为我们只考虑反射光,不考虑折射等光线,所以需要和0比,取最大值

镜面反射

高光的方向 -> 越光滑 越趋于镜面反射的方向

观察的方向越接近镜面反射的方向 越能看到高光

Blinn-Phong 改进模型 这是目前实时渲染(如 OpenGL、DirectX 和早期 UE 引擎)中默认采用的方案。它不再计算复杂的反射向量,而是引入了半程向量(Halfway Vector)

图形管线/实时渲染管线

  • 顶点处理

将三维空间的点投影在平面上

  • 三角形处理

将这些点连接形成三角形

  • 光栅化

将三角形离散成为屏幕上的Fragment(未经处理的像素)

  • 着色

给像素上色

  • 后处理

深度缓冲-处理遮挡关系,MSAA等抗锯齿

(以上操作都在硬件中处理好了,也就是gpu工作流程)

Shader

现代GPU中,这套渲染管线某些部分是可编程的,可以由开发者去定义顶点/像素如何着色

也就是用代码控制如何着色

这部分代码就叫Shader

Shader指定的是每一个像素/顶点如何着色,所以不能也不用去指定某一个像素如何着色

如果写的是顶点操作,这个shader就叫做VertexShader(顶点着色器)

如果写的是像素操作,这个shader就叫做FragmentShader(片段/片元着色器)/PixelShader(像素着色器)

标准实时渲染管线

模型变换(Model) → 视图变换(View) → 投影变换(Projection) → 裁剪(Clipping) → 光栅化(Rasterization) → 片元着色(Fragment Shading) → 深度测试 / 混合

Lecture9 Shading — 纹理处理

环境光贴图

法线贴图

位移贴图

通过将数据存储到贴图中,我们就可以快速的着色而不需要更多性能消耗

Lecture10 -12 Geometry— 几何

隐式几何

隐式几何用来表达该几何点之间的关系

隐式表达的函数f(x,y,z)很难从函数看出函数形成的面是什么形状的

但可以轻松的知道某一点是否在这个平面上,或物体内外

image.png

显式表达

给定:点的空间坐标uv,遍历所有点就可以在空间中画出该物体

用平面中的uv去映射到空间中,表示空间上的面

优点就是可以看出函数形成的面是什么形状的

但无法轻松的知道某一点是否在这个平面上

image.png

两种表达各有各的用途,没有好坏之分,根据需要选择

例如,隐式表达中有一个概念Distance Function(距离函数)

在传统的显式网格建模中,电脑只知道“表面在哪里”。但在 SDF 的世界里,空间中的任意一个点 ,都可以输入到一个数学函数 f(p) 中。这个函数会返回一个具体的数值,这个数值代表:当前这个点,距离最近的物体表面有多远。 之所以叫“有符号 (Signed)”,是因为它不仅告诉你距离,还通过正负号告诉你位置关系: • f(p) > 0:点在物体外部。数值越大,离物体越远。 • f(p) < 0:点在物体内部。数值越小,陷得越深。 • f(p) = 0:点正好在物体的表面上。

例如比较现代的lumen光照技术就是用到了距离函数。

分形

指的是图形和自己相同或相同与自己的一部分

image.png

贝塞尔曲线(Bézier Curve)

运用

字体渲染 (Font Rendering)

你现在看到的屏幕文字,大多是由贝塞尔曲线定义的。TrueType 字体使用二阶贝塞尔曲线,而 PostScript(如 OpenType)则使用三阶贝塞尔曲线。这保证了文字在无限放大时依然平滑,没有锯齿。

路径与矢量绘图 (Vector Graphics)

在 Photoshop、Illustrator 或 SVG 中,“钢笔工具”画出的路径本质上就是三次贝塞尔样条

通过连接多段贝塞尔曲线,并保持连接处的导数连续(G0, G1, G2 连续性),可以勾勒出任何复杂的平面形状。

动画曲线 (Animation Curves/Easing Functions)

在游戏引擎(如 Unreal Engine 或 Unity)中,物体的位移、缩放随时间的变化通常由贝塞尔曲线控制。

通过调整控制点,可以轻松实现“淡入淡出”(Ease-in/Ease-out)效果,让动画看起来更符合物理规律,而不是机械的匀速运动。

3D 建模与曲面 (Bézier Surfaces)

将贝塞尔曲线延伸到二维参数空间,就形成了贝塞尔曲面。这在早期的 3D 建模中非常流行,用于构建汽车外壳等流线型零件。

曲面细分

catmull-clark Subdivision

核心原理:通过在网格中插入面心、边心并更新原顶点位置,将粗糙多面体递归平滑化。

数学收敛:多次迭代后会收敛至二阶连续的 B 样条曲面

优势:支持任意拓扑结构(不仅限于三角形),广泛用于影视动画建模。

曲面简化

核心操作边坍缩(Edge Collapse),即通过合并顶点减少面片数。

度量标准二次代价误差(Quadric Error Metrics)。通过计算顶点到周围所有平面的距离平方和求解能使几何形状改变最小的最优坍缩位置

主要应用:游戏中的 LOD(细节层级) 技术,平衡渲染性能与视觉效果。

Lecture 13-16 光线追踪

Shadow mapping

Shadow Mapping(阴影贴图)是一种基于深度缓冲的阴影生成技术

image.png

Shadow Mapping 本质是:

在光源空间做一次 Z-buffer 可见性测试

它其实是一个 visibility test(可见性判断)问题

换句话说:

Z-buffer 是从摄像机视角判断可见性

Shadow Map 是从光源视角判断可见性

也就是说,阴影的生成方式就是判断光源获取到的深度和摄像机获取到的深度是否相等。若不相等,则这一块是阴影。

Ray Tracing

Ray Tracing(光线追踪)是一种通过模拟光线传播路径来计算像素颜色的渲染方法。

检测光线是否与面相交的方法。对于隐性表示,就使用光线函数与物体表示函数的解。交点必定过两个函数。

对于显式表示,则求三角面与光线的交点,也就是分解为:

1.光线是否与三角形所在平面相交

2.交点是否在三角形内部

bounding volume包围盒(AABB)

AABB(Axis-Aligned Bounding Box,轴对齐包围盒)是计算机图形学、游戏开发和物理引擎中极常用的一种碰撞检测技术。简单来说,它就是用一个所有边或面都严格平行于坐标轴(X轴、Y轴、Z轴)的矩形或六面体,将复杂的几何模型包围起来。通过判断两个包围盒在各个坐标轴上的投影是否同时发生重叠,就能极其快速、高效地判断出两个物体是否可能发生了碰撞。

image.png

用一个包围盒包住物体,检测光线相交时,先检测是否与包围盒相交。这样就能提升性能。 目前我们使用**BVH(Bounding Volume Hierarchy)**来切分包围盒

BVH(Bounding Volume Hierarchy)

定义:一种使用“层级包围体”来组织几何体的空间加速结构。

核心思想:

用一个大的包围体包住所有物体

递归分裂,形成树结构

本质是:

用空间层级结构减少求交测试次数。

       Root AABB
        /      \\\\
   Node AABB   Node AABB
    /     \\\\       /    \\\\
 Leaf    Leaf   Leaf   Leaf

Basic radiometry(辐射度量学)

功率 → 强度 → 辐照度 → 辐射率


1️⃣ Radiant Flux(辐射通量)

符号:Φ

单位:W(瓦特)

定义:

单位时间内发出的总能量。

公式:

Φ = dQ / dt

含义:

  • 光源一秒钟发出多少能量
  • 不考虑方向
  • 不考虑面积

理解:

“总亮度”


2️⃣ Radiant Intensity(辐射强度)

符号:I

单位:W / sr

定义:

单位立体角内的功率。

公式:

I = dΦ / dω

其中:

  • ω = 立体角(steradian)

含义:

  • 光向某个方向的强度
  • 开始引入“方向”概念

3️⃣ Irradiance(辐照度)

符号:E

单位:W / m²

定义:

单位面积接收到的光能量。

公式:

E = dΦ / dA

含义:

  • 表面被照亮的程度
  • 不区分方向

重要特性:

如果光与表面夹角为 θ:

E ∝ cosθ

这就是:

Lambert 余弦定律


4️⃣ Radiance(辐射率)【最重要】

符号:L

单位:W / (m² · sr)

定义:

单位面积、单位立体角内的光能量。

公式:

L = d²Φ / (dA · dω · cosθ)

这是渲染方程的核心变量。

理解:

Radiance 同时考虑:

  • 面积
  • 方向
  • 角度

它是:

描述光传播最完整的量。

BRDF(Bidirectional Reflectance Distribution Function,双向反射分布函数)

BSDF = BRDF +BTDF(反射)

BRDF 是一个描述表面如何将来自某个方向的光反射到另一个方向的函数,是渲染方程的核心组成部分,也是现代 PBR 材质模型的物理基础。

Radiance ↓ 入射光 L_i ↓ BRDF 决定反射比例 ↓ 出射光 L_o

image.png

全局光照

全局光照就是计算光线多次反射后的光照效果

Gemini 说

全局光照(Global Illumination,简称 GI是计算机图形学中的一个核心概念,指的是在模拟光线在三维场景中传播时,不仅考虑光源直接照射到物体表面的光(直接光照),还要考虑光线在物体表面之间多次反射、折射和散射所产生的光(间接光照)。

简单来说:全局光照 = 直接光照 (Direct Illumination) + 间接光照 (Indirect Illumination)。

游戏引擎中的全局光照技术实现

在离线渲染(如电影特效)中,通常使用路径追踪(Path Tracing)通过大量发射光线来暴力求解 GI。但在游戏开发等实时渲染领域,由于性能限制,技术美术(TA)和图形程序员演化出了多种实时或半实时 GI 的解决方案:

  • 传统烘焙光照(Baked Lighting / Lightmaps):在游戏打包前,离线计算好静态场景的间接光照,并把结果存成纹理(光照贴图)贴在模型上。
    • 优点:运行时性能开销极小。
    • 缺点:只适用于静态物体和静态光源,场景一旦发生动态变化就失效了。
  • 光照探针与辐照度体积(Light Probes / Irradiance Volumes):在场景中放置一系列探针,预计算并存储空间中特定点的光照信息(通常用球谐函数 Spherical Harmonics 编码),动态物体经过时从最近的探针中插值获取间接光。
  • 屏幕空间全局光照(SSGI):利用屏幕空间深度和颜色缓冲,模拟屏幕内可见像素之间的光线弹射。
    • 缺点:只能处理屏幕内可见的信息,屏幕外发光物体对屏幕内的影响无法计算。
  • 基于体素的 GI(VXGI):将场景体素化(Voxelize),并在体素结构中追踪光线锥来计算间接光。
  • 硬件光线追踪(Hardware Ray Tracing GI):依赖于现代显卡(如 RTX 系列)的 RT Core,在硬件层面加速光线的求交计算,以实现实时的间接光弹射。
  • 基于 SDF(有向距离场)的 GI:现代引擎中最前沿的方案之一。例如 Unreal Engine 5 的 Lumen 系统的软件追踪模式,就是通过场景的 Mesh SDF 和 Global SDF 结构来加速光线步进(Ray Marching),结合屏幕空间探针来实现全动态的实时全局光照。

路径追踪(Path Tracing)

Path Tracing(路径追踪)是一种基于蒙特卡洛积分的全局光照算法,通过随机追踪光线路径来近似求解渲染方程。

image.png

Path Tracing 工作流程

核心思想:

从摄像机发射光线,随机弹射,直到光线终止。

流程如下:


Step 1:从像素发射一条主光线

摄像机 → 场景

如果打到物体:


Step 2:计算直接光

向光源发射 shadow ray 判断是否可见


Step 3:随机生成反射方向

根据材质的 BRDF:

  • 漫反射 → 半球随机采样
  • 镜面 → 反射方向
  • 折射 → 斯涅尔定律

Step 4:递归追踪

新方向继续发射光线

不断累积:

贡献=BRDF×入射光×cosθ贡献 = BRDF × 入射光 × cosθ

贡献=BRDF×入射光×cosθ


Step 5:俄罗斯轮盘赌终止路径

为了避免无限递归:

  • 以概率 p 终止
  • 保持期望不变

为什么会有噪点

因为:

它是随机采样积分

样本数低时:

  • 方差高
  • 噪点明显

样本数越高:

  • 收敛到真实解
  • 噪点减少

这就是你看到:

  • Blender Cycles 渲染一开始满屏噪点
  • 慢慢变干净

菲涅尔项

表示光线的折射性质

想象你站在一个平静的湖边:

  • 俯视脚下: 你能清晰地看到水底的石头(大部分光线折射进入了水中)。
  • 远眺湖面: 你看到的几乎全是远山和天空的倒影(大部分光线被反射了回来)。

这就是菲涅尔效应。几乎所有电介质(绝缘体,如水、玻璃、塑料)和金属都遵循这一规律。

1. 区分材质质感 如果没有菲涅尔项,物体在所有角度的反射强度都一样,看起来会像一张扁平的贴图,缺乏“体积感”和“高级感”。 2. 边缘高光(Rim Lighting) 在渲染球体或复杂模型时,由于菲涅尔效应,物体的边缘(即入射角接近 90° 的地方)反射会显著增强。这能自然地勾勒出物体的轮廓。 3. 金属与非金属的区别非金属: 只有在边缘处才有强反射 • 金属: 在所有角度都有较强反射,且带有颜色(例如黄金的是淡黄色)。

image.png

Anisotropy(各项异性)

各向异性 = 性质随“方向”改变

各向同性 = 性质在所有方向相同

举例:

  • 空气 → 各向同性(任何方向都一样)
  • 木头 → 各向异性(顺纹理方向强度不同)

1️⃣ 普通(各向同性)材质

比如普通塑料:

  • 高光是圆形
  • 无论物体怎么旋转,高光形状一样

只依赖法线,不依赖切线方向。


2️⃣ 各向异性材质

典型例子:

  • 拉丝金属
  • CD 光盘
  • 丝绸
  • 头发

特征:

高光是拉长的椭圆

它依赖:

  • 法线
  • 切线方向
  • 表面微结构方向

BSSRDF(双向表面散射反射分布函数)

BRDF → 局部反射 BSDF → 反射 + 折射 BSSRDF → 空间散射

为什么需要 BSSRDF?

先回顾:

1️⃣ BRDF 的假设

BRDF 假设:

光在一个点入射

在同一个点出射

数学形式:

fr(ωi,ωo)f_r(\omega_i, \omega_o)

fr(ωi,ωo)

只和方向有关。

这叫:

局部反射模型(Local Model)


2️⃣ 现实世界的问题

有些材质不是“表面反射”:

  • 皮肤
  • 蜡烛
  • 牛奶
  • 大理石
  • 玉石

光会:

  1. 进入表面
  2. 在内部散射
  3. 从别的地方出来

也就是说:

入射点 ≠ 出射点

BRDF 无法描述这种现象。


三、BSSRDF 解决什么问题?

BSSRDF 描述的是:

光从一个位置进入

在另一个位置离开

数学形式:

S(xi,ωi,xo,ωo)S(x_i, \omega_i, x_o, \omega_o)

S(xi,ωi,xo,ωo)

它依赖:

  • 入射点位置
  • 入射方向
  • 出射点位置
  • 出射方向

比 BRDF 多了两个空间维度。

在 Unreal Engine 5 中:

有:

Subsurface Profile

但它不是完整 BSSRDF,而是实时近似。

Lecture 21 -22 动画

质点弹簧系统

常用于布料,毛发模拟

粒子系统

例如ue Niagara系统。通过对粒子施加各种量来模拟粒子效果

FK(正向动力学)IK(反向动力学)

把手理解为一个骨架,已知手臂位置推测出手掌位置即为FK(正向动力学)

而已知手掌位置推测手臂位置即为IK(反向运动学)

Rigging(绑定)

Rigging(绑定)是指:

为模型建立“可驱动的控制结构”,使其能够被动画系统操控。

完整 Rigging 一般包含:

  1. 建立骨骼(Skeleton)
  2. 设定层级结构
  3. 添加控制器(Control Rig)
  4. 约束系统(IK / FK)
  5. 蒙皮(Skinning)
  6. 权重调整(Weight Painting)

感谢您的支持


评论(0)

查看评论列表

暂无评论


发表评论