Why:这篇文章干了一件什么事呢?他提出了一个改良版的微表面模型。传统的微表面模型认为物体表面有无限个facet,因此BRDF是平滑的。但是如果我们要渲染glittery的表面,很明显是有很多法线上的突变的,才会形成其特有的闪烁现象,这是平滑的BRDF所不能模拟的。我们当然可以坚持用平滑的BRDF,然后用高分辨率的法线贴图来储存所有的facet,但是这种方法不仅消耗大量资源,而且在窄角度光照的情况下会产生一些反常的亮点。我们在这篇文章中提出的是一个更加兼容的模型:既可以用于渲染glittery的表面,也可以用于渲染光滑的表面。
What:如标题所示,这个改良模型被称为Discrete Stochastic Microfacet Model。Discrete指的是:我们不像传统的微表面模型那样使用连续的BRDF表达式,而是认为facet是有限的。我们将微表面模型的BRDF公式的法线分布项定义成离散形式,得到离散的BRDF。Stochastic指的是:我们不采用事先将所有的facet信息(包括法线方向和在物体表面上的坐标
)储存起来的方法,而是在查询的过程中实时随机生成这些facet。
How:
1. Multiscale BRDFs
这部分我们的目的是得到离散的微表面BRDF表达式。
传统的微表面BRDF的反射情景是:光线从一个方向入射,打到某一个位于点
的facet,然后向一个
方向出射。我们如果仍然使用这样的情景,就必须要在计算每个点的着色时都要遍历所有的facet,确定这个点是不是一个facet。为了避免这样做带来的巨大开销,我们做了一种近似:不再考虑一个点
的着色,而是考虑一个有限区域
的着色;不再考虑一个方向
的出射,而是考虑一个以
为轴的立体角
范围内的出射。这就相当于对实际反射位置和出射方向做了一个模糊。
就是一个像素在该表面的投影,而
是我们规定的一个角度。
是半程向量的范围,也就是这片区域所有facet的法线分布。我们可以将
和
做笛卡尔积形成的四维空间(
和
坐标各有两个变量)看作facet的查询范围。我们需要求出这个查询范围的平均BRDF表达式,也称为multiscale BRDF。
如上文所述,我们将微表面模型的BRDF公式
中的一项定义为形如
的离散形式。其中表示对在
上的
保留所有
的位置,
同理。为了得到multiscale BRDF表达式,我们从标准BRDF决定式出发
分别对在上的
和在
上的
积分,并除以
,得到这一区间的平均BRDF
最后,将(3)代入(2),得到
实验证明,对于查询区域中每个facet,主要区别在于项。因此我们可以将除了
的其它带有
上标的项全部去掉,相关量用中心点的值代替,得到
其中
这就是我们需要的离散BRDF函数,接下来的工作就是对于每个查询范围,找到在其中的所有facet,代入公式计算BRDF即可。
2. Reflection Geometry
为了便于在查询算法中划分区域,我们有必要先考察随
和
变化的规律。
在这一部分接下来的内容中,我们暂时用表示法线,并假设
是
中的一个方向。
由几何关系可得
变形得到
根据线性代数的知识,形如的方程是圆锥曲线。如果矩阵
是正定矩阵,则
在椭圆上;如果
是不定矩阵,
在双曲线上。考虑到变量
是方向向量,我们通过类比可以猜出
在球面圆锥曲线内,这里暂时不做证明。为了方便确定矩阵
是否正定,我们希望求出
的特征值,因此我们将方向向量坐标变换为直角坐标
原不等式变为
特征值为正,因此
轨迹取决于
的正负。当
时
的轨迹是圆(b);随着
和
夹角增大,轨迹变为椭圆(c);当
时
的轨迹开始变为双曲线,直到
和
反向(d)。
3. Hierachical Traversal
这部分我们的目的是得到在上述查询范围中查询facet个数的算法。
Algorithm 1是一个标准的广度优先算法,最后返回的是count/N,也就是查询区域内的facet占根节点facet的比例。我们定义根节点为单位半球面和纹理空间的笛卡尔积,即。每个节点包括一个纹理空间的包围盒和方向空间的球面三角形,每个节点有四个子节点。纹理空间每次被划分为均匀的四个包围盒,方向空间每次通过将三角形各边中点连线来一分为四。每次划分选择一个空间进行划分,选择纹理空间进行划分的条件为
式(11)中的期望是由该算法的一个事先的运行得到的。
我们先盖住11、12行。每次迭代中,算法从队列中pop出一个4D的树节点,并检查与查询区域的相交情况。如果节点内没有facet或与查询区域不相交,直接返回;如果整个节点都在查询区域内,将facet个数|node|加入count中;如果节点有一部分在查询范围内,用split()获得其子节点,并将所有子节点push进队列中等待进一步查询。
主要部分完成后,我们再来看11、12行加入了什么。很显然,我们上面介绍的算法会把所有的facet都数出来,然而实验证明在某些情况下我们并不需要这么精确,因为我们最后返回的实际上只是一个总数(或者说比例)。如果节点和查询区域部分相交,且facet的分布是均匀的,我们可以通过二项分布模拟真实分布,用二项分布的期望代替查询出的个数。假设每个facet落入查询区域的概率是,根节点facet个数为
,期望
就是我们要找的facet数。我们要求这样的近似使用的条件是:二项分布的标准差小于某个比例
,
由实验得出,即
。根据实验结果,取
时依然可以得到较好的结果。概率
我们通过相交区域与整个节点的4D体积之比来得到。
接下来我们要解决上文中提到的查询范围和节点的求交、求重叠面积如何实现的。纹理部分是简单的平面上的相关操作,不再赘述。对于方向空间,我们要判断一个球面圆锥曲线和球面三角形
的相交。如果
和
不相交,则
与
是包含关系或没有重叠,具体谁包含谁通过从一个曲线内取一个点检测其是否在另一个曲线上判定,如果两个判定都没有包含关系,就是没重叠。判断一个点是否在
中,用式(8);判断一个点是否在
中,用三次plane-point sidedness test。接下来我们要求出球面弧和球面圆锥曲线的交点:球面弧和球面圆锥曲线相交当且仅当两端点连线形成的弦与曲线相交,即
最后,我们要计算球面上一个三角形与圆锥曲线的重叠面积。球面上的面积计算非常困难,但是注意到我们只有在式子(10)满足的情况才会用到这样的面积计算。这种时候球面上的图形弯曲的程度非常小,可以用平面上这两种图形相交的结果近似代替,用Stroke’s theorem可以求解。
4. Stochastic Process
这部分我们提出不需要事先储存所有facet,而是在查找过程中动态生成。同时需要注意,这种生成方法必须在时间上必须具有连续性,否则可以想象会有严重的抖动。
我们每次将根节点一分为四,每一次划分都满足以概率向量
和根节点facet数
为参数的多项分布。每次划分的时候,我们都对这个多项分布进行采样,得到子节点的facet数。这样的方法就可以保证每一级划分出来的子节点facet数之和都等于
,并且不需要事先存储所有facet。因为facet在半球上的分布是不均匀的概率向量
不再等于
。要想得到新的
,必须在划分出来的四个子三角形上对平滑的微表面分布函数
积分。但是,解析地算出这个积分非常困难,所以我们这里采用了数值的方法。渲染开始之前,先调用integrate函数对微表面分布函数用中点法和高斯积分法分别积分。当两个结果差异高于一定值时,算法递归调用,并返回四个子三角形的积分和。我们将每个球面三角形都做这样的积分,得到一个三角形内facet个数的哈希表。渲染过程中,对于近似均匀分布的三角形,我们可以直接用一点高斯积分算;对于非均匀分布的,一定可以在之前的哈希表中找到其结果。