Lightings

作者: 离原春草 | 来源:发表于2020-08-06 20:56 被阅读0次

1. 【Siggraph2020】Point Light Attenuation Without Singularity
这篇文章给出了对点光计算公式的修正算法,从而避免了在到光源距离接近于0时亮度趋近于无穷大的奇异值,这个算法相对于传统的直接在分母中添加常量c的做法,其进步之处在于为常量c添加了物理意义,使得取值更为精准。下面给出相关推导过程:
首先,基本的采用BRDF的光照反射计算公式给出如下:
L_o(\omega_o) = \int_{\Omega} L_i(\omega_i)f_r(\omega_o, \omega_i)cos\theta d\omega_i
而如果我们只考虑点光源的话,那么这里的积分就可以直接收缩为一个点的输入,那么就有如下的公式:
L_o(\omega_o) = I V(\omega_i)f_a(d)f_r(\omega_o, \omega_i)cos\theta
其中V(\omega_i)为光源的可见性函数,d对应的是光源到像素的距离,而f_a(d) = \frac{1}{d^2}为点光的衰减函数。我们可以看到,点光衰减函数在距离d趋近于0的时候,会接近于无穷大,从而出现一个光照的奇异点,虽然这就是点光的基本特性,但是由于点光本身就是一盏虚拟光源,因此这个结果并不是渲染所需要的,为了消除这个奇异值,我们尝试换个角度来思考问题,比如我们将点光看成是一个带有一定半径的球面光源(比较符合实际),那么此前的反射光照公式就变成了如下的形式:
L_o(\omega_o) = \frac{1}{\pi r^2} \int_{\Omega} V(\omega_i)f_r(\omega_o, \omega_i)cos\theta d\omega_i
如果球面足够小,上述公式可以近似为如下公式:
L_o(\omega_o) \approx \frac{1}{\pi r^2} f_r(\omega_o, \omega_i)cos\theta \int_{\Omega} V(\omega_i) d\omega_i

而上述公式中的积分部分按照上面的示意图,可以得到结果为(相当于求取球面上的面积,先沿着半径方向积分,再沿着圆周积分,参考Wiki):
\int_{\Omega} V(\omega_i) d\omega_i = \int_0^{2\pi}d\theta\int_0^{\alpha}sin\phi d \phi = 2\pi(1-cos\alpha)
接着可以得到
f_a(d) = \frac{2\pi(1-cos \alpha)}{\pi r^2}
根据三角函数的关系,可以转化为:
f_a(d) = \frac{2}{r^2}(1-\frac{d}{\sqrt{d^2+r^2}})
这个公式需要满足一定的条件,比如d >> r等,此外当r趋近于0的时候,利用泰勒展开,上面的公式可以收缩为
f_a(d) = \frac{1}{d^2}
跟点光源计算公式完全一致,而我们在使用点光源的时候,为了避免奇异点,通常会在分母中加一个常量c:
f_a(d) = \frac{1}{d^2 + c}
如果我们取d = 0,那么此时就有
f_a(0) = \frac{1}{c} = \frac{2}{r^2},

c = \frac{r^2}{2},最终我们得到:
f_a(d) = \frac{1}{d^2 + \frac{r^2}{2}}

相关文章

  • Lightings

    1. 【Siggraph2020】Point Light Attenuation Without Singular...

网友评论

      本文标题:Lightings

      本文链接:https://www.haomeiwen.com/subject/vgitdktx.html