Skip to content

Commit

Permalink
Create "GAMES101 第8讲 着色(着色频率, 实时渲染管线, 纹理映射)"
Browse files Browse the repository at this point in the history
  • Loading branch information
WangSimiao2000 committed Dec 25, 2024
1 parent cbe1a2d commit a8f8f83
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 0 deletions.
162 changes: 162 additions & 0 deletions _posts/2024-12-25-GAMES101-Lecture08.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
---
title: GAMES101 第8讲 着色(着色频率, 实时渲染管线, 纹理映射)
date: 2024-12-25 19:47:00 +0800
categories: [笔记, GAMES101]
tags: [GAMES101, 计算机图形学]
math: true
---

## 着色频率

把颜色应用在一个面上, 应用在一个顶点上, 或者应用在一个像素上, 这些都是着色的频率. 通常来说, 着色的频率越高, 渲染的效果就越好, 但是性能也就越差.

![着色频率](/assets/posts/GAMES101-Lecture08/01.png){:width="700px"}

其中: 如果在顶点上着色(例如图中在矩形的四个顶点上着色), 那么在矩形内部的像素就会使用顶点的颜色进行**插值**.

### 逐三角形着色

又叫 **平面着色 Flat Shading**

一个三角面内的颜色完全相同, 根据三角形的法线(两条边的叉乘)等参数求得, 然后填充整个三角形.

![逐三角形着色](/assets/posts/GAMES101-Lecture08/02.png){:width="400px"}

- 三角形面是平坦的(只有一个法线方向)
- 对于平滑的曲面, 逐三角形着色会导致边缘的颜色不连续

### 逐顶点着色

又叫 **Gouraud Shading**

对任意一个顶点, 计算出它的法线, 以此为基础计算出顶点的颜色, 然后在三角形内部的像素上进行插值.

![逐顶点着色](/assets/posts/GAMES101-Lecture08/03.png){:width="400px"}

- 内部的颜色通过顶点颜色的插值得到
- 顶点法线的计算方法见[后文](#顶点法线的计算)
- 又叫Phong Shading, 不是Blinn-Phong反射模型, 是一种Shading算法, 都是以Phong这个人的名字命名的

### 逐像素着色

又叫 **Phong Shading**

对于每一个像素, 计算出它的法线, 以此为基础计算出像素的颜色.

- 逐像素着色是最精确的着色方法
- 但是计算量也是最大的
- 通常用于高质量的渲染

### 着色频率的选择

![着色频率的选择](/assets/posts/GAMES101-Lecture08/04.png){:width="400px"}

- 当面片数量已经很高时, 逐像素着色的计算量就会很大, 这时候可以考虑逐顶点着色或者逐三角形着色.
- 当面片数量较少时, 逐像素着色的计算量就会很小, 这时候可以考虑逐像素着色.
- 当然, 当面片数量大于了一定的阈值, 超过了像素数量, 那么逐像素着色就是最好的选择.

### 顶点法线的计算

顶点法线的计算方法有很多种, 当我们只需要计算一个绝对光滑的球形时, 法线方向就是球心指向顶点的方向.

![顶点法线的计算](/assets/posts/GAMES101-Lecture08/05.png){:width="400px"}

当我们需要计算一个不规则的曲面时, 可以通过计算顶点的四周的面片的法线, 然后取平均值.

![顶点法线的计算2](/assets/posts/GAMES101-Lecture08/06.png){:width="400px"}

$$
N_v = \frac{\sum_{i} N_i}{\|\sum_{i} N_i\|}
$$

但是想要更加精确的法线, 可以通过计算顶点的四周的面片的法线, 然后**根据面片的面积加权平均**.

### 逐像素的法线插值

顶点的法线是已知的, 但是像素的法线是未知的, 所以需要对顶点的法线进行**重心坐标插值**.

![逐像素的法线插值](/assets/posts/GAMES101-Lecture08/07.png){:width="400px"}

插值后需要对法线进行归一化.

## 实时渲染管线(图形管线)

从场景到屏幕的过程, 通常被称为图形管线.

![图形管线](/assets/posts/GAMES101-Lecture08/08.png){:width="700px"}

1. **Application 应用**: 先输入三维(模型)空间中的顶点数据
2. **顶点处理 Vertex Processing**: 将顶点数据变换到屏幕空间(投影变换)
3. **三角形处理 Triangle Processing**: 将顶点数据变换成三角形
4. **光栅化 Rasterization**: 将三角形变成片元(fragment, 又叫像素)
5. **片元处理 Fragment Processing**: 着色, 计算像素的颜色(这里也有深度测试等操作)
6. **帧缓冲 Framebuffer Operations**: 将像素写入帧缓冲
7. **显示 Display**: 将帧缓冲的内容显示到屏幕上

如果要着色:
- **Gouraud Shading**: 顶点处理阶段计算顶点颜色, 片元处理阶段插值得到像素颜色
- **Phong Shading**: 顶点处理阶段计算顶点法线, 片元处理阶段插值得到像素法线, 然后计算像素颜色

这两个阶段(顶点处理和片元处理)是可以自定义的, 也成为可编程着色器, 我们称其为**着色器 Shader**.

### 着色器 Shader

现代GPU允许我们编写自定义的着色器(Shader), 用于顶点处理和片元处理.

**着色器 Shader** 是一种可以在GPU硬件上执行的语言, OpenGL使用GLSL, DirectX使用HLSL.
- **顶点着色器 Vertex Shader**: 用于顶点处理阶段, 计算顶点的位置, 颜色等
- **片元着色器 Fragment Shader**: 用于片元处理阶段, 计算像素的颜色

片元着色器例子:

```glsl
uniform sampler2D myTexture; // 纹理
varying vec3 lightDir; // 光线方向
varying vec2 uv; // 纹理坐标
varying vec3 norm; // 顶点法线
void diffuseShader() {
vec3 kd;
kd = texture2D(myTexture, uv); // 从纹理中获取颜色
kd *= clamp(dot(norm, lightDir), 0.0, 1.0); // 计算漫反射
gl_FragColor = vec4(kd, 1.0); // 设置像素颜色
}
```

## 纹理映射

**纹理映射 Texture Mapping** 是一种将纹理映射到三维模型表面的技术.

### 2D纹理

![2D纹理](/assets/posts/GAMES101-Lecture08/09.png){:width="700px"}

我们认为: 任何一个三维物体的表面都可以看作是一个二维平面, 我们可以将一个二维的纹理贴到这个平面上.

这个过程就是**纹理映射 Texture Mapping**, 一般由美术工程师完成, 也有自动化完成纹理映射的相关研究方向

### 纹理坐标(UV坐标)

![纹理坐标](/assets/posts/GAMES101-Lecture08/10.png){:width="700px"}

- 纹理坐标是二维的, 通常用 $u$ 和 $v$ 表示
- $u$ 和 $v$ 的范围通常认为是都在 $[0, 1]$ 区间内
- 三角形每一个顶点都对应一个uv坐标

### 纹理的重复

在下图中, 我们显示了一个建筑场景的uv坐标的可视化结果:

![纹理的重复](/assets/posts/GAMES101-Lecture08/11.png){:width="400px"}

我们可以很明显的看到, 纹理在建筑的表面上重复了很多次, 而且两个纹理的边界是很明显的; 但是在实际的渲染结果中, 并不能看到这种重复的现象:

![纹理的重复2](/assets/posts/GAMES101-Lecture08/12.png){:width="400px"}

这说明, 纹理本身在设计时是上下边界连续的, 这种纹理被称作**可平铺纹理 Tileable texture**.

### 三角形内部的像素的纹理坐标

我们知道三角形三个顶点对应的纹理坐标, 那么三角形内部的像素的纹理坐标是如何计算的呢?

这也是通过将顶点的纹理坐标进行插值得到的.
Binary file added assets/posts/GAMES101-Lecture08/01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/06.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/07.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/08.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/09.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/posts/GAMES101-Lecture08/12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a8f8f83

Please sign in to comment.