zoukankan      html  css  js  c++  java
  • 《CSM and PCF》

    在进行阴影绘制的时候,除了blur整张shadow map之外,实现软阴影的方法还有CSMPCF

    CSM:

    CSMCascaded Shadow Map)即级联shadow map,又称作PSSM,它的做法是把相机从近裁剪面到远裁剪面分割成N个子视锥,每个视锥渲染一张shadow map

    一般而言,级联shadow map的几级大小是一样的,比如四级,可以在整张shadow map中分成四份,只是一级的shadow map里面的可视区域最小,阴影边缘锯齿也最不明显;第四级的shadow map可视区域最大,用它做出来的阴影的边缘锯齿也就最明显,但是由于使用到这一级的shadow map的物体都是比较远的物体所以可以这种效果。

    在分级的时候,比如分4级,原来相机只有一个远裁剪面,现在会分成4个,可以进行线性等分,也可以不等分:

    下图中,C0是近裁,Cm是远裁,Ci代表分割线,假如我们想要分割出N个子视锥,那我们就需要求出N-1Ci 
     

    通用算法是: 

    使用混合因子λ将平均切分和指数切分融合起来。 

     

    其中,指数切分公式是: 

    平均切分的公式是: 

    其中,n为近裁,f为远裁,i为切分线,m为子视锥总数。 

    代入最上面的公式,就能得到最终的切分公式。

    利用级联CSM的算法实现shadow map,生成级联的shadow map之后,后面的步骤即和传统的shadow map原理相差不大,不同的是,在传统的shadow map算法中,将当前pixel的坐标转换到light space后,等到的深度值仅仅和唯一的一张shadow map进行比较,现在,在级联shadow map的算发现,是有多张shadow map的,应该根据之前在light space中得到的深度来判断应该使用哪张级联shadow map中的那个,再进行深度比较,其中要注意UV的偏移不要采样到错误的shadow map中的像素,得到错误的比较结果,导致阴影效果出问题。

    关于一些CSM的优化;如果camera不动,角色在场景中走动,穿过两级shadow map的时候会发现阴影效果有明显改变,为了解决这种问题,可以让两级shadow map之间有重叠部分,比如重叠20%,然后对两张shadow map产生的阴影进行混合,这样的好处是完成了两级阴影效果之间的平滑过渡,但是坏处是发现当前pixel的深度位于light space的两级视锥之间的时候需要采样两张shadow map,具有额外的矩阵计算和采样消耗。

    SDSM:

    仅仅按照以上的CSM算法,会在视觉上有一些问题,主要有两个缺点。第一个是,CSM阴影效果影响很大的地方是光锥的集中程度。如果光锥需要包裹整个视锥,那么即便视锥的近平面上有面墙挡住了整个视野,光锥仍然不能集中到可见的pixel上。有一个优化方法是根据视锥内物体的AABB来提高光锥的集中效率,但如果遇上上面说的那面墙,情况并不会得到改善。另一个缺点是,决定区域划分的时候有一个参数,通过对它的调整可以改善近距离屈于或者远距离屈于的阴影质量,但不能两全其美。

    以上两个缺点,I3D2011上的Sample Distribution Shadow Maps可以用很很低的代价同时解决掉这些缺点,在最大程度上优化shadow map上sample的分布。

    另外针对于以上缺陷,可以使用SDSM方法实现,它能够根据可见pixel来动态分配区域划分,完全解决掉这两个问题。

    CSM的两个缺点实际都来自同一个根源:光锥区域是根据视锥的大小,而不是可见pixel的范围来调整。这里所说的pixel范围涉及到两个方面。第一是pixel在view space的深度范围,这会影响到区域的划分。另一个是pixel投影到light space的坐标范围,这影响到scale和bias的计算。很明显最佳情况是,shadow map的sample分布在所有可见pixel上,其他地方不浪费。而这两个方面都可以很简单地通过场景的depth texture得到。

    具体的SDSM算法可以归纳为:

    1.渲染一遍场景,得到depth texture。

    2.统计depth texture,得到最大和最小的depth。

    3.把depth的范围根据log的距离分布平均切成几个区域。

    4.从pixel的depth求出view space position,投影到light space,得到该区域的scale和bias,组成crop matrix乘到projection matrix之后。

    5.对每一区域都生成一张shadow map。

    6.在使用的时候,根据像素在view空间的位置确定自己是在哪个区域,以选择shadow map。

    SDSM仍然是一种CSM。总体来看,SDSM只是不通过光锥,而是通过可见pixel来划分区域和计算crop,这就解决了PSSM的第一个缺点。另外,由于深度是自动划分的,也就不会存在远近不能两全的缺点,也不需要一个额外参数来手工调整。所以PSSM的两个大缺点在SDSM里都不存在了。

    从这里看出,整体程序升级到SDSM不需要改变太多。由于depth texture在deferred rendering里面是必须的,所以1步骤是基本已经有了。对于forward rendering而言,pre-depth也是常用的。 

    PCF:

    PCFPercentage Closer Filtering的缩写;传统算法里,在shadow map里面采样出来的值和depth value进行比较的时候二者是一一对应的,在PCF算法中,可以对shadow map的周边进行采样,然后都和depth value进行比较,比如采样shadow map4次,每确定这次采样处于阴影中就为最终计算的值累计0.25,这样最终得到的值的可能性是0.00.250.500.751.0,该值用于与阴影颜色相乘,以此来决定该pixel处于阴影的程度,实现软阴影效果。

    参考:http://www.klayge.org/2013/05/07/%E5%A4%A7%E8%8C%83%E5%9B%B4shadow-map%EF%BC%88%E4%BA%8C%EF%BC%89%EF%BC%9Asdsm/

  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/DeanWang/p/7143741.html
Copyright © 2011-2022 走看看