GAMES202-高质量实时渲染
时间:2023年9月1日16:22:54
视频URL:https://www.bilibili.com/video/BV1YK4y1T7yY
课程主页:https://sites.cs.ucsb.edu/~lingqi/teaching/games202.html
课程介绍 P1
Waht
主题
不涉及内容 28:11
How 39:45
Why 46:50
准备 48:50
学GAMES202 没必要看这本书 《Real-time Rendering》
Ch1.导读 P1
动机 64:00
实时渲染演变 67:00
技术和算法的里程碑 75:00
可编程渲染管线
预计算
Interactive 光线追踪
Ch2.回顾CG基础 P2
渲染管线 03:20
OpenGL 13:45
渲染类比绘画:
- 放置物体
- 放置画架
- 在画架上放画布
- 画画
- (更换其他画布画)
- (使用之前的画布参考)
easel:画架
GLSL 41:00
Shader调试 56:30
渲染方程 65:00
微积分 75:00 下节预告
Ch3.实时阴影 P3-4
阴影映射 P3 7:00
从光源出发,只需要获得深度图即可
阴影映射问题 P3 17:30
自遮挡
Shadow map记录的是离散值,存在精度问题可能导致自遮挡的发生
- 光源越垂直地面问题越小;越接近掠角问题越大
解决方案:根据光源和地面的夹角,增加容错率(bias)
新问题:bias过大,导致漂浮
解决方案:Second-depth shadow mapping*。记录最小和次小深度,取中间的深度
缺点:所有物体要求是watertight(均有正反面)
锯齿
解决办法:Cascaded 是工业界做法,不做展开
近似积分的技巧 P3 41:00
RTR中的近似:
- 令f(x)=2代入下面式子,可以发现左右是相等的,因此右式分母相当于归一化项
何时更准确:
- 当g的积分限小的时候
- g足够光滑(积分域内不要变化太大)
拆出Visibility为阴影项的影响
3.1 PCSS P3 55:00
Percentage closer soft shadows
作用:生成软阴影
引入:PCF
Percentage Closer Filtering
作用:抗锯齿。==在阴影映射中叫PCSS==。
核心思想:在采样Shadow Map时,多次采样得到是否在阴影里的二值结果,再对这些结果求平均。
注意:
- 不是最终渲染到屏幕的图上做filtering
- 也不是在Shadow map上做filtering
PCF 缺点:对所有阴影都使用同样的soft操作,不符合现实中的物理规律(见下面分析)
参数过大:采样区域大,效率低,阴影模糊参数过小:抗锯齿效果不明显
观察:被投射物(纸)和投射物(笔)离得越近,阴影越硬
- 笔尖处的纸和笔尖近,就硬,越远越软
结论:Shadow map不同地方需要使用不同的filter size。
改进:PCSS
分析:
- 与Light的大小有关(w
Light):wLight越大阴影越软 - Blocker和Reciver的距离有关(或者Blocker和Light的距离,二者等价用前者):Blocker和Reciver越远,阴影越软
公式推导使用相似三角形:红圈圈出
- w
Penumbra:阴影柔软程度,越大越软
- 图中从w
Penumbra往左不会有任何阴影,往右全是阴影。因此wPenumbra属于半影区域
重要补充
1.平均遮挡深度计算原理:只会对下图蓝色区域的值做平均
2.完全处于阴影区域的点也会计算出半影距离去采样。只不过完全处于阴影的点不论用何种PCF,结果都是返回阴影(0)
3.自己总结的结论
- L:点光源
- d
b1:第一种情况下(离笔尖近),遮挡物和光源的距离 - d
r1:着色点和光源的距离 - w
L1:光源size(=wL2) - w
p1:半影距离
——– P4 ——–
PCF和PCSS更多内容 P4 21:30
PCF用于PCSS时的公式,就是点在阴影内是1,不在是0,取该点对应Shadow周围区域所有点计算阴影,对结果加权平均
w:权重
f:函数
*:卷积
p:输入
注意:不是对Shadow map做卷积,也不是对结果图像做卷积
问题:PCSS的1,3步涉及采样,比较慢
3.2 VSSM P4 34:00
Variance Soft Shadow Mapping
优化PCSS:Step3
从step3的PCF入手
得到shade point对应shadow map图上一块区域的正态分布,需要知道μ和var(后面使用==切比雪夫估计==,没有使用正态分布,正态分布只是为了保证课程连贯性)
均值可以使用mipmap或SAT生成
方差可以通过下述公式生成,shadow map用单独一个通道存X^2^
实际使用时,先得到shade point的均值μ和方差var,计算CDF(pdf积分,即pdf曲线下面积)
- CDF没有解析解,只能求数值解或查表(依旧麻烦,继续改进)
切比雪夫不等式 P4 50:00
作用:给出均值和方差,可以近似得到 1 - CDF 的值
前提:t必须在均值右边
优化PCSS:Step1 P4 59:30
zavg:shade point对应shadow map上一块区域的点的平均深度。(计算在前面Step3说了)
zocc:遮挡物的平均深度
zunocc:非遮挡物的平均深度
假设shade point 深度为7
细节补充:MIPMAP和SAT P4 71:00
在使用VSSM时,需要通过shade point快速查询到对应shadow map区域的均值μ,这里展开讲解这个过程。
SAT for Range Query P4 74:00
作用:解决范围查询
思路:跑一遍数据,记录累加和。查询时,利用后面的累加和 - 前面的累加和即可
举例:下面 20-9=11(验证:3+7+1=11)
2D情况:查4次白色点即可得到蓝色区域(SAT均从左上角点开始生成)
- CPU生成SAT复杂度:O(m x n) m为行 n为列
动手验证
3.3 Moment shadow mapping P4 86:15
不是所有情况下都是高斯分布
实际分布是蓝线
漏光
解决的问题:改进VSSM,使其的分布描述得更准
VSSM相当于只使用了二阶矩,Moment SM用了更多阶矩
计算四阶矩的CDF很复杂,初学不建议看
下节预告 P4 101:40
3.4 基于距离场的软阴影 P5 06:40
SDF 回顾
SDF插值
SDF应用 P5 16:30
应用1:Ray Tracing
应用2:软阴影(假设SDF已经生成,生成过程复杂课程未涉及)
安全角度θ反映了遮挡程度
在观察方向取多个点计算θ,取最小θ的作为最终安全角度,安全角度越小越在阴影,越大越不在
k代表过渡带,k越大越硬,k越小越软
距离长阴影小结 P5 36:20
其他应用:SDF字体
Ch4.实时环境映射 IBL P5-6
———- 假 · 实时 ———-
==假实时==指的是==场景不可动==计算的间接光
环境光照介绍 P5 45:00
环境光存储方式:Spherical map 和 Cube map
- HDRI map <=> Spherical map
蒙特卡洛积分来自四面八方的环境光不现实,计算量太大(蒙特卡洛积分==弊端==就是需要大量样本,结果才能逼近真实值)
4.1 分离近似求和 P5 51:10
The Split Sum Approximation
推导可参考:[近似积分的技巧 P3 41:00](#近似积分的技巧 P3 41:00)
Part1
本质:在法线附近采样得到Pre-Filtering
橙色框内的积分限:反射的镜面波瓣
- lobe:波瓣
类比计算实时阴影的公式(红框)可以发现:如何分离积分求近似值很灵活
Part2
本质:预计算BRDF,只引入粗糙度α和cosθ
右边的项不容易预计算(变量太多)
课程不考虑G,但可以发现G的变量也是θ和α
From:GSN Composer:Shader Monthly
圈出来的是变量,颜色一样的表示可近似相等。可以发现有3个变量,尝试降维。
- RTR中,这几个角度可互换:入射光与法线夹角 ≈ 出射光与法线夹角 ≈ 半程向量与法线夹角
- R
0:对于金属是基础反射率albedo,对于非金属是下面这个公式(课程里面没有作区分,均当作基础反射率albedo)
拆出F项,预计算积分部分(fr部分除以了F,意味着不需要计算了哦)
分离近似求和思想
- 分母p:pdf
——– P6 ——–
前置知识
环境光阴影 8:00
RTRT:Realtime Raytracing
数学基础 19:40
回顾:傅里叶变换
时域卷积 = 频域乘积
基函数 30:30
基函数:许多函数线性组合可以成为新的函数,每一个线性组合项称为基函数
优点:物体可旋转
缺点:高频信息难以还原
球谐 – 基函数 33:40
球谐函数:一种2D基函数,每个基函数两两正交
l:阶数
m:个数
给定任何函数f(w),求Basic Function系数的过程称为投影(这一块只能意会,不太好表达,因为它有一种连续变化的感觉)
- f(w)是一个2D函数(2D:理解成一个球面函数),Basic Function也是一个2D函数。对于每个θ、φ,f投影到每个Basic Function上积分都有一个值c
- 类比1D傅里叶展开(泰勒展开也类似):相当于把f乘以单独的某一个基函数,积分得到的结果(f和B的卷积)
- 类比空间xyz坐标轴,空间某一点的位置就是向xyz的投影,位置值就是系数c
i - **==类比==**向量点乘,把f(x)当做一个任意向量,把每一个B函数当作一个和f(x)同维的基向量。下面的过程就很像==点乘==,由于函数表示一系列数,因此需要==再积分==才是投影的结果。(推荐这样理解!)
纯干货数学推导_傅里叶级数与傅里叶变换_Part1_三角函数的正交性:https://www.bilibili.com/video/BV1Et411R78v(函数正交性理解可参考)
类比Prefiltering 56:40
预计算Prefiltering,使用反射向量采样 <=> 使用反射向量采样特定区域
BRDF * Li就好像再做投影!!!
- L
i就像由一系列基函数组成,可以有高频有低频 - ==BRDF需要是Diffuse==,就好似低通滤波器
- 高频 * 低频 = 低频
Al相当于系数,l是阶数,由图可得l>3阶之后影响不大
1阶实验
2阶实验
3阶实验
小结 67:40
SH光照弊端:只能解决漫反射环境光照,因为只有漫反射BRDF是低频的
4.2 PRT Diffuse 70:00
Precomputed Radiance Transfer
非IBL的计算环境光照的技术
渲染方程渲染时的未知量:
- i:2D(θ,φ)
- o:2D(θ,φ)
各个物理量:
L(i)
,V(i)
,BRDF(i, o)
,max(0, n·i)
输出:1D
直接使用渲染方程计算简介光照:费
假设:场景内只有光源可动,物体和相机都不可动(这里因为BRDF是漫反射的,的确可以固定o)
- L(i):一系列球面基函数,运行时可变,可进行预计算(由一系列基函数构成)
- V(i):往四面八方看可见性,球面函数,固定不变
- BRDF:观察方向o不变(已给出),球面函数,固定不变
lighting是球面函数,light transport 也是球面函数。以下只展开lighting部分:
PRT 关键理解(个人)
lighting coefficient
渲染方程中变化的量是L,它会随环境贴图变化而变化,因此需要对不同的环境贴图求系数l
i(i表示不同入射方向)。这样就可以通过系数l
i和基函数Bi(i)确定一张环境贴图入射的Radiance。在实际渲染时,不需要传环境贴图,只需要提供li就可以得到近似的L(i)。(不同的环境贴图对应一组不同的li,计算时不需要额外进行采样)==一张环境贴图输出维度==:通道数 * 基函数个数
light transport。
- 根据1改造渲染方程,再将渲染方程积分和求和对换(根本想不到好吧?!),根据入射Radiance做球谐投影
- ==输出维度==:顶点数 * 基函数个数(实际在顶点着色器运行时,一个顶点只取出相应的T
i,Ti∈ R^基函数个数^)
启发
SH 基函数 86:00
SH基函数性质
可视化:相当于不同频率的环境光所影响下的结果
结果 94:20
PRT补充 P7 9:00
Precomputed Radiance Transfer
需要预计算,并非完全实时
PRT (Diffuse Case)
基函数正交性可以从O(n^2^) -> O(n)
PRT (Glossy Case) P7 14:10
每个不同的o都对应一个BRDF,导致light transport部分不一样
PRT本质 P7 24:30
下图想表达:任意复杂的light transport都能被预计算得到
- L:光源
- E:眼睛
- D:漫反射
- S:镜面反射。理想的,完全的反射
- G:介于D和S之间
换角度看:B(i)相当于渲染方程L(i),每一个基函数计算的结果就相当于是一个光源渲染的结果
PRT更适合低频,高频光照还原比较费
小波 – 基函数 P7 44:40
优点:能够较好还原高频信息
缺点:物体不能旋转
低频留左上,高频留其他
递归操作
Ch5.实时全局光照 P7-9
—— 真 · 实时, 3D Space ——
==真实时==指的是==场景可动==计算的间接光
实时环境光照介绍 P7 58:00
5.1 RSM P7 67:30
思路:利用shadow map找到不处于阴影的片段,这些片段又作为次级光源照亮其他物体。实际使用时也不会使用全部次级光源,而是找离当前着色点近的(例如shadow map上周围像素)
Reflective Shadow Maps
shadow map相当于给了我们一个场景的离散表述,每一个像素都可以当成是一个次级光源。一次弹射相当于这些次级光源对点p的影响
假设:所有作为次级光源的物体表面都是Diffuse的,点p可以不用是Diffuse的
p点对立体角的积分 ==> q点对面积的积分
并非所有次级光源都对p有贡献(一次弹射)
- 可见性:次级光源没有接收直接光照,可以剔除
- 方向性:法线和二者连线夹角超过90度,可以剔除
- 距离:次级光源和p点过远,可以剔除
将p点投影回shadow map,寻找邻近点作为次级光源(大胆假设)
- 具体采样方法没展开
RSM优缺点 P7 95:55
——– P8 ——–
5.2 LPV* 03:50
Light Propagation Volumes
LPV 步骤
- 类似RSM,计算出每个次级光源表面
- 生成表示场景的体素网格,找到每个网格附近的次级光源,利用2阶SH近似
- 根据光源对周围体素的分布,边传播边求和,利用2阶SH近似每个体素的Radiance分布。直到稳定结束。
上图只展示了4个面
LPV 问题 18:30
漏光
LPV 效果 24:40
5.3 VXGI* 26:00
Voxel GLobal Illumination
步骤 30:35
效果 37:50
直接光
间接光
最终效果:直接 + 间接
——– Screen Space ——–
GI in Screen Space 43:50
起点:直接光照信息
思想:做后期处理,预测间接光
5.4 SSAO 46:30
Screen Space Ambient Occlusion
优点:易于实现,立体感更强
SSAO
- 一种全局光照的近似
- 在屏幕空间
关键概念:
- 假设间接光是常数
- 考虑不同shading point的可见性(并非所有point都能收到各个方向的Incident Radiance)
- 假设是漫反射材质
AO推导 55:30
橙色区域是常数
AO推导结果 69:00
SSAO 推导 71:40
假设不知道法线,采样一个像素对应点的一个球
问题:当深度相差过大时,不应该认为有遮挡,但没有做这种过滤,会导致SSAO瑕疵(个人感觉如果球半径不大的话,应该不会发生这种瑕疵吧??)
举例:下图的凳子和地面相差很远,但地面扔被遮挡
优化:先用少量Sample得到Noise AO,再做De Noise
假设法线已知,采样的是半球
在SSAO基础上做了深度过滤,离得太远的物体不会遮挡
——– P9 ——–
SSDO* 8:00
Screen Space Directional Occlusion
SSAO的改进:SSAO假设间接光是一样的,SSDO则考虑得更多
AO:在大范围内,没有打到物体则有间接光(假设:打到物体则产生遮挡)
DO:在小范围内,打到物体则有间接光(假设:打到物体则产生间接光)
DO只考虑被挡住的部分
思路:P点半球范围内采样(下图1的A,B,C,D),根据采样点的可见性(观察方向到该点)来决定是否被挡住,挡住的计算间接光
问题:下图3中没有被挡住却实际看作被挡住
SSR 28:30
Screen Space Reflection (SSR)
本质:屏幕空间做光线追踪
两个任务;
- 求交
- 着色
效果
基础SSR算法 34:20
思路:每次前进步长,寻找交点
问题:步长太小,效率低;步长太大,精度差
动态步长
生成深度Mip-Map
做法:min pooling
思路:从最精细的一层开始,走一步,没有交点就粗糙层+1
终止条件:找到交点或没有交点停下
问题 59:00
Shading using SSR 61:30
假设:反射物是Diffuse(地面就是接收反射物发出的Radiance)
提高* 69:10
SSR小结 75:45
Ch6.基于物理的材质 P10-11
PBR Material 04:30
微表面模型的BRDF 15:30
微表面法线和半程向量一致时,才能发生镜面反射
Fresnel Term
越接近grazing angle(掠角),反射程度越大
绝缘体Fresnel Term
导体Fresnel Term
NDF
z法线分布函数
高斯平面无限大,但角度极限是90度,因此定义在坡度空间(Slope Space)
NDF在投影立体角上积分为1
根据γ的不同,可以控制tail长度
Shdowing-Masking Term 47:00
入射,出射越接近grazing angle,遮挡越严重
没有G项,在grazing angle处分母(n, o)
会接近0,导致外圈是一圈白色
m:half vector
问题:存在能量损失
Kulla-Conty 62:10
思路:
- 假设L(i) = 1,那么经过BRDF反射后,损失的能量就是 1 - E(μ
o) - 考虑到BRDF的可逆性,入射出射方向都要考虑,因此这里的BRDF设计为 $c(1-E(μ_o))(1-E(μ_i))$ ,使其积分为 1 - E(μ
o) 来补齐缺失的能量。
上述BRDF应用换元的思想:cosθsinθ dθdΦ = sinθ dsinθdΦ => μ dμdΦ
Eavg可以打表算
但此时依然有问题,因为如果BRDF是有颜色的,则能量会吸收,能量积分和不为1了。Kulla-Conty方法是先考虑没有颜色的情况,再考虑由颜色引起的能量损失(从菲涅尔项入手–菲涅尔就体现了不同波长的反射率)。
思路:使用平均菲涅尔项
——– P10 ——–
LTC* 4:30
Linearly Transformed Cosines
Disney’s Principled BRDF* 26:10
实现复杂,不展开,详见开源实现
适用于离线渲染
sheen:边缘一圈雾化效果,类似绒毛的感觉
参数空间过大,可能导致冗余
NPR 52:40
真实感渲染
非真实感渲染
NPR应用 60:30
什么是风格化 64:50
描边 + 色块 + 表面笔划
描边 68:30
描边区域:边缘、折痕、材质、多面共享边界
Shading
思路:Grazing Angle附近为描边
问题:不同位置描边效果不一样
Geometry
扩大一圈作为描边
Image
色块 86:15
表面划线 91:00
mipmap等级提高,但密度不变
NPR小结 98:00
Ch7.实时光线追踪 P12-13
课程安排
实时光线追踪 12:30
RTX就是一种硬件架构,可以让我们Trace光线
先打到primary hitpoint,再打到光源
接着打到secondary hitpoint,再打到光源
Key:降噪 28:10
Temporal 41:10
时间滤波
Back projection
- 得到点的世界空间坐标(下面PPT变回模型空间,M应该可删)
- 使用上一帧的变换矩阵,将点投影回上一帧的屏幕空间
不同于CV的光流,光流只知道两帧结果,求解难度大,效率低
先做当前帧降噪(空间降噪),再找到上一帧对应像素做线性混合(时间降噪)
- 大多数是用上一帧的内容
- 不太适合光照变化强烈的场景
结果展示 65:55
滤波不能使图变暗:
- 下图1暗是因为超出白色亮度被clamp了,所以导致能量损失。如果使用HDR就可以解决。
Temporal 问题 71:05
切换场景,光源,特写镜头等导致前后帧变化剧烈
向后退,使得当前帧引入新像素点
某些点突然出现,类似case2
参考:[Temporal Clamping](#Temporal Clamping)
解决问题 80:10
Clamping:把前一帧的结果限制到当前帧范围
Detection:
- 使用object ID,前后帧id相同才有匹配
- 根据ID调整α
- 不匹配则当前帧加大空间过滤
其他问题:滞后
小结 91:00
——– P13 ——–
实现滤波 7:40
双边滤波 20:45
Bilateral Filtering
高斯滤波问题:模糊
双边滤波:保留边界
- 如果i、j颜色差异不大,继续沿用高斯滤波
- 如果i、j颜色差异大,则降低混合权重
双边滤波问题:不利于降噪
联合双边滤波 28:30
思想:使用更多特征来滤波
实现大范围滤波 47:50
如果按常规做法,大范围滤波性能消耗很大
法1.Separate Passes
法2.Progressively Growing Sizes 58:50
思想:多次filter,但核内步长不同
步长小:去高频
步长大:去低频
问题:Outlier Removal 76:00
问题:图像中存在超级亮的点,滤波后会导致周围很亮
解决:在滤波前解决Outlier
具体办法:对任意像素,计算7x7范围内的均值与方差,超过均值与方差的点认为是Outlier,使用Clamp将其压缩到一个范围内
Temporal Clamping
Ch8.工业界解决方案 P14
SVGF 04:45
时空方差引导滤波
考虑到长方体侧面(如图A,B点)深度差异较大,故不再单纯比较深度。而是沿法线看过去的面(切线空间)来比较深度,这也下图A,B实际深度差异不大,可以互相贡献。
RAE 25:30
Recurrent AutoEncoder
SVGF vs. RAE 34:40
工业界解决方案实践 39:45
抗锯齿
每帧选取同一像素内不同位置的点sample
矢量化
GBuffer不能使用抗锯齿
超分辨率 56:00
延迟渲染 68:20
Tiled Shading 76:00
思想:在延迟渲染基础上,发现不是所有光源都会对物体产生影响,可以剔除掉不会产生影响的光源做shading
俯视图,圆圈是点光源
Clustered Shading 78:50
在Tiled Shading基础上,对深度再切片
LOD(Nanite) 81:00
使得区域间有重叠,实现blend效果