一、作业描述
先渲染出模型,然后实现硬阴影,再实现PCF(Percentage Closer Filter) 和PCSS(Percentage Closer Soft Shadow)。
二、解决方法
代码来自参考引用,这里不贴了。
1、 投影变换
坐标的相对位置不变,光线是平行的,将物体变换到 [ − 1 , 1 ] 3 [-1,1]^3 [−1,1]3的立方体中(即坐标范围为[-1,1])。
M
o
r
t
h
o
=
(
2
r
−
l
0
0
−
r
+
l
r
−
l
0
2
t
−
b
0
−
r
+
b
r
−
b
0
0
2
n
−
f
−
n
+
f
n
−
f
0
0
0
1
)
M_{ortho}=\left(\begin{matrix} \frac{2}{r-l}&0&0&-\frac{r+l}{r-l}\\ 0&\frac{2}{t-b}&0&-\frac{r+b}{r-b}\\ 0&0&\frac{2}{n-f}&-\frac{n+f}{n-f}\\ 0&0&0&1 \end{matrix} \right)
Mortho=⎝⎜⎜⎛r−l20000t−b20000n−f20−r−lr+l−r−br+b−n−fn+f1⎠⎟⎟⎞
M
p
r
e
s
→
o
r
t
h
o
=
(
n
0
0
0
0
n
0
0
0
0
n
+
f
−
n
f
0
0
1
0
)
M_{pres \rightarrow ortho}=\left(\begin{matrix} n&0&0&0\\ 0&n&0&0\\ 0&0&n+f&-nf\\ 0&0&1&0 \end{matrix} \right)
Mpres→ortho=⎝⎜⎜⎛n0000n0000n+f100−nf0⎠⎟⎟⎞
M
p
r
e
s
=
M
o
r
t
h
o
M
p
r
e
s
→
o
r
t
h
o
M_{pres}=M_{ ortho}M_{pres \rightarrow ortho}
Mpres=MorthoMpres→ortho
M
p
r
e
s
=
(
2
n
r
−
l
0
l
+
r
l
−
r
0
0
2
n
t
−
b
b
+
t
b
−
t
0
0
0
n
+
f
n
−
f
−
n
f
n
−
f
0
0
1
0
)
M_{pres}=\left(\begin{matrix} \frac{2n}{r-l}&0&\frac{l+r}{l-r}&0\\ 0&\frac{2n}{t-b}&\frac{b+t}{b-t}&0\\ 0&0&\frac{n+f}{n-f}&-\frac{nf}{n-f}\\ 0&0&1&0 \end{matrix} \right)
Mpres=⎝⎜⎜⎛r−l2n0000t−b2n00l−rl+rb−tb+tn−fn+f100−n−fnf0⎠⎟⎟⎞
Vertical Field of View(fovY) 是垂直可视角度
Aspect ratio是宽高比
-将fovY 和aspect转换成l,r,n,t
因为Z是取负方向的,所以t为负数
结果如下图:
2、硬阴影
2-pass算法:
1、先从光源出发,记录其所能到达的最浅的深度,保存为shadowMap
2、再从相机位置出发,根据shadowMap去渲染出场景(小于shadowMap中的深度才能被看到)。
缺点:会有走样和自遮挡。
shadowCoord是当前节点在光源坐标系下的坐标[-1,1],需要将坐标范围调整为[0,1],来进行贴图采样。
贴图采样后,通过unpack获取到当前深度,与shadowMap中的深度才能被看到。
结果如下:
但是会存在自遮挡现象:
原因是shadowMap记录的深度是不连续的,每个采样点都表示一个区域的深度值,但是每一个区域的每一个点的实际深度是不一样的。跟光源位置也有关系,光源从正上方照射下来,误差最小,往左右偏移,误差变大。
通过添加移动量解决。
结果如下:
但是,会存在课上老师提到的脚部阴影消失的问题。
结果如下图:
3、PCF
将当前节点的深度与shadowmap上一个范围内的深度进行比较,大于为0,小于为1,最后求平均,也可以加权求平均。(类似二维图像处理的均值滤波)。
用于抗锯齿。
结果如下图:
4、PCSS
阴影与遮挡物的距离有关,近的偏硬,远的偏模糊。
根据上图可以得到一个相似三角形公式:
第一步 取一定范围里的点,累加遮挡点的深度,取平均深度
d
B
l
o
c
k
e
r
d_{Blocker}
dBlocker
第二步,根据相似三角形原理,根据以上公式,利用
d
B
l
o
c
k
e
r
d_{Blocker}
dBlocker计算出penumbra,利用penumbra计算出filtersize
第三步,同PCF。
结果如下图:
三、总结
这个作业断断续续花了很久的时间,做个笔记记录一下。有些东西101学过,但是没有实践过,没有理解。有必要记录一下,算是加深理解。
很多东西老师课程上讲了,但是做作业的时候没有去回顾,等到参考别人的做完后,写笔记去回顾才发现都讲过。实现起来还是蛮难的。这个笔记也写了很久,在写的过程中也会产生很多疑问,查了很久。
四、参考和,引用
[1] GAMES202-高质量实时渲染
[2] 知乎:GAMES-202 高质量实时渲染学习笔记 - 1- 硬阴影与软阴影
[3] CSDN:GAMES202 作业1解答
[4] 知乎:7.2 Shadow Map
[5] GAMES202-高质量实时渲染PPT
[6] 知乎:自适应Shadow Bias算法