目录
一 为什么要使用PCF技术?
二 算法
三 效果
本章节源码点击此处
一 为什么要使用PCF技术?
- 在阴影改善这篇文章最后我们发现阴影的边缘锯齿化很严重,对于这种问题主要是因为采样精度的问题
- 对于不同片段有可能从深度纹理中采样到了同一个纹理像素,这就导致形成了明显的边缘,看起来就像是锯齿或阶梯状的过渡,即所谓的“锯齿边”
- 可以这样理解,所有这些相邻的屏幕像素在计算阴影时,实际上查看的是深度贴图上的同一个深度值。
- 比如现在有一个片段,假象把他分为两部分:第一部分采样和第二部分从纹理中采样获取到的深度值是一样的,但是它的当前实际深度值不一样,这就导致一部分不能通过阴影计算而一部分可以通过阴影计算公式。
原理
- PCF通过在每个像素周围进行多次样本采样,并对这些样本进行平均来实现阴影边界的模糊效果,从而平滑阴影的边缘,避免了由于阴影贴图分辨率限制导致的硬阴影边缘。所有的周围像素的结果结合在一起,进行平均化,我们就得到了柔和阴影。
作用
- 能够较号的改善阴影贴图的边缘锯齿问题
- 主要是软化阴影边缘,让阴影边缘开起来不是那么的生硬,而是变得比较柔和、
二 算法
- 首先我们要进行对每个取样点的像素的多个像素点进行平均取样,那么就需要先获取像素点的大小
vec2 texelSize = 1.0 / textureSize(shadowMap, 0);
- 然后我们需要获取每一个采样点的阴影结果,并对其进行累加后求平均值
- 比如这样如果这个像素周围的8个点包括自己都是阴影那它取平均值后就还是阴影,如果这9个采样点中只有2个点是阴影,那么它的阴影结果就是2/9阴影。这样阴影的效果就会变得比较柔和。
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(depthMap,0);
for(int x = -1; x <= 1; ++x)
{
for(int y = -1; y <= 1; ++y)
{
float pcfDepth = texture2D(depthMap,projCoords.xy + vec2(x,y) * texelSize).r;
shadow += curDepth - bias > pcfDepth ? 1.0f : 0.0f;
}
}
shadow /= 9.0;
三 效果
- 这样我们看到的阴影效果就比较柔和了而不是和最开始一样生硬。
- 当然这个效果可以根据采样点的多少来进行调整,也可以适当调整采样纹理时的分辨率,但这个损失的性能会更大,最好是使用PCF技术来进行调整采样点。