半球上的Hammersley
源作者:Holger Dammertz
一组关于如何在2D中使用Hammersley点集以在着色器程序中快速实用地生成半球方向的笔记。如果你发现任何错误或有意见,不要犹豫,请联系我或在我的博客上留言。
1. 概述
在编写与光照有关的着色器时,人们经常需要一些以表面法线为方向的半球方向。通常的做法是预先计算这些方向,并将它们存储在一个静态/统一的数组中,或者创建一个包含这些方向的可查询的纹理。在这一页,我研究了如何在着色器中直接使用2d中的Hammersley点集来快速计算合理的分布方向。当然,这个点集并不局限于取样方向,它还可以用于阴影图过滤、屏幕空间环境遮蔽(SSAO)或其他任何需要2D取样模式的应用。
二维的Hammersley
点集是最简单的低差异序列之一,在计算机图形中的伪蒙特卡洛(Quasi Monte Carlo)集成方面有许多可能的应用。对各种不同的伪蒙特卡罗序列的总体概述可以在Niederreiter [niederreiter92]的书中找到。例如在 [wong97]中可以找到明确使用Hammerysley点集
进行球体采样的方法。
下面我首先简要介绍一下如何从数学上构造Hammersley点集
,然后展示这些点在2d中的样子,以及它们在映射到半球时的样子。之后,我向你展示了一个可以直接插入GLSL着色器中的实现(或者很容易翻译成任何其他语言)。
2. Hammersley点集
我们考虑一个点集 P N = { x 1 , . . . , x N } P_N=\left\{ x_1,...,x_N \right\} PN={
x1,...,xN} 与点的数量 N ≥ 1 N≥1 N≥1在二维单位面积上 [ 0 , 1 ) [0,1) [0,1)(原本中关于此处均使用左闭右开)。Hammersley点集
H N H_N HN,在2D中,现在被定义为
H N = { x i = ( i / N Φ 2 ( i ) ) , f o r i = 0 , . . . , N − 1 } ( 1 ) H_N=\left\{ x_i=\left( \begin{array}{c} i/N\\ \varPhi _2\left( i \right)\\ \end{array} \right) ,for\,\,i=0,...,N-1 \right\} \,\, \left( 1 \right) HN={
xi=(i/NΦ2(i)),fori=0,...,N−1}(1)
其中 Φ 2 ( i ) \varPhi _2(i) Φ2(i)是Van der Corput序列
Van der Corput
序列的想法是在小数点处镜像 i i i的二进制表示,以得到区间[0,1]中的一个数字。
Van der Corput
序列 Φ 2 \varPhi _2 Φ2的数学定义如下:
Φ 2 ( i ) = a 0 2 + a 1 2 2 + . . . + a r 2 r + 1 ( 2 ) \varPhi _2\left( i \right) =\frac{a_0}{2}+\frac{a_1}{2^2}+...+\frac{a_r}{2^{r+1}}\,\, \left( 2 \right) Φ2(i)=2a0+22a1+...+2r+1ar(2)
其中 a 0 a 1 . . . a r a_0a_1...a_r a0a1...ar是 i i i用二进制表示的各个数字(i.e. i = a 0 +