其实笔记是很早就在我的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,nl)
      • 高光 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,nh)p
      • 环境光 L a = k a I a L_a = k_aI_a La=kaIa
  • 分类

    • 漫反射(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,nl)
      • 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,nl) :有多少光被接受了
      • v v v 的方向没有影响
        • 不管从哪个位置看,看到的颜色是完全一样的
  • Q:如何确定接收到的光照强度?

    • Lambert’s cosine law
      • 光照强度: c o s θ = l ⋅ n cos\theta=l \cdot n cosθ=ln

      • 在这里插入图片描述

      • 光的能量扩散

  • 光的强度衰减规律

    • 在这里插入图片描述

    • 考虑能量守恒

    • 假设在单位距离(=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,nh)p
      • 指数 p p p 的用途
        • 一般取值 100-200
        • 在这里插入图片描述
  • 实际上允许使用视角向量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. 软阴影

    • 在这里插入图片描述

    • 软阴影(点光源有一定的大小)

      • 离物体近的地方,阴影比较硬
      • 离物体远的地方,阴影比较软

点光源

  • 做法(两趟):

    1. 从点光源看向场景(有个虚拟相机),记录下它能看到的点的深度(Z-buffer)
    2. 从实际位置(相机)去看场景,看到某个点,变换到点光源的相机位置,比较它在点光源的相机位置的深度
      • 在这里插入图片描述

      • 如果深度一致,能被点光源看见

      • 如果深度不一致,点光源看不见这个点

  • 存在一些问题

    • 计算机内部是浮点数,不准确(加入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:R2R3;(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 遍历就可以得到所有的点
  • 缺点:很难根据某个点的坐标 ( 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)=(1t)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)=(1t)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)=(1t)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)=(1t)2b0+2t(1t)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=[(1t)+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(1t)3+b13t(1t)2+b23t2(1t)+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(an1+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{邻居点的位置之和} (1nu)原来的位置+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时间
      • 离线的渲染

光线追踪基础

  • 光线的三种假设

    1. 光线沿直线传播(实际上是光波)
    2. 光线相交时,不会相互碰撞
    3. 光线从光源出发,最终到达人眼
      • 光路可逆,视线形成到光源,仍然是有效的光路
  • 光线追踪

    • 从眼睛往场景中的物体投射出一个光线(eye ray)
      • eye ray 考虑与场景中的物体最近的交点
    • 将这个点与光源相连,是否被光照到,是否在阴影中
      • 进行着色(用blinn phong model等)
  • 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 0t<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:(pp)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) (1b1b2), 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 texit0 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 texit0
  • Q:为什么选择AABB?而不是任意一个包围盒?

  • A:计算会容易很多,计算量少很多。

    • 一般的平面相交 v.s. 沿着 x 轴的面相交
    • 在这里插入图片描述
Uniform grids 均匀格子
  • 预处理:

    1. 找到包围盒
    2. 画出格子
    3. 表面相交的地方涂黑
      在这里插入图片描述
  • 光线追踪:

    • 如果光线与格子有交点
      • 判断光线是否和格子里的物体相交
    • 如何判断光线下一步走到哪个格子?
      • 假设光线向着右上方走,下一步一定是在当前格子的上面或者右面
  • 格子的数量

    • 格子太稀疏
      • 没有加速
    • 格子太密集
      • 效率变低
    • 启发式算法
      • 格子数量 = C × \times × 物体数量(三维情况下, C ≈ 27 C \approx 27 C27
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} Xip(x)=ba1(常数)
      • 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=Nbai=1Nf(Xi)
    • 不是均匀的采样(即此时的 p ( X i ) ≠ 1 b − a p(X_i)\neq\frac{1}{b-a} p(Xi)=ba1
      • ∫ 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=N1i=1Np(Xi)f(Xi)Xip(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
    • ∫ 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)dxN1i=1Np(Xi)f(Xi)Xip(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)N1i=1Npdf(ωi)Li(p,ωi)fr(p,ωi,ωo)(nωi)
    • 伪代码
      • 在这里插入图片描述
  • (进一步优化)如果考虑间接光照

    • 在这里插入图片描述

    • Q 点反射到 P 点的光照 = 在 P 点看 Q 点(把Q点当成光源)的直接光照

    • 伪代码(递归求 shade(q, -wi) )

      • 在这里插入图片描述
    • 存在的问题:

      1. 光线数量大,运算量大,指数级爆炸

        • 在这里插入图片描述

        • 解决的伪代码

          • N = 1 N=1 N=1 的时候,就不会爆炸啦! 就是 path tracing!(当 N ≠ 1 N\neq1 N=1 的时候,是 distributed path tracing)

          • (优化)去除 For 循环

          • 在这里插入图片描述

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

          • 在这里插入图片描述

      2. 递归没有结束条件

        • 不能直接cut反射数量,不然能量也被cut了
        • 解决方法:
          • 俄罗斯轮盘赌(RR),以一定概率停下来。
          • 设置一个概率 P P P
            • P P P 的概率渲染 L o P \frac{L_o}{P} PLo
            • 1 − P 1-P 1P的概率,不发出射线,得到0
          • 最终期望值 E = P ∗ ( L o / P ) + ( 1 − P ) ∗ 0 = L o E=P *( Lo / P)+(1-P) * 0= Lo E=P(Lo/P)+(1P)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ω=xx2dAcosθ ,将 d A dA dA 的法线朝向 d ω d\omega dω
      • 在这里插入图片描述
  • 某一点收到的 radiance 来源于两部分

    • from the light source(不需要俄罗斯轮盘赌)
    • from other reflectors(需要俄罗斯轮盘赌)
    • 在这里插入图片描述
  • (最后一步优化)如果某个点到光线的采样被 block 了

    • contribution from the light source
      • 再加两行
      • 在这里插入图片描述
  • 一些问题

    • 点光源处理:当作一个小的面光源
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐