games202-6

环境光照下的阴影

即在渲染方程中考虑visibility,无法进行

1、环境光照相当于记录了每个方向的光照,可以认为每个方向上都有光源。此时着色可以看成多光源绘制,绘制阴影需要给每一个方向的光源生成shadow map,数量极其庞大。

2、visibility 项不能进行预处理然后采样,因为每个点的可见度都是不同的,其复杂度任意,难以通过预处理计算积分。且该项不好从渲染方程中拆出来。

目前,工业界的一般方案是选取环境中最亮的那个光源(例如太阳)或前几个光源生成阴影图,然后由此生成阴影。

傅里叶级数展开

对于任何函数,都可以通过常数项和增加更多的sin和cos项逼近。也就是sin和cos的线性组合,且这些sin和cos函数频率都不同(从低频到高频,这些sin cos函数叫基函数)。

image-20230721203450497

图像作为二维数据,可以将其频域显示出来即频谱(傅里叶变换)。频谱中心最低频,外部最高频。通过滤波留下图中低频的部分,再恢复成原图,可以发现图片变模糊了。同时,时域的卷积(模糊操作)=频域的乘积。

两个函数相乘并积分(如x函数和y函数相乘对x积分,不然积分出来的是一个值而不是一个函数)=卷积/滤波操作=频域上这两个函数对应的频谱相乘。这两个频谱只要有一个是低频,那么频域上乘积的结果就是低频的,即两个函数相乘并积分的结果是低频的,结果变化小平滑。结果的频率由这两个函数更低的频率决定。

一个函数可以表示成多个基函数的线性组合。使用不同的基函数(一系列函数组合)可以表示不同的函数。除了sin cos还有常用的基函数:1+x+x^2+x^3…

image-20230721205214199

Spherical Harmonics

一系列二维基函数,并且每一个函数都定义在球面上(可以理解为对方向的一个函数,三维空间中球面上的方向可以用两个变量表示。单位球上的一个点即为一个方向)。

SH是一系列二维函数,这些函数有不同的频率(每一行一个频率)。每一个频率有几种不同的函数(一行每一列)。l=0,第0阶的SH;l=1,第1阶的SH。每一阶的SH有2l+1个SH基函数,这些基函数编号从-l~l。 前n阶n^2个函数。(这些二维函数不进行二维傅里叶变换,把球展开成二维的图。因为经过很多操作后恢复到球面上球面上会出现缝,很适合直接用SH分析球面上的性质)

image-20230721210710588

现在给一个二维球面函数,要展开成SH的线性组合,前面的系数该为多少,这个求解的过程叫做投影。展开的任何一个基函数前面的系数如下(蒙特卡洛采样或者预计算)。关于为什么称为投影: 对于空间中一个向量,可以用(x,y,z)表示,xyz是该向量在三个轴上的投影/系数。xyz轴是基函数。求投影的方法是用向量点乘xyz轴(基函数)。函数相乘再积分也是点乘。

image-20230721214251335

可以看到l可以无限多。如果对于一个函数,只希望用前4阶进行表示,那么该函数保留的最高频率是l=3的频率,丢弃了更高阶的频率。一般选取前几阶,所有基函数都使用,而不会在每一阶挑个别几个。

结论:环境光贴图提供了渲染方程中的L项。由于环境贴图已知,所以L项是一项已知的二维球面函数。可以用SH基函数表示,系数是用原函数和某一个基函数积分。

对于漫反射环境光着色(不考虑阴影):

image-20230721222819046

L项是环境光球面函数。BRDF是定义在半球上非常光滑的函数。这两个函数驻点相乘并积分。L可以任意频率,BRDF(包含cos)相当于一个低通滤波器,只是用三阶SH就可以很好的恢复。可以看到当函数投影到l=3及之后系数基本为0,再次说明BRDF是低频函数。也就是不管环境光多复杂,与漫反射物体作用后看不到高频信息。因此L没有必要使用高频描述。

image-20230721223414984

如下用0、1、2阶函数表示环境光照照到漫反射物体的结果,可以看到光照用3阶表示(同BRDF)就可以与实际计算得到一样的结果。也就是光照没必要保留太多高频信息。

image-20230721224036531 image-20230721224128875 image-20230721224213422

结论:当待计算的物体是类似漫反射物体,则BRDF平滑,基本可以用少阶SH表示,则L也可以用少阶的SH表示,丢弃高频信息。

PRT

漫反射

对于一个着色点、环境光可以描述成入射光i的球面函数,visibility项可以描述成入射光i球面函数,对于brdf已知出射光o,入射光i为2维,也可以表示成球面函数。解积分值最直接的方法是将每个对应像素相乘再相加。假如一个纹理是64×64×6的大小,每一个着色点需要计算64×64×6次。并且每个点的visibility*max纹理不同,BRDF纹理也可能不同(本质还是多次采样 )。

image-20230721231102958
采用预计算和SH简化计算:

首先将渲染方程看成两部分,V和BRDF与L拆分成两部分。L可以用基函数表示,Vmax和B对于一个着色点不变,可以认为是一个着色点的性质。也就是在渲染之前可以先计算好VB。在确定了o和n之后,VB以及cos项总体是一个球面函数,可以用基函数表示。(也就是场景物体不能变,只要光源被预计算,光源是可以切换的;光源旋转后会有不同的预计算结果,但是SH会立刻得到旋转后的光源系数如何改变)

则在diffuse场景(考虑阴影):在漫反射场景下,BRDF是一个常数,可以取到积分外。将L变成基函数的表示形式系数为l(求系数的积分是在球面积分),交换求和和积分函数(此处可交换)。将系数l移到积分外。Vmax(0,n·i)是和L无关的项,简称light-transport。light-transport和基函数积分即light-transport球面函数投影到基函数的系数,该系数可以预计算(求系数的积分是在球面积分,所以渲染方程的积分域应该改成球面,因为下半球都为0所以不影响积分结果)。也就是说将light-transport这个二维球面函数用和L一样的基函数表示,计算系数是多少。则对于任何一个着色点的值,假设要用m个基函数,将L的m个系数和light-transport的m个系数对应相乘再相加,并将结果乘以常数BRDF。

(对于确定的着色点,可以将light-transport投影到任何基函数;场景中只有L改变,也就是li)

SH:

正交性:基函数投影到其他基函数结果为0

投影好计算

支持旋转,旋转原球面函数只需旋转基函数,线性组合不变。旋转后得到的函数不再是SH基函数,但可以由同阶的基函数的线性组合得到。也就是旋转某一个基函数,实际上是改同阶基函数的系数。所以可以打表记录旋转角度以及对应的组合。

使用阶数越多,越能逼近原始环境光(BFDR也要高阶)。

具体实现:

在path tracing的基础上,在L已知的情况下,使用SH和预处理而不是采样的方法计算着色点的渲染方程,减少因大量采样耗费的时间。

一、只考虑来自环境光的直接光照

不考虑光的多次弹射和间接光照,可以在光栅化(因为片段着色器不知道坐标系下场景的坐标情况因此无法计算弹射和间接光照)的基础上使用渲染方程。对于积分和渲染方程,需要知道L即光源位置(不考虑递归L)。对于多个点光源,可以将点光源方向的L相加;对于面光源可以采样;此处环境光下L已知。

此处积分是在整个球而不是半球积分。对于下半球,max=0,所以不影响计算。

1、计算环境光的SH系数(使用3阶SH,对于每个顶点环境光函数是相同的,因为有RGB三个通道,系数为vec3)。每个像素代表一个方向,对于单个SH计算系数:

L:图片像素对应的RGB SH值:由像素得到方向,通过归一化后的方向向量得到某一阶下某个SH的在该方向的值。 dw:通过像素大小计算在单位球上的投影面积 ∫:对每个像素执行上述操作。

2、计算light-transport的SH系数(使用3阶SH,对于每个顶点light-transport函数是不同的,因此每个顶点都要计算一个SH系数作为顶点属性,系数为float)。对于一个顶点的单个SH计算系数:f(x):(1)考虑阴影:visibility× max(N·wi,0)(2)不考虑阴影:max(N·wi,0)采样一个方向,通过顶点法线和生成光线向量判断是否有遮挡物计算f(x)的值(不能光栅化)。 SH值:通过采样得到的方向向量得到某一阶下某个SH的在该方向的值。 ∫:多次采样得到多个方向向量重复上述操作。

3、计算着色:将顶点着色器计算每个顶点的颜色值再插值到片元。因为在预计算时只知道顶点的属性(坐标法线),因此只预计算了每个顶点的light-transport的SH系数作为顶点属性,所以在顶点着色器计算顶点的着色再插值到每一个片段/或者将light-transport的SH系数传入片段着色器,经过插值后计算片段着色(L对于每个片段相同)。

二、考虑间接光照(即光线多次弹射)
image-20230726183745871

image-20230726183842491

三、SH旋转

image-20230726183852172

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码

请我喝杯咖啡吧~

支付宝
微信