阴影II(shadow II)------计算机图形学高质量实时渲染(四)

阴影II(shadowII)

在这里插入图片描述

结束阴影部分

A.Signed Distance Function(距离函数)

首先我们先来复习一下SDF,在101里我们知道,Distance Function就是空间中任何一点,到某个物体的最小距离。
在这里插入图片描述
signed的意思就是加入规定负数代表在物体内部,正数则表示在物体外部,这样不止定义了距离,还定义了方向。
在这里插入图片描述
SDF大多用再与几何之类的方向上,比如我有两个物体的SDF,我们将两个物体SDF进行Blend操作,从而得到一个新的SDF,也就得到了一个新的几何物体,因为当距离为0时,即可认为是物体的边界,SDF可以很准确的反应物体的边界。几何转换SDF的时候,可以很好地把几何进行过渡。

B.SDF的应用:

应用1. Ray Marching

RayMarching一般用于比如说是SSR(SSGI)中,在屏幕空间上求光线和物体交点的过程中。不过那个主要用的是Hi-Z来实现。

假设我们已经知道了场景的SDF,现在有一根光线,我们试图让光线和SDF所表示的隐含表面进行求交,也就是我们要用Sphere Tracing(ray marching)进行求交。

Ray marching 是一个很有趣且聪明的思想:
任意一点的SDF我们是已知的,因此在P0点时,我们以它的SDF(P0)为半径做一个圆(此处假设在2D内,如果在3D内则是一个球),在这个圆内无论是哪个方向前进,只要不超过半径距离,都不会碰见物体,是安全的。
因此我们可以利用这个特性不断地朝一个方向前进,以P0开始朝一个方向走SDF(P0)到达P1点,若仍与物体表面相距甚远,则以P1点为新起点继续走SDF(P1)到达P2点,假设此处P2点的SDF足够小,也就是代表离物体表面足够接近了,则进行求交操作。
如果在超一方向trace非常远的距离但仍然什么都没trace到,此时就可以舍弃这条光线,也就是停止了。
在这里插入图片描述

应用2. 生成软阴影

将安全距离的概念进行延伸,在任意一点通过SDF可以获得一个Safe Angle。
在这里插入图片描述

我们取点P为shading point往一方向打出一根光线,光线上的一点a,有一个SDF值SDF(a),也就是在a点以SDF(a)为半径所做的球或者圆内是安全的,不会碰到物体。

把shading point和面光源相连,所得到的安全角度越小,被遮蔽的可能性越高,就可以认为:

safe angle 越小,阴影越黑,越趋近于硬阴影。
safe angle 越大,就视为不被遮挡没有阴影,也就越趋近于软阴影。

因此我们需要知道的应是如何从ray marching中求出safe angle。
在这里插入图片描述
我们以O为起点,沿一个方向推进,仍然是ray marching的步骤,在p1点以SDF(p1)进行推进,其余点也是一样,此处主要是为了求safe angle,我们在起点o沿每个点的sdf为半径所形成的圆做切线,从而求出各个点的safe angle,我们最后再取出其中最小的角度作为总的safe angle。
也就是说我们在trace的每次过程中都求出一个safe angle,到最后进行相交操作时取最小的safe angle来用。

那么我们该怎么去计算这个角度?

从图我们可以知道,以p1点为例,从o点到p1的距离为斜边,sdf(p1)是直角边,因此我们用arcsin就可以直接求出safe angle了。
但是,arcsin的计算量其实是非常大的,因此再shader中我们不用反三角函数。
在这里插入图片描述
只要sdf长度除以光线走过的距离乘一个k值,再限定到1以内,就能得到遮挡值或者说是visibility,而k的大小是控制阴影的软硬程度。
在这里插入图片描述
我们从图中右半部分可以看出来,当k的值越大的时候,就越接近硬阴影的效果,也就是它限制了可能半影的区域。
k越小,半影区域越大,越接近软阴影效果。
k越大,半影区域越小,越接近硬阴影效果。

这个思想并不是去考虑一个在这里插入图片描述从而求出一个比值,在用这个比值作为visibility。

而是求出safe angle,安全角度越大,阴影越软,安全角度越小,阴影越硬。

结论:

SDF是一个快速的高质量的软阴影生成方法(比shadow map快是忽略了SDF生成的时间,但是在存储上的消耗非常大,而且生成SDF的花的时间也要很久,SDF是预结算,在有动态物体的情况就得重新计算SDF)。

IBL(image based lighting)

Shading from environment lighting
在环境光照下做一点的shading时是不用去考虑shadow的。
首先我们复习一下什么是环境光照:

在games101中我们知道,环境贴图就是在场景中任意一点往四周看去可看到的光照,将其记录在一张图上这就是环境光照,或者也可以叫做IBL(image-based lighting)这里我们认为看到的光照来自于无穷远处,这也就是为什么用环境光照去渲染物体时会产生一种漂浮在空中的感觉,因为光照来自于无穷远处。

通常我们用spherical map和cube map来存储环境光照。

如果已知环境光照,此时放置一个物体在场景中间,在不考虑遮挡时我们该如何去得到任何一个物体上任何一shading part的shading值呢?

首先要先来看rendering equation:
在这里插入图片描述

渲染方程定义只考虑来自正半球方向的光照, Li项是环境光照(IBL),后面的那一项是BRDF。

由于我们在这里不考虑遮挡,所以舍去visibility项,通用的解法是使用蒙特卡洛积分去解,但是蒙特卡洛需要大量的样本才能让的得出的结果足够接近,如果我们对每个shading point都做一遍蒙特卡洛,那样的话将会花费很多时间在采样上,太慢了。

(PS:一般来说shader中如果出来sampling的话是不会用于rtr中的,但是由于这几年技术的提升,使得sampling在rtr中也有了可行性)。

在这里插入图片描述
既然采样这么慢,那么如果我们不进行采样呢?

IBL基本思路:

由于我们不考虑visibility项,那么rendering equation就只是brdf项和lighting项相乘再积分。

BRDF又分两种情况:
1.brdf为glossy时,覆盖在球面上的范围很小,也就是small support(积分域)
2.brdf为diffuse时,它会覆盖整个半球的区域,但是是smooth的,也就是值的变化不大,就算加上cos也是相对平滑的。

在这里插入图片描述
此时应该想到了我们之前讲的近似公式:
在这里插入图片描述
由于brdf项满足accuary condition,即small support或smooth,从而我们将rendering equation的lighting项拆出让他变为:
在这里插入图片描述
闫神这里主要讲的是specular阶段。

The spilt sum:1st stage

把lighting项拆出来,然后将brdf范围内的lighting积分起来并进行normalize,其实就是讲ibl这张图给模糊了。

模糊/卷积就是在任何一点上取一片范围求出范围内的平均值,并将平均值写回到这个点上,用于滤波的核取多大取决于BRDF占多大,BRDF的区域越大,最后取得的图也就越模糊。

在这里插入图片描述
而这些模糊过的图是我们在进行rendering之前生成的,也就是pre-filtering,pre-filtering那个就是提前把滤波环境光生成,提前将不同卷积核的滤波核的环境光生成一系列模糊过的图(和MIPMAP相似)。

当我们需要时进行查询即可,其他尺寸的图则可以经过这些已生成的通过三线性插值得到。

之前提过,拆分就是为了做一个pre-filtering,那么做pre-filtering是为了干什么?
在这里插入图片描述
左图为brdf求shading point值时,我们要以一定立体角的范围进行采样再加权平均从而求出shading point的值。
右图为我们从镜面反射方向望去在pre-filtering的图上进行查询,由于图上任何一点都是周围范围内的加权平均值,因此在镜面反射方向上进行一次查询就等价于左图的操作,并且不需要进行采样,速度很快。

其实就是生成一个预滤波环境贴图。

The spilt sum:2nd stage

到此我们解决了拆分后的前半部分积分采样的问题,那么接下来我们处理BRDF项采样的问题:
在这里插入图片描述
接下来讲的方法并不是最优方法,现如今已经有更简单方便的方法了,但是本课我们主要是为了学习方法背后的思想。
在这里插入图片描述
我们仍然可以利用预计算来解决后半部分积分采样的问题,但是预计算的话我们需要将参数的所有可能性均考虑进去,但是比较多,包括roughness,color等。考虑所有参数的话我们需要打印一张五维乃至更高维度的一张表格,这样会拥有爆炸的存储量,因此我们需要想办法降低维度,也就是减少参数量从而实现预计算。
在这里插入图片描述
在microface brdf中,考虑的是菲涅尔项、阴影项以及法线项,由于此时暂时不考虑阴影,此处需要关注的是Fresnel term 和distribution of normals。
在这里插入图片描述
Frenel term可以近似成一个基础反射率R0和入射角度的指数函数。

法线分布函数(NDF)是一个一维的分布,其中有两个变量,一个变量定义的是diffuse还是gloosy,另一个是half vector和法线中间的夹角,可以近似成入射角度相关的数,这样就变成了3维的预计算。

(PS.在这里我们认为反射角,入射角,half vector可以用一个角θ代替)

至此我们有了三个变量:基础反射率r0,roughness α和角度θ,三维的预计算仍然是一个存储量爆炸的结果,因此我们还要想办法减少参数量。

所以我们通过将Schlick近似带入后半部分的积分中:
在这里插入图片描述
基础反射R0被拆出积分式,需要预计算的两个量就只有roughness α和角度θ,可以将预计算结果绘制成一张纹理,在使用时进行查询即可。
在这里插入图片描述
我们可以看到,最后产生的结果是十分满意的。
在这里插入图片描述
生成一张BRDF的LUT查找表。

课程问答:

  • 1.frenel项需要预计算吗?
    菲涅尔项被拆开了,避免了对变量的依赖性。
  • 2.这张预计算是固定的吗?
    是固定的。
  • 3.Microfacet在ggx中会多参数吗
    不会
  • 4.深度学习在实时渲染中有什么应用吗?
    深度学习在实时渲染中并不成功,太慢了。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值