计算机图形学:【Games101】学习笔记04——着色(光照与基本着色模型,着色频率、图形管线、纹理映射)

计算机图形学:【Games101】学习笔记04------着色(光照与基本着色模型,着色频率、图形管线、纹理映射)

  • 前言
  • 一、着色(光照与基本着色模型)
    • [1.1 Visibility 处理:解决物体遮挡问题(Visibility / occlusion)](#1.1 Visibility 处理:解决物体遮挡问题(Visibility / occlusion))
      • [1.1.1 画家算法(Painter's Algorithm)](#1.1.1 画家算法(Painter’s Algorithm))
      • [1.1.2 Z 缓冲算法(Z-Buffer)](#1.1.2 Z 缓冲算法(Z-Buffer))
    • [1.2 着色(Shading)基础:给物体添加光影](#1.2 着色(Shading)基础:给物体添加光影)
      • [1.2.1 着色的基本概念](#1.2.1 着色的基本概念)
      • [1.2.2 简单的着色模型(Blinn-Phong 反射模型)](#1.2.2 简单的着色模型(Blinn-Phong 反射模型))
  • 二、着色(着色频率、图形管线、纹理映射)
    • [2.1 Blinn-Phong 反射模型进阶](#2.1 Blinn-Phong 反射模型进阶)
      • [2.1.1 漫反射项(Lambertian Term)](#2.1.1 漫反射项(Lambertian Term))
      • [2.1.2 高光项(Specular Term)](#2.1.2 高光项(Specular Term))
      • [2.1.3 环境光项(Ambient Term)](#2.1.3 环境光项(Ambient Term))
      • [2.1.4 完整Blinn-Phong 反射模型(Blinn-Phong Reflection Model)](#2.1.4 完整Blinn-Phong 反射模型(Blinn-Phong Reflection Model))
    • [2.2 着色频率(Shading Frequencies)](#2.2 着色频率(Shading Frequencies))
      • [2.2.1 平面着色(Shade each triangle (flat shading))](#2.2.1 平面着色(Shade each triangle (flat shading)))
      • [2.2.2 Gouraud着色(Shade each vertex (Gouraud shading))](#2.2.2 Gouraud着色(Shade each vertex (Gouraud shading)))
      • [2.2.3 Phong 着色(Shade each pixel (Phong shading))](#2.2.3 Phong 着色(Shade each pixel (Phong shading)))
      • [2.2.4 三种着色方法的对比](#2.2.4 三种着色方法的对比)
      • [2.2.5 补充:定义每个顶点的法向量(Defining Per-Vertex Normal Vectors)](#2.2.5 补充:定义每个顶点的法向量(Defining Per-Vertex Normal Vectors))
    • [2.3 实时渲染管线(Graphics Pipeline)](#2.3 实时渲染管线(Graphics Pipeline))
      • [2.3.1 管线各核心阶段](#2.3.1 管线各核心阶段)
      • [2.3.2 着色器(Shader Programs)](#2.3.2 着色器(Shader Programs))
      • [2.3.3 GPU 架构与并行计算(Graphics Pipeline Implementation: GPUs)](#2.3.3 GPU 架构与并行计算(Graphics Pipeline Implementation: GPUs))
    • [2.4 纹理映射(Texture Mapping)](#2.4 纹理映射(Texture Mapping))
  • 三、疑难点整理总结
  • 写在最后

前言

  • 🎮 GAMES101 是国内相当有名的图形学公开课。项目相关资源在:https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html
  • 本 📒笔记为 🖊️笔者在自学过程中整理的 🇨🇳中文版笔记,供各位 📖读者阅读 😼~
  • 计算机图形学中, visibility 处理与着色是实现真实渲染的核心环节。GAMES101 第 7 讲围绕 Z 缓冲算法、着色模型及图形管线展开,清晰拆解了从物体遮挡判断到表面光影呈现的关键技术,本文将梳理核心知识点与实践要点。

一、着色(光照与基本着色模型)

1.1 Visibility 处理:解决物体遮挡问题(Visibility / occlusion)

在 3D 场景渲染中,多个物体重叠时需确定哪些部分可见,这一问题的核心是遮挡判断。

1.1.1 画家算法(Painter's Algorithm)

  • 核心思路:模拟绘画逻辑,按深度从后往前绘制,用前景物体颜色覆盖后景物体。
  • 特点:需对所有三角形进行深度排序,时间复杂度为 O (n logn)(n 为三角形数量)。
  • 问题:存在明显缺陷,部分场景下无法确定深度顺序,导致遮挡判断失效。

1.1.2 Z 缓冲算法(Z-Buffer)

这是目前 GPU 硬件普遍采用的 visibility 解决方案,也是本讲重点。

  • 核心原理
    • 维护两个缓冲区:帧缓冲区(framebuffer)存储像素颜色,深度缓冲区(z-buffer)存储每个像素的当前最小 z 值。
    • 约定 z 值为正数,且 z 值越小表示物体越靠近相机,z 值越大表示物体越远。
  • 算法步骤
    • 初始化深度缓冲区所有值为无穷大(∞)。
    • 光栅化每个三角形时,遍历其覆盖的每个采样点(x, y, z)。
    • 若当前采样点的 z 值小于深度缓冲区中对应位置的 z 值,说明该点更靠近相机。
    • 更新帧缓冲区对应位置的颜色,并将深度缓冲区的 z 值更新为当前采样点的 z 值。
    • 若 z 值不小于缓冲区中的值,则该采样点被遮挡,不做任何操作。

  • 关键优势:
    • 时间复杂度为 O (n)(假设每个三角形覆盖的采样点数量固定),无需提前排序。
    • 不受物体绘制顺序影响,能处理复杂遮挡场景。
    • 硬件级实现,渲染效率极高,是现代图形学中最核心的 visibility 算法。

1.2 着色(Shading)基础:给物体添加光影

解决遮挡问题后,需通过着色让物体呈现材质质感与光影效果,本讲重点介绍 Blinn-Phong 反射模型。

1.2.1 着色的基本概念

1. 着色的定义

  • 词典定义:用平行线或色块对插图、图表进行暗化或上色的过程。
  • 课程定义:将材质属性应用于物体表面的过程,核心是计算特定点向相机反射的光强。

2. 着色的核心特性

  • 局部性:仅基于着色点的局部信息计算(观察者方向、表面法向量、光线方向等)。
  • 与阴影的区别:着色不包含阴影计算,仅处理物体表面自身的光影反射。

1.2.2 简单的着色模型(Blinn-Phong 反射模型)

Blinn-Phong 反射模型通过叠加三种光照效果,实现符合人眼感知的着色效果:

1.漫反射(Diffuse Reflection)

  • 光线照射到粗糙表面后,向各个方向均匀散射,物体颜色在所有视角下保持一致。
  • 遵循朗伯余弦定律( Lambert's cosine law ):单位面积接收的光能量与光线方向和表面法向量的夹角余弦成正比,即 cosθ = n・l(n 为单位法向量,l 为单位光线方向)。
  • 计算公式:Ld = kd × (I/r²) × max (0, n・l)
    • kd 为漫反射系数(决定物体基础颜色)。
    • I 为光源强度,r 为着色点到光源的距离。
    • max (0, n・l) 确保光线从物体正面照射时才计算贡献(避免负光强)。

2.高光反射(Specular Highlights)

  • 光线照射到光滑表面后,在特定方向形成明亮的高光区域,与观察角度相关。

3.环境光(Ambient Lighting)

  • 模拟场景中四处反射的间接光,避免未被直接光照的区域呈现纯黑色,提升画面整体亮度。

4.光线衰减(Light Falloff)

  • 点光源的光强会随距离增加而衰减,遵循平方反比定律,即光强与距离的平方成反比(I/r²)。
  • 这一特性确保远处物体看起来更暗,符合真实物理规律。

二、着色(着色频率、图形管线、纹理映射)

在计算机图形学中,着色(Shading)是实现真实感画面的核心技术之一。GAMES101 第八讲作为光照模型的进阶内容,不仅深入完善了 Blinn-Phong 反射模型,还系统讲解了着色频率、实时渲染管线、纹理映射等关键技术,这些内容共同构成了现代实时图形渲染的基础框架。本文将结合课程知识点,梳理核心概念与技术细节,帮助读者建立完整的渲染知识体系。

2.1 Blinn-Phong 反射模型进阶

上一讲我们初步了解了 Blinn-Phong 模型的核心思想,本讲进一步完善了模型细节,并明确了三个核心分量的数学表达与物理意义,最终形成完整的光照计算框架。

2.1.1 漫反射项(Lambertian Term)

漫反射的特点是光线照射到粗糙表面后,会向各个方向均匀散射,因此其亮度与观察方向无关,仅取决于入射光线与表面法向量的夹角。

  • 数学公式: L d = k d ⋅ ( I / r 2 ) ⋅ max ⁡ ( 0 , n ⋅ l ) L_d = k_d \cdot (I/r^2) \cdot \max(0, n \cdot l) Ld=kd⋅(I/r2)⋅max(0,n⋅l)
  • 各参数含义:
    • k d k_d kd:漫反射系数(取值 0-1),决定表面漫反射能力,通常与表面颜色相关;
    • I / r 2 I/r^2 I/r2:着色点接收的光能量,遵循平方衰减定律(光线强度随距离平方递减);
    • n ⋅ l n \cdot l n⋅l:法向量 n 与入射光线方向 l 的点积,反映光线照射角度(垂直照射时效果最强);
    • max ⁡ ( 0 , ⋅ ) \max(0, \cdot) max(0,⋅):避免光线从背面照射时产生负亮度。
  • 示例:光线强度随距离平方递减。

2.1.2 高光项(Specular Term)

高光项用于模拟光滑表面的镜面反射效果,亮度集中在反射方向附近,且强烈依赖观察方向。Blinn-Phong 模型通过 "半向量" 简化了传统 Phong 模型的计算,效率更高。

  • 核心思想:引入半向量 h(入射光线方向 l 与观察方向 v 的角平分线),当 h 与法向量 n 接近时,高光最强;
  • 数学公式: L s = k s ⋅ ( I / r 2 ) ⋅ max ⁡ ( 0 , n ⋅ h ) p L_s = k_s \cdot (I/r^2) \cdot \max(0, n \cdot h)^p Ls=ks⋅(I/r2)⋅max(0,n⋅h)p
  • 各参数含义:
    • k s k_s ks:高光系数(取值 0-1),决定表面镜面反射能力;
    • p p p:高光指数,控制高光区域的大小(p 越大,高光越集中,表面越显光滑);
    • n ⋅ h n \cdot h n⋅h:法向量与半向量的点积,反映高光强度。
    • max ⁡ ( 0 , ⋅ ) \max(0, \cdot) max(0,⋅):避免光线从背面照射时产生负亮度。
  • 示例:p 越大,高光越集中,表面越显光滑


2.1.3 环境光项(Ambient Term)

现实场景中,物体除了直接接收光源照射,还会受到环境中多次反射的间接光照。环境光项是一种简化模拟,用于填补直接光照产生的阴影,避免画面出现纯黑区域。

  • 数学公式: L a = k a ⋅ I a L_a = k_a \cdot I_a La=ka⋅Ia
  • 各参数含义:
    • k a k_a ka:环境光系数(取值 0-1),决定表面接收环境光的能力;
    • I a I_a Ia:环境光强度,为全局常量。
  • 注意:环境光项是近似模拟(并非物理真实),仅用于提升画面合理性。

2.1.4 完整Blinn-Phong 反射模型(Blinn-Phong Reflection Model)

Blinn-Phong 模型的最终亮度为三个分量之和:

L = L a + L d + L s = k a I a + k d ( I / r 2 ) max ⁡ ( 0 , n ⋅ l ) + k s ( I / r 2 ) max ⁡ ( 0 , n ⋅ h ) p L = L_a + L_d + L_s = k_a I_a + k_d (I/r^2) \max(0, n \cdot l) + k_s (I/r^2) \max(0, n \cdot h)^p L=La+Ld+Ls=kaIa+kd(I/r2)max(0,n⋅l)+ks(I/r2)max(0,n⋅h)p

2.2 着色频率(Shading Frequencies)

着色频率指 "在哪个层级计算光照",不同频率直接影响画面光滑度与计算效率,常见的有三种方式。

2.2.1 平面着色(Shade each triangle (flat shading))

  • 着色层级:每个三角形面(Face)
  • 核心逻辑:为每个三角形分配一个法向量(面法向量),整个三角形使用同一光照计算结果;
  • 优点:计算效率极高(每个三角形仅需一次光照计算);
  • 缺点:画面呈现明显的 "三角形分割感",无法表现光滑表面(如球体、圆柱体)。
  • 示例:

2.2.2 Gouraud着色(Shade each vertex (Gouraud shading))

  • 着色层级:每个顶点(Vertex)
  • 核心逻辑:
    • 为每个顶点计算法向量(可通过周围面法向量平均得到);
    • 在顶点处执行光照计算,得到顶点颜色;
    • 三角形内部的像素颜色通过顶点颜色插值得到;
  • 优点:效率中等,画面比平面着色光滑;
  • 缺点:高光效果可能失真(插值过程会模糊高光细节)。
  • 示例:

2.2.3 Phong 着色(Shade each pixel (Phong shading))

  • 着色层级:每个像素(Pixel)
  • 核心逻辑:
    • 顶点法向量通过 barycentric 插值得到三角形内部每个像素的法向量(需归一化);
    • 对每个像素执行完整的 Blinn-Phong 模型计算;
  • 注意:此处的 "Phong 着色" 是着色频率,并非上一讲的 "Phong 反射模型";
  • 优点:画面最光滑,高光效果精准,是实时渲染的主流选择;
  • 缺点:计算量最大(每个像素都需执行光照计算)。
  • 示例:

2.2.4 三种着色方法的对比

着色方式 着色层级 画面效果 计算效率
平面着色 三角形面 粗糙,有分割感 最高
Gouraud 着色 顶点 较光滑,高光可能失真 中等
Phong 着色 像素 最光滑,高光精准 最低

2.2.5 补充:定义每个顶点的法向量(Defining Per-Vertex Normal Vectors)

顶点法向量(Per-Vertex Normal Vectors)是 3D 模型每个顶点对应的单位向量,用于表征顶点所在光滑表面的真实朝向,是 Gouraud 着色(顶点着色)和 Phong 着色(像素着色)的关键基础 ------ 直接影响光照计算的准确性和表面着色的光滑度,区别于平面着色中单一的 "面法向量"。

  1. 优先方案:从底层几何直接获取
  • 适用场景:模型有明确的原始几何定义(如数学公式描述的球体、参数曲面);
  • 核心逻辑:通过几何公式计算顶点的真实法向量,无需近似;
  • 示例:球体的顶点法向量方向为 "从球心指向顶点",天然垂直于球体表面。
  1. 近似方案:通过周围面法向量平均计算
  • 当模型为离散三角形拼接而成(无原始光滑几何信息,如 3D 扫描模型、手工多边形模型)时,采用此主流方案,步骤如下:确定相邻三角形:找到所有包含目标顶点的三角形(即顶点所属的全部三角形);计算面法向量:对每个相邻三角形,通过其三个顶点的位置向量叉乘,得到该三角形的面法向量(N_i),并归一化(确保为单位向量);向量求和与归一化:将所有相邻三角形的面法向量求和,再对求和结果做归一化处理,最终得到顶点法向量。

2.3 实时渲染管线(Graphics Pipeline)

渲染管线是将 3D 场景转换为 2D 图像的流程,现代 GPU 会并行执行该流程的各个阶段,确保实时性(30-60 FPS,VR 场景要求更高)。

2.3.1 管线各核心阶段

1️⃣ 应用阶段(Application)

  • 运行在 CPU 上,负责场景准备工作:
    • 定义 3D 模型的顶点数据(位置、法向量、纹理坐标等);
    • 设置光源参数、相机位置;
    • 输出顶点流(Vertex Stream)到下一阶段。

2️⃣ 顶点处理(Vertex Processing)

  • 对每个顶点执行变换操作:
    • 模型变换(Model):将顶点从模型空间转换到世界空间;
    • 视图变换(View):将世界空间顶点转换到相机空间;
    • 投影变换(Projection):将相机空间顶点转换到裁剪空间;
    • 最终输出屏幕空间的顶点位置。

3️⃣ 三角形处理(Triangle Processing)

  • 将顶点流组装为三角形(每个三角形由 3 个顶点组成);
  • 执行裁剪操作(剔除屏幕外的三角形);
  • 输出三角形流(Triangle Stream)。

4️⃣ 光栅化(Rasterization)

  • 核心任务:将三角形转换为像素(片段 Fragment);
  • 采样三角形覆盖的像素位置,生成片段流(Fragment Stream);
  • 每个片段包含像素位置、插值后的法向量、纹理坐标等信息。

5️⃣ 片段处理(Fragment Processing)

  • 对每个片段执行着色计算:
    • 执行片段着色器(Shader):结合 Blinn-Phong 模型、纹理映射计算片段颜色;
    • 执行深度测试(Z-Buffer):剔除被遮挡的片段;
  • 输出着色后的片段(Shaded Fragments)。



6️⃣ 帧缓冲操作(Framebuffer Operations)

  • 合并片段颜色(如透明度混合);
  • 将最终颜色写入帧缓冲(Framebuffer);
  • 输出图像到显示器。

2.3.2 着色器(Shader Programs)

着色器是运行在 GPU 上的程序,用于自定义管线中的顶点处理和片段处理阶段,常见的有:

  • 顶点着色器(Vertex Shader):处理顶点变换、传递插值数据(如纹理坐标、法向量);
  • 片段着色器(Fragment Shader):计算片段颜色,是实现光照、纹理的核心。

示例:GLSL 漫反射片段着色器

cpp 复制代码
uniform sampler2D myTexture; // 纹理采样器
uniform vec3 lightDir;       // 光源方向(全局参数)
varying vec2 uv;             // 插值后的纹理坐标
varying vec3 norm;           // 插值后的法向量

void main() {
    vec3 kd = texture2D(myTexture, uv).rgb; // 从纹理获取材料颜色
    float diffuse = clamp(dot(-lightDir, norm), 0.0, 1.0); // Lambert漫反射模型计算
    gl_FragColor = vec4(kd * diffuse, 1.0); // 输出片段颜色
}
  • 着色器函数每个片段执行一次。
  • 输出当前片段对应屏幕采样位置处的表面颜色。
  • 该着色器执行纹理采样,获取该位置处表面的材质颜色,随后执行漫反射光照计算。

示例:蜗牛着色器程序(Snail Shader Program)。

目标是实时呈现高度复杂的3D场景。但存在以下挑战:

  • 一个场景中包含数十万个到数百万个三角形;
  • 复杂的顶点和片段着色器计算;
  • 高分辨率(200-400万像素 + 超采样);
  • 每秒30-60帧(虚拟现实场景下甚至更高);

2.3.3 GPU 架构与并行计算(Graphics Pipeline Implementation: GPUs)

GPU 是异构多核处理器,专为并行执行管线阶段设计:

  • 包含大量 SIMD(单指令多数据)核心,可同时处理多个顶点 / 片段;
  • 支持纹理缓存、Z-Buffer 等硬件加速单元;
  • 现代 GPU 性能可达 2-4 TFLOPs,能高效处理百万级三角形场景。

2.4 纹理映射(Texture Mapping)

纹理映射是给 3D 模型表面添加细节的核心技术,通过将 2D 纹理图像 "贴" 到 3D 表面,实现木纹、布料、图案等复杂外观,而无需增加模型顶点数量。

核心原理:

  • 3D 表面的每个顶点都分配一个 2D 纹理坐标(u, v),取值范围通常为 [0, 1];
  • 纹理坐标定义了顶点在 2D 纹理图像中的位置;
  • 三角形内部像素的纹理坐标通过 barycentric 插值得到;
  • 渲染时,根据像素的纹理坐标从纹理图像中采样颜色,代入 Blinn-Phong 模型计算最终亮度;

纹理空间与映射关系(Surfaces are 2D)

  • 曲面存在于三维世界空间中,每个3D表面点在2D图像(纹理)中也有对应的位置。
  • 纹理空间:2D 纹理图像的坐标系统(u 轴水平,v 轴垂直);
  • 映射流程:3D 世界空间顶点 → 纹理坐标(u, v)→ 纹理图像采样 → 表面颜色。

纹理复用(Tiling,Textures can be used multiple times!)

  • 纹理坐标可超出 [0, 1] 范围,实现纹理重复排列(如地板木纹的连续铺设);
  • 需在着色器中设置纹理采样模式(重复、镜像、 clamp 等)。

应用效果(Texture Applied to Surface)

  • 无纹理:表面为单一颜色,缺乏细节;
  • 有纹理:表面呈现复杂图案,真实感大幅提升。

三、疑难点整理总结

待补充。

写在最后

💗 感谢各位 📖 读者的支持,如果觉得文章对你有用,请 ♥️ 点赞 🌟 收藏,笔者将不胜感激 🌹~

相关推荐
嗷嗷哦润橘_2 小时前
AI Agent学习:MetaGPT项目之debate.py
学习
秋深枫叶红2 小时前
嵌入式第三十三篇——linux系统编程——文件IO
linux·学习·文件io
第二层皮-合肥2 小时前
50天学习FPGA第21天-verilog的时序与延迟
学习·fpga开发
知识分享小能手2 小时前
CentOS Stream 9入门学习教程,从入门到精通,CentOS Stream 9 中大数据 —语法详解与实战案例(15)
大数据·学习·centos
石像鬼₧魂石2 小时前
Hydra 弱口令爆破的详细命令模板
linux·windows·学习·ubuntu
暗然而日章2 小时前
C++基础:Stanford CS106L学习笔记 9 类模板(Class Templates)
c++·笔记·学习
m0_689618282 小时前
拓扑变换让机器人抓得又稳、又柔、又灵活
人工智能·笔记·学习·机器人
车载测试工程师2 小时前
CAPL学习-SOME/IP交互层-底层API函数
学习·tcp/ip·以太网·capl·canoe
代码游侠3 小时前
学习笔记——Linux内核链表
linux·运维·笔记·学习·算法·链表