选择theta
bearccos(sqrt(rand1))
不会在单位球体的表面上给你随机分布的点,因为它的分布arccos(sqrt(rand1))
并不像应有的那样均匀。
给定两个随机变量u
和v
,从 均匀采样(0, 1)
,在球坐标中,随机点将是:
theta = 2*pi * u <--- note, no arccos here
phi = arccos(2*v - 1)
由于它是来自表面的反射,因此您只需对球面的一半进行采样,因此theta
宁愿theta = pi * u
.
由于反射角是随机的,因此光源的位置并不重要,即结果不取决于光矢量 L。您只需选择球坐标,使采样的半球位于外部表面的一侧。
另外的选择:
- 在整个单位球面上画一个随机点(即
theta = 2 * pi * u
)
- 转换为笛卡尔点向量坐标
- 取法线和点向量的点积。如果它是否定的,请从步骤 1 开始重复。
这将保证您只从面向表面外侧的半球采样。
您也可以完全跳过球坐标并直接计算笛卡尔坐标:
x = sqrt(1 - u^2) * cos(theta)
y = sqrt(1 - u^2) * sin(theta)
z = u
这里u
是从 均匀采样的[-1, 1]
(例如u = 2*v - 1
,在哪里v
是均匀采样的[0, 1]
)并且theta
是从 均匀采样的[0, 2*pi)
。
还有另一种完全不使用三角函数的方法(取自此处):
从 中取x1
并x2
均匀采样[-1, 1]
。如果x1^2 + x2^2 < 1
,那么(如果不是,重复采样):
x = 2 * x1 * sqrt(1 - x1^2 - x2^2)
y = 2 * x2 * sqrt(1 - x1^2 - x2^2)
z = 1 - 2 * (x1^2 + x2^2)