Skip to content

Commit 27850c0

Browse files
committed
feat: update on 26.03.25
1 parent 9c70d0a commit 27850c0

86 files changed

Lines changed: 1355 additions & 46 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/cg/5.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -832,13 +832,13 @@ mipmap 是宽高同时缩小的,但各向异性过滤是可以按不同比例
832832
<img src="images/lec5/85.png" width=30%>
833833
</div>
834834
835-
- 比较光源到着色点的距离和阴影图
835+
- 比较光源到着色点的距离和阴影贴图
836836
837837
<div style="text-align: center">
838838
<img src="images/lec5/86.png" width=30%>
839839
</div>
840840
841-
- 图中绿色部分表示光到着色点的距离近似等于阴影图上的深度,非绿色的部分就是阴影存在的区域
841+
- 图中绿色部分表示光到着色点的距离近似等于阴影贴图上的深度,非绿色的部分就是阴影存在的区域
842842
843843
事实上,阴影映射是一种很知名的渲染技术,它在早期动画(比如《玩具总动员》)和所有 3D 游戏中是一种基础的阴影技术。
844844
@@ -861,7 +861,7 @@ mipmap 是宽高同时缩小的,但各向异性过滤是可以按不同比例
861861
<img src="images/lec5/89.png" width=50%>
862862
</div>
863863
864-
- 阴影质量依赖于阴影图的分辨率(基于图像的技术的常见问题)
865-
- 阴影图分辨率过低会导致锯齿状的阴影出现
866-
- 一些游戏可能存在类似“阴影质量”的选项,这就是在调整阴影图的分辨率
864+
- 阴影质量依赖于阴影贴图的分辨率(基于图像的技术的常见问题)
865+
- 阴影贴图分辨率过低会导致锯齿状的阴影出现
866+
- 一些游戏可能存在类似“阴影质量”的选项,这就是在调整阴影贴图的分辨率
867867
- 浮点数深度值的比较意味着会存在量纲(scale)、偏差(bias)和容忍度(tolerance)的问题

docs/ge/15.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ counter: true
103103
- 问题:要求过于严格,导致留在内存中的东西越来越多,所以现在很少这么做了
104104

105105
- **弱引用**(weak reference):允许直接删除对象,但每次调用回调函数前会先检查其依赖的对象是否存在
106+
106107
>很像 C++ 的智能指针
107108
108109
<div style="text-align: center">

docs/ge/21.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ Lumen 的解决流程如下(简化版):
678678
<img src="images/lec21/67.png" width=80%>
679679
</div>
680680

681-
1. 根据表面缓存(和阴影图)计算每个像素的直接光照
681+
1. 根据表面缓存(和阴影贴图)计算每个像素的直接光照
682682
- 将 128x128 的页划分为 8x8 的块
683683
- 使用 8x8 的块来剔除光源
684684
- 每个块选择前 8 个光源

docs/ge/5.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ MR 转换到 SG:
645645

646646
- **百分比接近过滤**(percentage closer filtering, **PCF**):
647647
- 要解决的问题:来自阴影映射的阴影走样严重
648-
- 从当前像素周围的阴影图中取样,并将其深度与所有样本进行比较
648+
- 从当前像素周围的阴影贴图中取样,并将其深度与所有样本进行比较
649649
- 通过平均结果,我们得到光与影之间更平滑的线条
650650

651651
<div style="text-align: center">
@@ -656,7 +656,7 @@ MR 转换到 SG:
656656

657657
- **百分比接近软阴影**(percentage closer soft shadows, PCSS)
658658
- 要解决的问题:走样 + 采样不足的问题
659-
- 搜索阴影图并平均与光源更接近的深度
659+
- 搜索阴影贴图并平均与光源更接近的深度
660660
- 使用平行平面近似
661661

662662
- 方差软阴影映射(variance soft shadow map)

docs/rtr/3.md

Lines changed: 117 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ counter: true
99
先来简单回顾一下**阴影映射**(shadow mapping)的原理。
1010

1111
- 它是一种**两趟**(2-pass)**算法**
12-
- 第一趟:从光源位置出发看向场景,生成**阴影图**(SM),即来自光源的「深度纹理」
12+
- 第一趟:从光源位置出发看向场景,生成**阴影贴图**(SM),即来自光源的「深度纹理」
1313

1414
<div style="text-align: center">
1515
<img src="images/lec3/1.png" width=40%>
@@ -90,7 +90,7 @@ counter: true
9090
=== "**自遮挡**"
9191

9292
- 左图中虽然人物的阴影是正常的,但是地面上却有一圈圈的纹路。这并非摩尔纹(即不是采样问题),而是由**数值精度**导致的问题。
93-
- 来看右边的示意图,光源照射场景后会得到图中用红色线条标出的阴影图,它是离散的,且每个点的深度即为光源到该点的距离。
93+
- 来看右边的示意图,光源照射场景后会得到图中用红色线条标出的阴影贴图,它是离散的,且每个点的深度即为光源到该点的距离。
9494
- 现在从眼睛处看向某一点,然后取该点和光源的连线(蓝色虚线)。但由于数值精度问题,实际上该点的深度位于橙色线条标记的地方,也就是说光源对应的深度实际上会更浅。这就导致了橙色线条处的地板「挡住了」该点,误以为该点处在阴影中。
9595
- **掠射角**(grazing angle)越大,该问题越严重(所以垂直照射时问题最小)。
9696

@@ -120,16 +120,16 @@ counter: true
120120

121121
=== "**反走样**"
122122

123-
阴影图的分辨率有限,如果分辨率不够大,很容易出现锯齿状的阴影。
123+
阴影贴图的分辨率有限,如果分辨率不够大,很容易出现锯齿状的阴影。
124124

125125
<div style="text-align: center">
126126
<img src="images/lec3/13.png" width=60%>
127127
</div>
128128

129129
解决方案有:
130130

131-
- **级联阴影映射**(cascaded shadow mapping):为阴影图的不同位置设置不同分辨率,在工业界中得到应用
132-
- 动态分辨率的阴影图
131+
- **级联阴影映射**(cascaded shadow mapping):为阴影贴图的不同位置设置不同分辨率,在工业界中得到应用
132+
- 动态分辨率的阴影贴图
133133

134134

135135
## The Math Behind Shadow Mapping
@@ -193,7 +193,7 @@ $$
193193
- 而不是为了实现软阴影效果(也就是后面介绍的 PCSS)
194194
-**阴影比较结果**(对于任意一点,在阴影中记为0,否则记为1)进行**滤波**(filtering)(模糊)
195195

196-
- **不直接对阴影图做滤波**的原因:
196+
- **不直接对阴影贴图做滤波**的原因:
197197
- (第一趟中)这样的纹理滤波仅对颜色分量计算平均值,这导致先会得到一个模糊的阴影贴图(比如把物体本身边缘给模糊掉了)
198198
- (第二趟中)而计算深度值平均值后再进行比较,则仍然得到的是**二元**可见性(硬阴影),并没有起到模糊阴影的效果
199199

@@ -303,7 +303,7 @@ $$
303303

304304
通过这个公式,我们就能理解之前为什么说
305305

306-
- PCF != 先对阴影图滤波再比较的结果
306+
- PCF != 先对阴影贴图滤波再比较的结果
307307

308308
$$
309309
V(x) \ne \chi^+ \{[w * D_{\text{SM}}](q) - D_{\text{scene}}(x)\}
@@ -337,7 +337,7 @@ $$
337337
- 方差:
338338
- $\text{Var}(X) = E(X^2) - E^2(X)$
339339
- 所以只需额外计算深度平方的均值
340-
- 也就是说只要生成另一张阴影图,记录深度的平方值(不会产生很多额外的开销)
340+
- 也就是说只要生成另一张阴影贴图,记录深度的平方值(不会产生很多额外的开销)
341341

342342
回到前面有关「百分比接近」的讨论。在已经得到均值和方差的基础上,阴影区域的精确解(多少百分比的纹素的深度比着色点的更浅)便是着色点深度在对应正态分布的 **CDF**(累计分布函数)值(即曲线下方的面积)。
343343

@@ -361,7 +361,7 @@ $$
361361

362362
总结一下 VSSM 在第三步中的改进:
363363

364-
- 阴影图生成
364+
- 阴影贴图生成
365365
- 「平方深度图」:和普通的深度图并行计算,计算量取决于像素个数
366366
- 计算均值:MIPMAP 或 SAT(稍后介绍)
367367
- 运行时:
@@ -453,7 +453,7 @@ VSSM 中还未讲到的一块是如何加速计算任意范围(深度和深度
453453
<img src="images/lec3/34.png" width=50%>
454454
</div>
455455

456-
矩阴影映射的做法和 VSSM 极其相似,但它要生成关于 $z, z^2, z^3, z^4$ 的阴影图(4 张),并在执行遮挡物搜索和 PCF 期间恢复 CDF。
456+
矩阴影映射的做法和 VSSM 极其相似,但它要生成关于 $z, z^2, z^3, z^4$ 的阴影贴图(4 张),并在执行遮挡物搜索和 PCF 期间恢复 CDF。
457457

458458
!!! success "优点:能产生非常好的结果。"
459459

@@ -467,4 +467,110 @@ VSSM 中还未讲到的一块是如何加速计算任意范围(深度和深度
467467
</div>
468468

469469

470-
## Distance Field Soft Shadows
470+
## Distance Field Soft Shadows
471+
472+
???+ example "例子(距离场软阴影的效果)"
473+
474+
<div style="text-align: center">
475+
<img src="images/lec3/36.png" width=80%>
476+
</div>
477+
478+
479+
### Distance Function
480+
481+
先来回顾一下**距离函数**(distance functions)的概念。它是指在任何时刻给出到物体上最近位置的最小距离(可以是带符号的距离)。比如对于下图的字母 A,距离函数便是点到字母轮廓的最近距离,并且右图以可视化的方式呈现计算结果。
482+
483+
<div style="text-align: center">
484+
<img src="images/lec3/37.png" width=70%>
485+
</div>
486+
487+
???+ example "例子(对移动边界进行混合(线性插值))"
488+
489+
<div style="text-align: center">
490+
<img src="images/lec3/38.png" width=80%>
491+
</div>
492+
493+
- SDF == 0 => 边界
494+
- 可以看到,如果只是简单的线性插值,只能得到中间的灰色区域,而不会产生新的黑白边界
495+
- 但如果是对两幅图的 SDF 进行线性插值,还原后的图像的中间就有明显的边界了
496+
497+
实际上可以通过混合任意两个距离函数 d1, d2 来混合任意形状的物体:
498+
499+
<div style="text-align: center">
500+
<img src="images/lec3/39.png" width=90%>
501+
</div>
502+
503+
!!! info "注"
504+
505+
SDF 和**最优传输**(optimal transport)理论密切相关,建议课后学习一下。
506+
507+
508+
### The Usages of Distance Fields
509+
510+
距离场的用途有:
511+
512+
- 通过**光线行进**(ray marching)(球体追踪(sphere tracing))来执行光线和 SDF 的求交计算(ray-SDF intersection)
513+
- 背后蕴含了一个非常聪明的思想:**SDF 的值 == 周围的「安全」距离**
514+
- 因此每次在点 p 处只需行进 SDF(p) 的距离,这样保证不会和任何物体相交
515+
- 当 SDF 小到一定程度后(也就是说离物体足够接近时),或者行进很长一段距离后还是没有碰到物体时停止行进
516+
- 可以处理运动的物体,但不适合用在有能产生形变的物体的场景中(需根据形变程度重新计算)
517+
518+
<div style="text-align: center">
519+
<img src="images/lec3/40.png" width=60%>
520+
</div>
521+
522+
- 使用 SDF 确定(近似的)**遮挡百分比**(percentage of occlusion)
523+
- **SDF 的值 == 眼睛看到的「安全」角度**
524+
- 观察:更小的安全角度 <-> 更小的可见性
525+
526+
<div style="text-align: center">
527+
<img src="images/lec3/41.png" width=50%>
528+
</div>
529+
530+
531+
### Distance Field Soft Shadows
532+
533+
现在正式来看如何计算距离场软阴影:在光线行进阶段的每一步中计算来自眼睛的「安全」角度,并保留最小值。
534+
535+
![](images/lec3/43.png){ align=right width=40% }
536+
537+
<div style="text-align: center">
538+
<img src="images/lec3/42.png" width=50%>
539+
</div>
540+
541+
也许读者会想利用圆的切线来求解安全角度,这样的话计算公式便是 $\arcsin \dfrac{\text{SDF}(p)}{p - o}$。但在着色阶段中,人们通常希望能避免像反三角函数这样复杂的计算。因此实际上会用这个公式来算:$\min\left\{ \dfrac{k \cdot \text{SDF}(p)}{p - o}, 1.0 \right\}$。
542+
543+
- $\dfrac{k \cdot \text{SDF}(p)}{p - o}$ 用于近似表示反三角函数,加上 $\min$ 使该值不超过 1
544+
- $k$ 值越大,意味着安全角度很大,半影将更早被裁剪,因而让阴影变得更硬
545+
546+
???+ example "距离场的可视化结果"
547+
548+
<div style="text-align: center">
549+
<img src="images/lec3/44.png" width=80%>
550+
</div>
551+
552+
!!! success "优点"
553+
554+
- 快速
555+
- 应该说生成 SDF 比生成阴影贴图更快,运行时查询的时候两者速度应该差不多
556+
557+
- 高质量
558+
559+
!!! bug "缺点"
560+
561+
- 需要预计算
562+
- 需要大量存储,不过也有一些缓解措施
563+
- 使用 KD 树、八叉树等对空间划分,只去计算场景中较近区域的 SDF
564+
- 有人尝试过用深度学习方法压缩,但这样做反而增加解压的时间,因此不太可能在实际中得到应用
565+
566+
- 接缝处可能存在瑕疵
567+
568+
??? info "一个有趣的应用"
569+
570+
在 RTR 中实现了抗锯齿/无限分辨率的字符。
571+
572+
<div style="text-align: center">
573+
<img src="images/lec3/45.png" width=60%>
574+
</div>
575+
576+
GitHub 链接:<https://github.com/protectwise/troika/tree/master/packages/troika-three-text>

0 commit comments

Comments
 (0)