可见性(Visibility) / 遮挡(Occlusion)
为什么需要可见性判断?
在场景中可能有多个三角形投影到相同像素位置。因此,我们必须决定:这个像素真正看到的是哪个三角形?
方法1:画家算法
核心思想:先画远处图元,再画近处图元,后画的像素覆盖前画的。
然而,由于在实际工作中,它存在局限性:
- 遮挡环(Cyclic Occlusion):无法线性决定绘制顺序。
- 三角形之间的深度关系可能不是全局一致的。
方法2:Z-Buffer(深度缓存)算法
深度缓存算法是现代光栅化管线中最常用的可见性处理方式。
核心思想:
- 每个像素记录一个当前最小深度值(默认是“无穷远”)。
- 对场景中的所有三角形进行光栅化时,逐像素判断当前片元的深度是否小于已有深度值。如果小于已有深度值,则更新颜色和深度;否则忽略该片元。
即:每一个像素可以记录先后顺序(最浅的深度信息),也可以说深度缓存是发生在像素内的。
深度缓存算法流程:P9~P11
- 初始化帧缓冲区和Z-Buffer:所有像素深度设为∞。
- 遍历所有三角形:对每个三角形进行光栅化,找到所有覆盖的像素。
- 对每个像素进行深度比较:把最浅的颜色放到深度缓冲区
- 最终图像 = 深度最浅的像素颜色。
深度缓存算法特点:
- 时间复杂度为 O(n),其中 n 是像素数量 × 三角形数量(近似估算)。
- 实时渲染中普遍使用。
着色:漫反射
什么是着色?
着色是根据物体表面属性、光源信息以及观察方向等因素计算最终像素颜色的过程。
定义:对不同物体应用不同材质
高光 / 漫反射 / 环境(间接)光照
P22观测方向,表面法线,光照方向,物体表面属性参数
漫反射光照模型(Diffuse Reflection)
- 当光线打在粗糙表面时,光会被均匀地向各个方向反射。
- 人眼所见亮度与观察方向无关,只与光照角度有关。
漫反射建模 —— Lambert’s Cosine Law(P25)
物体表面接收到的光强与光线方向和法线方向夹角的余弦成正比。
漫反射光照模型公式
Ld = kd(I / r2) ⋅ max(0, n ⋅ L)
| 符号 | 含义 |
|---|---|
| Ld | 表面点最终漫反射光强(颜色) |
| kd | 材质的漫反射系数(也就是表面颜色) |
| I | 光源强度 |
| r | 点光源与着色点之间的距离 |
| I / r2 | 实际有多少光强到达光照点,因存在衰减 |
| n | 表面法线向量(单位向量) |
| L | 从着色点指向光源的单位向量 |
| n ⋅ L | 入射夹角的余弦值,表示表面接收的能量 |
| max(0, ⋅) | 防止光线从背面照射时贡献负值 |
Light Falloff 光的衰减(P26)
- 点光源发出的光会均匀扩散到所有方向,因此距离每增长一倍,单位面积上接收到的光强下降为 I / r2。
- 这被称为 光照衰减律(Light Attenuation)。
着色:高光反射(Specular Reflection)
什么是高光?
表面光滑时,光线会沿特定方向反射。当观察方向和反射方向相近时,会看到高亮点,这就是高光。而根据计算,当法线方向和半程向量h非常接近时,会出现高光。
什么是半程向量?P8
半程向量比反射向量更好算
Blinn-Phong 高光模型(P8)
反射模型公式(改进版):
Ls = ks (I/r2) ⋅ max(0, cos ) p= ks (I/r2) ⋅ max(0, n · h) p
| 符号 | 意义 |
|---|---|
| Ls | 高光分量 |
| ks | 材质的高光系数(越大越亮) |
| I | 光源强度 |
| r | 光源与着色点距离 |
| n | 法线向量 |
| h | 半程向量(Half Vector) |
| p | 高光“锐度”指数(越大越尖锐) |
为什么要加指数p?(P9)
- 如果只使用n · h,会造成高光区域过大,缺乏真实感。
- 指数p控制高光“锐利程度”:
- 小 → 高光柔和扩散(如塑料)
- 大 → 高光集中尖锐(如金属)
环境光照
对于模型的有些地方,根本不可能被光线打到,但它却有一点光照。这是因为光线会被不断反射,直到打到这个位置。
因此,环境光照为:模拟由于多次间接反射而照亮物体暗部的光。
模型公式:La = ka * Ia
| 符号 | 含义 |
|---|---|
| ka | 材质的环境光反射系数 |
| Ia | 环境光强度(通常设为常量) |
环境光与光源/方向无关,通常是常数近似。
综合光照模型 —— Blinn-Phong模型P12
将三种光照合成一个表达式:L = La + Ld + Ls
La:环境光
Ld:漫反射(Lambert)
Ls:高光反射(Blinn-Phong)
三种着色方式(Shading Modes)
Flat Shading(平面着色)—— P16
- 每个三角形使用一个颜色(整个面法线一致)。
- 法线由三角形的三个点叉积得出。
- 简单快速,但边缘容易出现突变。
Gouraud Shading(Gouraud 着色)—— P17
- 逐顶点着色 + 插值颜色
- 每个顶点计算光照,三角形内部通过插值传播颜色。
- 优点:效率高
- 缺点:高光可能被“平滑”丢失
Phong Shading(逐像素着色)—— P18
- 逐像素插值法线,然后再计算光照。
- 比 Gouraud 更精确,能展现清晰高光。
- 成本较高(但现代GPU可以轻松处理)。
如何定义顶点法线?(P20)
一个顶点常常被多个三角形共享。
在这种情况下,顶点法线通常取这些三角形法线的加权平均值。
如何定义像素法线?(P21)
在 Phong Shading 中:
在三角形内部插值三个顶点法线。
得到的结果再归一化作为当前像素法线。
实时渲染管线
shader:每个像素都会执行一次
定义一个点的基本属性
任何一个三维物体表面都是二维的,找到物体表面的点和纹理表面的点一一对应的关系,就是纹理映射。
纹理上定义的坐标系:UV
================================================================
重心坐标
如何在三角形内部进行任何属性的插值?
(1) 重心坐标(Barycentric Coordinates)
在一个三角形平面中,任意点都可以表示为三个顶点的加权平均,即:
满足三个条件(P7):
- α+β+γ=1\alpha + \beta + \gamma = 1α+β+γ=1
- α,β,γ∈R\alpha, \beta, \gamma \in \mathbb{R}α,β,γ∈R
- 若三者都为正,则点 PPP 位于三角形内部。
(2) 重心坐标的计算:使用面积比法(Area Method)
用子三角形的面积占整个大三角形面积的比例来计算权重。
- 设点 PPP 在三角形 ABCABCABC 内
- 计算子三角形的面积:
- 可用叉乘公式简化面积计算。
(3) 重心坐标的用途
- 在三角形内部插值任意属性(颜色、法线、纹理坐标、深度等)
- 关键用于逐像素着色(fragment shader)
- 插值公式:属性(P)=α属性(A)+β属性(B)+γ属性(C)
(4) 重心坐标的透视矫正(Perspective Correction)
投影会破坏线性关系:
- 屏幕空间插值的重心坐标是错误的!
- 投影之后的图像是非线性的
纹理映射(Texture Mapping)
如何把纹理应用到渲染中?
P14纹理映射的原理:
- 每个顶点提供纹理坐标(u,v)
- 插值后传递到像素,再用(u,v)查找纹理颜色
问题1:如果纹理太小了怎么办?P16-P22
有一个很小的图,现在想把它放大,但是这会造成一个问题:低分辨率纹理被放大时,每个像素可能对应纹理中非整数坐标。
解决方法:双线性插值(Bilinear Filtering):
让一个像素考虑最靠近的4个像素,对颜色进行加权平均,从而做到平滑过渡。
设采样位置为(u, v):
- 找出周围的4个纹理像素(左上、右上、左下、右下)。
- 根据u, v距离,插值合成最终颜色。
问题2:如果纹理太大了怎么办?
多个像素可能对应纹理中很大一片区域,容易导致混叠(aliasing)
解决方法:Mipmap + 过滤器
- 为原始纹理生成一系列分辨率不断减半的图层(通常用 2 的幂次)
- 渲染时自动选择最合适的图层采样,这样可以:
- 降低计算压力
- 减少混叠和闪烁
范围查询(approximate filtering):
Mipmap允许做范围查询(但只能做近似的,正方形的查询)
- 在某个 Mipmap 级别中,按一定范围平均取样
- 实现更平滑的缩小效果(代价是精度下降)
实际 GPU 会使用 [三线性插值(trilinear filtering)]:
在两个相邻的 mipmap 层之间插值采样,提升过渡效果
纹理的应用
在现代GPU中,可以把纹理理解为一块内存,并且可以对这块内存进行滤波。
Environment Map:可以用纹理去描述环境光,然后用该环境光去渲染其他物体。
假设:环境光来自无限远,即:只记录方向信息,没有实际的深度意义。
Spherical Map:
Cube Map:
凹凸贴图:纹理可以定义一个表面上,任意一个点的相对高度。当相对高度改变,该点的法线也会随之变化,最终导致着色的结果发生变化,于是出现了明暗对比。
法线贴图:通过法线贴图,可以得到一个复杂的纹理,但是却没有改变人物几何信息。
- 把任何一个像素的法线做扰动(Perturb):通过定义不同位置的高度,把它临近位置的高度差来重新计算法线。P15
- 如何计算法线的变化:
位移贴图:实际地改变三角形顶点的位置
3D纹理

Leave a comment