Lecture 3-4 Soft Shadow
Recap of Shadow Mapping - 点光源
- 从“Light”处看向场景,生成场景关于光源的深度图,即Shadow Map;
- 从相机处看向场景渲染画面,利用Shadow Map判断像素是否在阴影中。
Feature:
- 基于二维图像的算法,而不需要三维几何场景
- 使用透视投影后Z值或透视投影前实际距离生成深度图皆可,Shadow Map与阴影生成时的深度判定方式一致即可
Problem
Self occlusion 自遮挡
Shadow Map的每一个像素记录同一深度,形成下图现象。在单个/行像素采样处,形成尺寸为像素宽高的遮挡面。
解决方案:在反射表面邻近区域不计算遮挡。不计算区域Light长度(Bias)由Light与反射表面法线夹角决定。(Light垂直于表面时不产生自遮挡问题)。——带来新问题:丢失遮挡关系。
Detached shadow 由解决自遮挡的Bias不计算带来的阴影残缺问题。
工业界无法彻底解决该问题,通过找到合适的Bias值减少视觉问题。
学术解决方案:Second-depth shadow mapping
- 存储第一深度和次级深度(离得第二近的表面距离),取中间值作为深度判断的值。
- 存在问题:要求所有物体watertight(有正反面);计算量过大。
- 实时渲染不相信复杂度,只相信绝对速度!因此工业界不适用。
Aliasing 采样
The math behind shadow mapping
微积分中常见的不等式:
An important approximation:
其中
该式何时较准确:
- 积分域较小时
在积分域内变化不大(Smooth)
Recall:Rendering Equation with Explicit Visibility
何时准确:
- 点光源/方向光源(积分域小)
- Diffuse/面光源(其中一个积分函数平滑)
Ambient Occlusion 环境光遮蔽中将再次用到类似的约等式
PCSS: Percentage Closer Soft Shadows
PCF: Percentage Closer Filtering
- [ For anti-aliasing at shadows’ edges - Not for soft shadows ]
- Filtering the result of shadow comparisons
[Solution]
- 根据Shadow Map判断像素是否在阴影中:不判断一个像素,判断对应像素周围的一圈像素(如7*7网格)
- 得到该组像素判断的平均值,赋给中心像素(原判断像素)
- 计算量?PCSS时一并解决
- 将Filter范围再放大得到软阴影?!
PCSS
软阴影:近处锐利,远处模糊 —— Filter Size <-> Blocker Distance
Block Depth: Average block depth 在一定范围内,一个Shading Point被遮挡的平均深度值
Complete algorithm
- Blocker search : Getting the average depth in a certain region (视面光源中心为点光源生成Shadow Map)
- Penumbra estimation : Use the average blocker depth to determine filter size
- Percentage Closer Filtering
Blocker search的范围(得到Average block depth的方式)如何确定?
取固定范围,如5*5
[Better] 取决于光源面积和光照接收面到光源的距离
开销巨大:下节课解决
A deeper look at PCF
The math behind PCF: Filter/Convolution
- PCF并不是对Shadow Map的滤波
- PCF也不是对结果图像做滤波
More about PCSS
[Blocker Search] and [PCF] is slow to look at every texel.
- [Blocker Search] 随机取样 => Noise
- [PCF] Filter范围过大,随机采样 -> 图像空间降噪
Variance Soft Shadow Mapping
- Fast blocker search and filtering
[ Filter ] PCF:根据正态分布可估计 Percentage Closer Value 正态分布由均值mean和方差variance定义
- Mean
- Hardware Mipmaping 但只能正方形
- Summed Area Tables (SAT)
- Variance
- 另一张“Shadow Map”记录深度的平方,称为“Square depth map”
由此得到正态分布图,求得CDF(x) of the Gaussian
PDF即可(即0-x的积分)。
该积分没有解析解只有数值解,可通过高斯分布积分表Error
Function得到CDF值。在cpp
中使用erf()
求数值解,但计算仍较复杂。
因此引入切比雪夫不等式估计值:
总结 + Shadow map generation + “Square depth map” + Runtime + Mean of depth in a range: O(1) + Mean of depth square in a range: O(1) + Chebychev: O(1) + No samples / loops needed + Perfectly ? 改变视角需要重新生成map 产生较大开销 GPU解决起来速度非常快
[ Block Search ]
Target: The average depth of blockers ( texels whose depth z < t,
)Chebychev Approximation:
Approximation:
MIPMAP and Summed-Area Variance Shadow Maps
Recall: MIPMAP
- fast, approx., square range queries
- 非
方形区域,需使用线性插值 - 不精准,限制多
SAT (Summed-Area Table)
in 1D: 第
位存储 的和[0] = Arr[0]; SATfor(int i = 1, i < n, ++i) { [i] = SAT[i-1] + Arr[i]; SAT} //Sum of a to b float sum(int a, int b) { return SAT[b] - SAT[a-1]; }
in 2D: 第
位存储 的矩形区域和// m * n for(int i = 0, i < n, ++i) { [i][0] = Arr[i][0]; SATfor(int j = 1, j < n, ++j) { [i][j] = SAT[i][j-1] + Arr[i][j-1]; SAT} } for(int j = 0, i < n, ++i) { for(int i = 1, j < n, ++j) { [i][j] += SAT[i-1][j]; SAT} } //Sum of a to b float sum(int a, int b) { return SAT[a-1][b] + SAT[a][b-1] - SAT[a-1][b-1]; }
Moment Shadow Mapping
VSSM Problem: 遮挡物简单情况下,遮挡深度分布非正态/不符合切比雪夫估计 ,估计值不准
- 与实际值相比较暗:视觉无影响
- 与实际值相比较亮:漏光(Light Leaking,工业界也有称Light Bleeding)
解决分布描述不准方法——引入高阶矩(Moments)
- 简单理解为“
即 的 阶矩” - 使用前
阶矩的组合( )可以描述一个具有 个“台阶”的阶跃函数 - 可视为一种展开,将原函数展开为前
阶矩的线性组合 - 在MSM中,前4阶矩可较好描述遮挡深度分布,在使用VSSM的想法计算所需值(可在Blocker Search和PCF环节使用该方法)
Distance Field Soft Shadows
Distance Field / Distance Function: Minimum distance to the closet location on an object SDF(Signed Distance Field) 是较好的混合方式,比线性插值得到结果更平滑连续——[ 最优传输理论 ]
Usages:
Ray marching (Sphere Tracing) 在某一点,作SDF值(距离物体的最小距离)为半径的球,则球体内任意方向发射光线均不与物体相交,将该半径定义为“安全距离”(safe distance)。则光线可以朝原方向走该半径长度的距离,得到新的点和SDF值,同理迭代。直到沿着同一方向与物体距离足够小,或光线路径过长(认为无物体与之相交)时停止追踪。
Soft Shadows 类Ray Marching,对每一根光线,算出”安全角度”(safe angle)。(光线上所有点的SDF值的最小值为半径,该点为圆心作圆,与光线发射点两条切线的夹角)
优势:快
局限性:SDF的计算量、存储量,以及物体运动后重新计算的复杂度。(对多个物体的SDF,取最小值即可。)and some artifact
misc:利用SDF在实时渲染中生成矢量字符