GAMES101-现代计算机图形学入门-闫令琪 课程笔记 - 汇总(中)
其实笔记是很早就在我的obsidian里写好的,之前一直拖延没有传上来,一直有人在问我,2026年新年新气象,终于决定发愤图强!传上来!
上一篇文章在这里:GAMES101-现代计算机图形学入门-闫令琪 课程笔记 - 汇总(上)
文章目录
4-shading着色
- shading 的含义:
- 对一个物体应用一种材质
shading model
Blinn-Phong Reflectance
-
一种最基础的光照模型,反射模型,经验型模型
-
公式
-
L
=
L
a
+
L
d
+
L
s
L=L_a+L_d+L_s
L=La+Ld+Ls
- 漫反射 L d = k d ( I / r 2 ) m a x ( 0 , n ⋅ l ) L_d = k_d (I/r^2)max(0, n\cdot l) Ld=kd(I/r2)max(0,n⋅l)
- 高光 L s = k s ( I / r 2 ) m a x ( 0 , n ⋅ h ) p L_s = k_s(I/r^2)max(0,n\cdot h)^p Ls=ks(I/r2)max(0,n⋅h)p
- 环境光 L a = k a I a L_a = k_aI_a La=kaIa
-
L
=
L
a
+
L
d
+
L
s
L=L_a+L_d+L_s
L=La+Ld+Ls
-
分类
- 漫反射(diffuse reflection)- 变化不是很明显的部分
- 高光(specular highlights)
- 间接光照/环境光照(ambient lighting)- 光打到别的物体,再打到它上面
-
输入
- 观测方向 v v v
- 平面的法线 n n n
- 光照方向 l l l
- p.s. 长度都是1
- 关于平面的参数
- 颜色
- 光照强度(shininess)

-
着色有局部性:
- 只考虑某个点的着色(shading),不考虑阴影(shadow)
漫反射

-
漫反射:光线被均匀地反射到各个方向
- 公式:
L
d
=
k
d
(
I
/
r
2
)
m
a
x
(
0
,
n
⋅
l
)
L_d = k_d (I/r^2)max(0, n\cdot l)
Ld=kd(I/r2)max(0,n⋅l)
-
k
d
k_d
kd:漫反射系数
- =1, 完全不吸收,白色
- =0,全部吸收,黑色
- 可以用 ( r , g , b ) (r,g,b) (r,g,b) 表示颜色
- I / r 2 I/r^2 I/r2:有多少光到达了这个点
- m a x ( 0 , n ⋅ l ) max(0, n\cdot l) max(0,n⋅l) :有多少光被接受了
-
v
v
v 的方向没有影响
- 不管从哪个位置看,看到的颜色是完全一样的
-
k
d
k_d
kd:漫反射系数
- 公式:
L
d
=
k
d
(
I
/
r
2
)
m
a
x
(
0
,
n
⋅
l
)
L_d = k_d (I/r^2)max(0, n\cdot l)
Ld=kd(I/r2)max(0,n⋅l)
-
Q:如何确定接收到的光照强度?
- Lambert’s cosine law
-
光照强度: c o s θ = l ⋅ n cos\theta=l \cdot n cosθ=l⋅n
-

-
光的能量扩散
-
- Lambert’s cosine law
-
光的强度衰减规律
-

-
考虑能量守恒
-
假设在单位距离(=1)上的光强度为 I I I,离光源半径 r r r 处的光强 I r 2 \frac{I}{r^2} r2I
-
高光
-
光滑的物体
- 近乎镜面反射
-
强度依赖于看的方向
- 当镜面反射与看的方向很接近的时候
- 接近的程度用 点乘 来计算

-

- 用半程向量做近似
- 用 n n n 和 h h h 的夹角 ⟺ \iff ⟺ R R R 和 v v v 的夹角
-
L
s
=
k
s
(
I
/
r
2
)
m
a
x
(
0
,
n
⋅
h
)
p
L_s = k_s(I/r^2)max(0,n\cdot h)^p
Ls=ks(I/r2)max(0,n⋅h)p
- 指数
p
p
p 的用途
- 一般取值 100-200

- 指数
p
p
p 的用途
-
实际上允许使用视角向量v和镜面反射向量R的接近程度来计算高光,而这种计算方式就称为 Phong 模型,Phong模型与Bling-Phong模型产生的高光效果不一样,Bling-Phong产生的高光更加柔和。
环境光
- L a = k a I a L_a = k_aI_a La=kaIa
着色频率(shading frequencies)

flat shading
- 逐个三角形着色(flat shading)
- 平面着色是使用一个顶点颜色来代表整个三角面的颜色, 默认是使用索引中第一个顶点的颜色
- 每个三角形面有一个法线向量(计算方法:两条边叉乘)
- 缺点:不够平滑
gouraud shading
- 逐个顶点着色(gouraud shading)
- 针对每个顶点计算,而后对每个顶点的结果颜色进行线性插值得到片元的颜色
- 每个顶点有一个法线
- 共有某个顶点的三角形,三角形的法线求平均作为这个顶点的法线
phong shading
- 逐个像素着色(phong shading)
- phong shading - 指着色频率,区 分phong 反射模型
实时渲染管线


- shading 可能发生在 vertex 阶段,也可能发生在fragment 阶段
- vertex 阶段:gouraud shading
- fragment 阶段:phong shading
纹理贴图 texture
如何将纹理贴上
- 根据 ( u , v ) (u,v) (u,v) 进行查询
解决一些问题
纹理太小
-
双线性插值 bilinear
- 利用周围的四个点优化
-
bicubic
利用周围的16个点画图
纹理太大
-
远处产生摩尔纹,近处产生锯齿
-
原因:用一个点去替代多个点
-
mipmap
-
拿到一个纹理后,先提前处理好,生成mipmap
-
给一个区域,可以立即知道这个区域的点的平均值
-
允许范围查询(vs.点查询 )
-
特点:快、近似(不准)、正方形的范围查询
-
每次减少到一半,原来的尺寸为 N × N N\times N N×N,总共计算 log N \log N logN 次,到 1 × 1 1\times 1 1×1
-

-
存储量是原来的 4 3 \frac{4}{3} 34,即增加了 1 3 \frac{1}{3} 31
-
-
各向异性过滤(各向同性:不同的方向上都一样)
-
对 mipmap 优化
-
可以查询矩形区域,而不完全是正方形区域
-

-
问题:存储量是原来的3倍
-
环境光
- 在现代的GPU中,纹理 = 一块内存 + 在这块存储中可以进行范围查询
- 环境光 可以看作一种纹理
- 假设 - 环境光来自于无限远处
应用
凹凸贴图
- 给一个假的法线贴图(纹理)造成视觉上的凹凸不平的感觉
- 没有改变一个物体的几何物体形状
- 视觉上,轮廓没有发生改变
- 不同高度可能造成阴影,但是凹凸贴图没有
位移贴图
- 改变 三角形顶点的位置
- vs. 凹凸贴图:轮廓发生变化,会有阴影关系
- 重要:
- 要求三角形足够细致,比纹理定义的频率高才可以
阴影
-
如何在光栅化的时候画阴影?
- shadow mapping
- 对应的结构 shadow map
-
在计算阴影的时候,不考虑场景的几何形状
-
核心思想:
- 如果这个点不在阴影中,光源和相机都可以看到这个点
-
硬阴影(点光源) v.s. 软阴影
-

-
软阴影(点光源有一定的大小)
- 离物体近的地方,阴影比较硬
- 离物体远的地方,阴影比较软
-
点光源
-
做法(两趟):
- 从点光源看向场景(有个虚拟相机),记录下它能看到的点的深度(Z-buffer)
- 从实际位置(相机)去看场景,看到某个点,变换到点光源的相机位置,比较它在点光源的相机位置的深度
-

-
如果深度一致,能被点光源看见
-
如果深度不一致,点光源看不见这个点
-
-
存在一些问题
- 计算机内部是浮点数,不准确(加入bias)
- shadow map 有分辨率,可能是走样的,有锯齿
- 两趟算法 开销大
5-几何
分类
隐式几何
-
点满足某些固定的关系(可以用公式表达)
-
缺点:
- 很难直接判断某个点 f ( x ) = 0 f(x)=0 f(x)=0
- 很难画出复杂的模型
-
优点:
- 给定某个点的坐标 ( x , y , z ) (x,y,z) (x,y,z) ,直接判断某个点在里面还是外面
- 方便判断到表面的距离
- 光线和表面求交点容易
-
组合几何
- 交集
- 并集
- 差集
-
距离函数
- 从任何一个地方到物体的最小距离(有正负)
-
f
(
x
)
=
0
f(x)=0
f(x)=0
- 如果没有办法表示出来,可以用 level set (水平集)表示,类似于等高线
显式几何
- 所有的点直接给出坐标,或者通过参数映射的方式全部写出
-
f
:
R
2
→
R
3
;
(
u
,
v
)
↦
(
x
,
y
,
z
)
f: \mathbb{R}^2 \rightarrow \mathbb{R}^3 ;(u, v) \mapsto(x, y, z)
f:R2→R3;(u,v)↦(x,y,z)
- e.g.
f
(
u
,
v
)
=
(
(
2
+
cos
u
)
cos
v
,
(
2
+
cos
u
)
sin
v
,
sin
u
)
f(u, v)=((2+\cos u) \cos v,(2+\cos u) \sin v, \sin u)
f(u,v)=((2+cosu)cosv,(2+cosu)sinv,sinu)
- 把所有的 u, v 遍历就可以得到所有的点
- e.g.
f
(
u
,
v
)
=
(
(
2
+
cos
u
)
cos
v
,
(
2
+
cos
u
)
sin
v
,
sin
u
)
f(u, v)=((2+\cos u) \cos v,(2+\cos u) \sin v, \sin u)
f(u,v)=((2+cosu)cosv,(2+cosu)sinv,sinu)
- 缺点:很难根据某个点的坐标 ( x , y , z ) (x,y,z) (x,y,z) ,直接判断某个点在里面还是外面
表示
-
点云
- 点 ( x , y , z ) (x,y,z) (x,y,z) 的列表
- 优点:可以表达任何几何
- 缺点:三维扫描,需要很大的存储空间
-
polygon mesh
-
.obj format
- 点
- 法线
- 纹理坐标
- 连接关系 f v / v t / v n f\ v/vt/vn f v/vt/vn
曲线
-
什么是贝塞尔曲线(Bezier Curve)?
-

-
起点在 p 0 p_0 p0 终点在 p 3 p_3 p3
-
-
为什么贝塞尔曲线是显式表示?
- 参数 t t t 是显示表示
-
如何画一条贝塞尔曲线?
- de Casteljau Algorithm
- 给定三个点
-

-

-

-

-
b 0 1 ( t ) = ( 1 − t ) b 0 + t b 1 \mathbf{b}_0^1(t)=(1-t) \mathbf{b}_0+t \mathbf{b}_1 b01(t)=(1−t)b0+tb1
-
b 1 1 ( t ) = ( 1 − t ) b 1 + t b 2 \mathbf{b}_1^1(t)=(1-t) \mathbf{b}_1+t \mathbf{b}_2 b11(t)=(1−t)b1+tb2
-
b 0 2 ( t ) = ( 1 − t ) b 0 1 + t b 1 1 \mathbf{b}_0^2(t)=(1-t) \mathbf{b}_0^1+t \mathbf{b}_1^1 b02(t)=(1−t)b01+tb11
-
得到 b 0 2 ( t ) = ( 1 − t ) 2 b 0 + 2 t ( 1 − t ) b 1 + t 2 b 2 \mathbf{b}_0^2(t)=(1-t)^2 \mathbf{b}_0+2 t(1-t) \mathbf{b}_1+t^2 \mathbf{b}_2 b02(t)=(1−t)2b0+2t(1−t)b1+t2b2
-
- 四个点
-
-
数学证明
-
四个点
-
三个点
-

- t = 0 t=0 t=0 时,在 b 0 b_0 b0 处
- t = 1 t=1 t=1时,在 b 1 b_1 b1 处
- 1 2 = [ ( 1 − t ) + t ] 2 1^2=[(1-t)+t]^2 12=[(1−t)+t]2 的展开
-
-
n n n 阶的贝塞尔曲线的公式
-

-
三个点, n = 2 n=2 n=2
-
四个点, n = 3 n=3 n=3
-
-
不一定是平面内,可以是三维空间内的点
- e.g. 点 b 0 = ( 0 , 2 , 3 ) , b 1 = ( 2 , 3 , 5 ) , b 2 = ( 6 , 7 , 9 ) , b 3 = ( 3 , 4 , 5 ) \mathbf{b}_0=(0,2,3), \mathbf{b}_1=(2,3,5), \mathbf{b}_2=(6,7,9), \mathbf{b}_3=(3,4,5) b0=(0,2,3),b1=(2,3,5),b2=(6,7,9),b3=(3,4,5) 代入公式 b n ( t ) = b 0 ( 1 − t ) 3 + b 1 3 t ( 1 − t ) 2 + b 2 3 t 2 ( 1 − t ) + b 3 t 3 \mathbf{b}^n(t)=\mathbf{b}_0(1-t)^3+\mathbf{b}_1 3 t(1-t)^2+\mathbf{b}_2 3 t^2(1-t)+\mathbf{b}_3 t^3 bn(t)=b0(1−t)3+b13t(1−t)2+b23t2(1−t)+b3t3 计算
-
-
性质
- 仿射变换下,对曲线上的每个控制点进行仿射变换,再画贝塞尔曲线,和贝塞尔曲线直接进行仿射变换相同。但是,对投影来说不适用。
- 凸包性质:贝塞尔曲线在控制点形成的凸包范围内
-
逐段的贝塞尔曲线
-
每4个控制点定义一条贝塞尔曲线
-

-
Q:如何保证某个顶点上是光滑的?
-
A:在这点的两个控制点在同一水平线上,反向,等长
-

-
C0 连续: a n = b 0 a_n=b_0 an=b0
-
C1 连续: a n = b 0 = 1 2 ( a n − 1 + b 1 ) a_n=b_0=\frac{1}{2}(a_{n-1}+b_1) an=b0=21(an−1+b1)
-
-
-
基函数
-
样条
- 一个由控制点控制的曲线
-
B样条
- 控制点的影响有限,能知道它影响的范围
曲面
-
把贝塞尔曲线用到曲面上
-

-
4个点,有 4 × 4 = 16 4\times4=16 4×4=16个控制点
-
把4个点连起来,作为一个贝塞尔曲线
-

-
两个控制时间的参数 [ t 1 , t 2 ] [t_1,t_2] [t1,t2] 或者说是 [ u , v ] [u,v] [u,v]
-
-
-
mesh 网格
- 几何处理
- mesh subdivison 增加三角形的数量,网格细分
- mesh simplification(downsampling) 用更少的三角形去表示同一个模型,会有一些损失,但是不能丢失太多信息
- mesh regularization 归一化,用的三角形大小都差不多
- 几何处理
mesh subdivison
-
引入更多的三角形后
- 平面更光滑
-
loop subdivision
-

-
两步
- 先细分
- 再调整
-
把一个三角形分成四个三角形
-
更新新的顶点位置
- 更新白色的点:被共享的点
- 更新白色的点:被共享的点
-
更新旧的顶点位置
-
更新白色的点
-
( 1 − n u ) ∗ 原来的位置 + u ∗ 邻居点的位置之和 (1-nu)*\text{原来的位置}+u*\text{邻居点的位置之和} (1−nu)∗原来的位置+u∗邻居点的位置之和
- n n n 顶点的度
-
-
-
Catmull-Clark Subdivision
-
Loop Subdivision v.s. Catmull-Clark Subdivision
- Loop Subdivision 只能用于三角形面的细分
- Catmull-Clark Subdivision 多边形的细分
mesh simplification
-
层次结构的几何
- v.s. 类似于 Mipmap(层次结构的图像)
-
在不同层次上,用不同的 mesh
-
Q:如何计算?
-
A:边坍缩(edge collapsing)
- Q:如何坍缩?
- A:Quadric Error Metrics(二次误差度量)
-

-
把这点放在一个位置上,最小化二次误差(类似于L2)
- 把这个点放在一个位置上,使得这个点到其它面的平方和最小
-
- Q:选择哪些点?
- A:用堆的数据结构,动态更新,每次取二次误差最小的点,更新后,再取二次误差最小的点
- 不断在局部取最优解,是个贪心算法,逼近全局最优解
6-光线追踪
光栅化 v.s. 光线追踪
-
光栅化的局限性
- 不能解决软阴影
- 当光反弹超过一次的时候
- Glossy reflection 反弹两次
- indirection illumination 反弹多次
-
光栅化 v.s. 光线追踪
- 光栅化:
- 快速的近似,质量较低
- 实时的渲染
- 光线追踪:
- 准确,非常慢,生成一桢需要大约 10K CPU时间
- 离线的渲染
- 光栅化:
光线追踪基础
-
光线的三种假设
- 光线沿直线传播(实际上是光波)
- 光线相交时,不会相互碰撞
- 光线从光源出发,最终到达人眼
- 光路可逆,视线形成到光源,仍然是有效的光路
-
光线追踪
- 从眼睛往场景中的物体投射出一个光线(eye ray)
- eye ray 考虑与场景中的物体最近的交点
- 将这个点与光源相连,是否被光照到,是否在阴影中
- 进行着色(用blinn phong model等)
- 从眼睛往场景中的物体投射出一个光线(eye ray)
-
recursive(whitted-style) ray tracing
-
弹射多次,是递归的算法
-
反射
-
折射
-
着色同样发生了变化
- 每个点会对这个点产生影响
- 每个点的能量会发生损耗

-
求交点
-
为什么要求交点?
- 渲染上
- 可见性
- 阴影
- 光照
- 几何上
- 判断在内还是在外
- 渲染上
-
光线的表达: r ( t ) = o + t d \mathbf{r}(t)=\mathbf{o}+t\mathbf{d} r(t)=o+td, 0 ≤ t < inf 0\le t < \inf 0≤t<inf
光线与球求交
- 先考虑最简单的情况


光线与隐式表面
- 进一步考虑隐式几何的相交

解出:实数、正数
光线与三角形求交
-
分解为两步:
- 三角形在某个平面上,先看光线是否和这个平面有交点
- 判断这个点是否在三角形内
-
平面
- 如何定义一个平面
- 法线 N N N
- 平面上一个点 P ′ P^\prime P′
- 平面上任何一个点
p
\mathbf{p}
p 如何表示
- p : ( p − p ′ ) ⋅ N = 0 \mathbf{p}:\left(\mathbf{p}-\mathbf{p}^{\prime}\right) \cdot \mathbf{N}=0 p:(p−p′)⋅N=0
- a x + b y + c z + d = 0 ax+by+cz+d=0 ax+by+cz+d=0
- 如何定义一个平面

- 如何一步求出光线和三角形的交点?
-

-
重心坐标 ( 1 − b 1 − b 2 ) (1-b_1-b_2) (1−b1−b2), b 1 b_1 b1, b 2 b_2 b2 都是正的
-
光线和三角形表面如何求交?
- 方法一:
- 逐个三角形和光线看是否有交点
- 方法简单,但是很慢
用 AABB 加速
-
AABB / uniform grid / spatial partitions 都是在光线追踪前的预处理
-
如何加速?
- 包围盒体积
- 如果光线和物体的包围盒没有交点,那么它和物体不会相交
-
一个长方体有 3 对面
- Axis-Aligned Bounding Box(AABB)
- 任何一个面都是沿着 x, y, 或者 z 轴
-
考虑 2 维的情况下,2对线
-
考虑光线与 AABB 点相交
- 两个关键点
- 一根光线进入盒子,当且仅当它进入了所有的对面(pairs of slabs)
- 一根光线离开盒子,当且仅当它离开了任意一个对面(pairs of slabs)
- 对每一对,计算
t
m
i
n
t_{min}
tmin 和
t
m
a
x
t_{max}
tmax(可以是负值)
- t e n t e r = m a x { t m i n } t_{enter}=max\{t_{min}\} tenter=max{tmin}
- t e x i t = m i n { t m a x } t_{exit}=min\{t_{max}\} texit=min{tmax}
- 如果 t e n t e r < t e x i t t_{enter}<t_{exit} tenter<texit ,光线在盒子中停留了一段时间(即有交点)
- 注意:还要判断
t
t
t 是否是负数,来验证正确性!
- 如果 t e x i t < 0 t_{exit}<0 texit<0 ,说明盒子在光线的背后,没有交点
- 如果 t e x i t ≥ 0 t_{exit}\ge 0 texit≥0 且 t e n t e r t_{enter} tenter ,光线的起点在盒子里,一定有交点!
- 结论:
- 光线和AABB有交点,当且仅当 t e n t e r < t e x i t t_{enter}<t_{exit} tenter<texit && t e x i t ≥ 0 t_{exit}\ge 0 texit≥0
- 两个关键点
-
Q:为什么选择AABB?而不是任意一个包围盒?
-
A:计算会容易很多,计算量少很多。
- 一般的平面相交 v.s. 沿着 x 轴的面相交

Uniform grids 均匀格子
-
预处理:
- 找到包围盒
- 画出格子
- 表面相交的地方涂黑

-
光线追踪:
- 如果光线与格子有交点
- 判断光线是否和格子里的物体相交
- 如何判断光线下一步走到哪个格子?
- 假设光线向着右上方走,下一步一定是在当前格子的上面或者右面
- 如果光线与格子有交点
-
格子的数量
- 格子太稀疏
- 没有加速
- 格子太密集
- 效率变低
- 启发式算法
- 格子数量 = C × \times × 物体数量(三维情况下, C ≈ 27 C \approx 27 C≈27)
- 格子太稀疏
Spatial Partitions 空间划分
-
解决格子的问题
-
格子大小不同(不均匀地划分),在分布稀疏的地方用大格子,在分布密集的地方用小格子
-
不同的划分方法
-

- 八叉树:
- 在二维空间是四叉树
- 每次划分四块,直到某一块里面包含的物体很少,不再划分
- 在三维空间是八叉树
- 在二维空间是四叉树
- KD 树:
- 沿着某个轴砍一刀,分成上下两个块
- 先水平划分,再竖直划分,交替
- BSP 树
- 每次选一个方向切分,不是横平竖直地划分
- 八叉树:
-
-
KD 树
-
这里省略了 1 2 3 的下一步划分
-

-
数据结构
- 中间节点存储
- 划分的轴:x轴,y轴,z轴
- 划分的位置:沿着轴的划分平面
- 子节点(指向子节点的指针)
- 内部节点不存储任何物体
- 叶子节点
- 物体列表
- 中间节点存储
-
-
如何做?
-
先看A,有交点,再判定A的两个子节点是否有交点
-
假如到了叶子节点
- 判断和物体是否有交点
-
-
缺点:
- 建立 KD 树很难,很难判定一个三角形是否和AABB有交点
- 一个物体可能在多个不同格子里
BVH
-
解决了 KD树 的问题
-
Object Partitions & Bounding Volume Hierarchy (BVH)
-
从物体出发进行划分
- 分成一堆,计算它的包围盒
- 递归地把一个包围盒里的物体分成两个部分
- 重新计算两个部分的包围盒


-
优点:
- 一个物体在一个包围盒里
-
缺点:
- 包围盒可能会相交
-
如何划分一个节点?
- 每次选择一个维度来划分
- 启发式算法1 :每次都沿着最长的轴划分
- 启发式算法2:找中位数那个物体的位置
- 方法:找第 n 2 \frac{n}{2} 2n 个数,用快速划分算法,时间复杂度 O ( n ) O(n) O(n)
- 结果:划分出来的三角形数量差不多,接近于平衡树
- 终止条件:直到包含很少的元素(设定一个阈值)
-
如果加了一个新物体?
- 需要重新从头开始预处理
-
BVH的数据结构
- 内部节点:
- 包围盒
- 子节点(指针)
- 叶子结点
- 包围盒
- 物体列表
- 内部节点:
-
伪代码实现
总结: spatial vs. object partition
- 空间划分(e.g. KD树)
- 划分成不重叠的区域
- 一个物体可能包含在多个区域中
- 物体划分(e.g. BVH)
- 把物体划分到不相交的集合
- 每个集合的包围盒在空间上可能相交
辐射度量学 Basic radiometry
- 动机
- blinning phong 着色过于简化
- 辐射度量学:精确地描述光的强度
- 度量方法和单位
- 定义了光照的若干属性
- radiant flux
- intensity
- irradiance
- radiance

Radiant Energy and Flux(power)
- Radiant Energy
- 定义:电磁辐射能量
- 符号: Q Q Q
- 单位:焦耳 Joule
- Radiant Flux(功 power)
- 定义:单位时间 energy
- 符号: Φ ≡ d Q d t \Phi \equiv \frac{\mathrm{d} Q}{\mathrm{~d} t} Φ≡ dtdQ
- 单位:watt(热学) / lumen(光学)
Radiant Intensity
- Radiant Intensity
- 定义:单位立体角上的 power
- 符号: I ( ω ) ≡ d Φ d ω I(\omega) \equiv \frac{\mathrm{d} \Phi}{\mathrm{~d} \omega} I(ω)≡ dωdΦ
- 单位:cd = candela


- 球体的单位立体角
- d ω = s i n θ d θ d ϕ d\omega = sin\theta d\theta d\phi dω=sinθdθdϕ
Irradiance
-
Irradiance
- 定义:power per unit area
- 符号: E ( x ) ≡ d Φ ( x ) d A E(\mathbf{x}) \equiv \frac{\mathrm{d} \Phi(\mathbf{x})}{\mathrm{d} A} E(x)≡dAdΦ(x)
- 单位:lux
-
光线垂直于面的部分才被吸收
radiance
- radiance
- 描述光线传播过程中的属性
- 定义:power per unit solid angle, per projected unit area
- = irradiance per solid angle
- = intensity per projected unit area
- 符号: L ( p , ω ) ≡ d 2 Φ ( p , ω ) d ω d A cos θ = d E ( p ) d ω cos θ = d I ( p , ω ) d A cos θ L(\mathrm{p}, \omega) \equiv \frac{\mathrm{d}^2 \Phi(\mathrm{p}, \omega)}{\mathrm{d} \omega \mathrm{d} A \cos \theta}=\frac{\mathrm{d}E(\mathrm{p})}{\mathrm{d} \omega \cos \theta}=\frac{\mathrm{d} I(\mathrm{p}, \omega)}{ \mathrm{d} A \cos \theta} L(p,ω)≡dωdAcosθd2Φ(p,ω)=dωcosθdE(p)=dAcosθdI(p,ω)
- 单位:nit

BRDF
- Bidirectional Reflectance Distribution Function (BRDF)
- 定义了不同的材质
- 反射方程
-

- f r ( ω i → ω r ) f_r(\omega_i \rightarrow \omega_r) fr(ωi→ωr) 从 ω i \omega_i ωi 到 ω r \omega_r ωr 的能量
-

- H 2 H^2 H2 指半球
- 从四面八方到这一点的光求和
-
渲染方程 rendering equation
-
L o ( p , ω o ) = L e ( p , ω o ) + ∫ Ω + L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) d ω i L_o\left(p, \omega_o\right)=L_e\left(p, \omega_o\right)+\int_{\Omega^{+}} L_i\left(p, \omega_i\right) f_r\left(p, \omega_i, \omega_o\right)\left(n \cdot \omega_i\right) \mathrm{d} \omega_i Lo(p,ωo)=Le(p,ωo)+∫Ω+Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi)dωi
- Ω + \Omega^+ Ω+ 正半球
- 假设所有的方向都是指向外面的
-
两部分组成:自己发出的光 + BRDF 反射别人的光
-
蒙特卡罗采样,进行近似计算
-

-

-

- 通过算子把渲染方程展开成递归项
-
光栅化
- 只有光源自己的光照 + 直接光照(只弹射一次)
全局光照
- 直接 + 间接光照(包括了一次、两次……、N次的光照)
蒙特卡洛积分
概率论
-

-

-
概率密度函数(probability distribution function) PDF
-
解决什么问题?
- 解决定积分(围的面积,一个数字)
- 之前的解法,先解出不定积分,再相减,得到定积分
- 不希望把解析式求出来,而是希望直接求得一个值
- 解决定积分(围的面积,一个数字)
-
vs. 黎曼积分:分成小的长方形,积起来
-
蒙特卡罗积分
- 利用采样的方法
- 基本的蒙特卡罗估算式子
- 随机均匀地采样一个位置 X i ∼ p ( x ) = 1 b − a X_i \sim p(x)=\frac{1}{b-a} Xi∼p(x)=b−a1(常数)
- F N = b − a N ∑ i = 1 N f ( X i ) F_N=\frac{b-a}{N} \sum_{i=1}^N f\left(X_i\right) FN=Nb−a∑i=1Nf(Xi)
- 不是均匀的采样(即此时的
p
(
X
i
)
≠
1
b
−
a
p(X_i)\neq\frac{1}{b-a}
p(Xi)=b−a1 )
- ∫ f ( x ) d x = 1 N ∑ i = 1 N f ( X i ) p ( X i ) X i ∼ p ( x ) \int f(x) \mathrm{d} x=\frac{1}{N} \sum_{i=1}^N \frac{f\left(X_i\right)}{p\left(X_i\right)} \quad X_i \sim p(x) ∫f(x)dx=N1∑i=1Np(Xi)f(Xi)Xi∼p(x)
- 求平均
- 重要:在 x x x 上求积分,就在 x x x 上采样
路径追踪 Path tracing
-
whitted-style ray tracing
- 只有镜面反射
- 漫反射就停止反射
-
在全局光照环境下存在 color blending 现象
-
whitted-style ray tracing 是错误的
-
渲染方程是正确的
- 解决定积分,得到值 => 蒙特卡罗解
- 解决递归问题
-
对于渲染方程: L o ( p , ω o ) = ∫ Ω + L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) d ω i L_o\left(p, \omega_o\right)=\int_{\Omega^{+}} L_i\left(p, \omega_i\right) f_r\left(p, \omega_i, \omega_o\right)\left(n \cdot \omega_i\right) \mathrm{d} \omega_i Lo(p,ωo)=∫Ω+Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi)dωi
- 忽略自己发出的光强
- 只考虑直接光照
- 从方向
ω
i
\omega_i
ωi 过来
- 如果是光源,就为光源的 L i ( p , ω i ) L_i(p, \omega_i) Li(p,ωi)
- 否则就为 0
- 从方向
ω
i
\omega_i
ωi 过来
-
∫
f
(
x
)
d
x
≈
1
N
∑
i
=
1
N
f
(
X
i
)
p
(
X
i
)
X
i
∼
p
(
x
)
\int f(x) \mathrm{d} x\approx\frac{1}{N} \sum_{i=1}^N \frac{f\left(X_i\right)}{p\left(X_i\right)} \quad X_i \sim p(x)
∫f(x)dx≈N1∑i=1Np(Xi)f(Xi)Xi∼p(x)
- f ( x ) = L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) f(x)=L_i\left(p, \omega_i\right) f_r\left(p, \omega_i, \omega_o\right)\left(n \cdot \omega_i\right) f(x)=Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi)
- p ( ω i ) = 1 / 2 π p\left(\omega_i\right)=1 / 2 \pi p(ωi)=1/2π,在半球上均匀采样(整个球的立体角是 4 π 4\pi 4π,半球的立体角是 2 π 2\pi 2π)
- L o ( p , ω o ) ≈ 1 N ∑ i = 1 N L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) p d f ( ω i ) L_o\left(p, \omega_o\right) \approx \frac{1}{N} \sum_{i=1}^N \frac{L_i\left(p, \omega_i\right) f_r\left(p, \omega_i, \omega_o\right)\left(n \cdot \omega_i\right)}{pdf\left(\omega_i\right)} Lo(p,ωo)≈N1∑i=1Npdf(ωi)Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi)
- 伪代码
-
(进一步优化)如果考虑间接光照
-

-
Q 点反射到 P 点的光照 = 在 P 点看 Q 点(把Q点当成光源)的直接光照
-
伪代码(递归求 shade(q, -wi) )
-
存在的问题:
-
光线数量大,运算量大,指数级爆炸
-

-
解决的伪代码
-
当 N = 1 N=1 N=1 的时候,就不会爆炸啦! 就是 path tracing!(当 N ≠ 1 N\neq1 N=1 的时候,是 distributed path tracing)
-
(优化)去除 For 循环
-

-
可以用到达某个 pixel 的足够多的 path 去对 radiance 求平均
-

-
-
-
递归没有结束条件
- 不能直接cut反射数量,不然能量也被cut了
- 解决方法:
- 俄罗斯轮盘赌(RR),以一定概率停下来。
- 设置一个概率
P
P
P
- 以 P P P 的概率渲染 L o P \frac{L_o}{P} PLo
- 以 1 − P 1-P 1−P的概率,不发出射线,得到0
- 最终期望值
E
=
P
∗
(
L
o
/
P
)
+
(
1
−
P
)
∗
0
=
L
o
E=P *( Lo / P)+(1-P) * 0= Lo
E=P∗(Lo/P)+(1−P)∗0=Lo
-
-
-
效率不高
- SPP,samples per pixel(发出path的个数)
- SPP 低,效果差
- SPP 搞,效果好,但是效率低
- 原因:均匀向四面八方采样,很多光线打不到光源,被浪费掉了
- 解决方法:选择一个合理的 pdf,不再是均匀向四面八方采样,而是在光源上均匀采样
- 在光源上采样,把渲染方程从对 ω \omega ω 采样改成对光源采样
- 写出 d ω d\omega dω 和 d A dA dA 的关系: d ω = d A cos θ ′ ∥ x ′ − x ∥ 2 d \omega=\frac{d A \cos \theta^{\prime}}{\left\|x^{\prime}-x\right\|^2} dω=∥x′−x∥2dAcosθ′ ,将 d A dA dA 的法线朝向 d ω d\omega dω

- SPP,samples per pixel(发出path的个数)
-
某一点收到的 radiance 来源于两部分
- from the light source(不需要俄罗斯轮盘赌)
- from other reflectors(需要俄罗斯轮盘赌)

-
(最后一步优化)如果某个点到光线的采样被 block 了
- contribution from the light source
- 再加两行

- contribution from the light source
-
一些问题
- 点光源处理:当作一个小的面光源
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐















所有评论(0)