是否有一个简单的数学解决方案来对磁盘区域光进行采样? (光线追踪)
Is there a simple math solution to sample a disk area light? (Raytracing)
我正在尝试在用 C 编码的光线追踪器中实现不同类型的灯光。我已经成功地实现了聚光灯、点灯、定向灯和 矩形区域 灯。
对于 矩形区域光 我在 space 中定义了两个向量(U 和 V),我使用它们移动到它们形成的虚拟(分隔)矩形中。
根据光的强度,我在矩形上取了几个样本,然后计算到达一个点的光量,就好像每个样本都是一个聚光灯一样。
使用矩形很容易找到各种样本的位置,但是当我尝试用 圆盘灯 做同样的事情时,事情就变得复杂了。
我发现很少有关于它的文档,而且它们中的大多数已经使用现成的函数来做到这一点。
我发现的唯一有趣的事情是这个文档 (https://graphics.pixar.com/library/DiskLightSampling/paper.pdf),但我无法利用它。
你知道如何用矢量运算帮助我获得类似的结果(下图)吗? (例如,具有圆盘的原点、方向、半径和样本数)
这方面的任何建议或文档都会对我有很大帮助。
这个问题简化为:
How can I pick a uniformly-distributed random point on a disk?
一种天真的方法是随机生成 polar coordinates 并将它们转换为笛卡尔坐标:
- 在
0
和2π
之间随机生成一个角度θ
- 在
0
和您的磁盘半径 r
之间随机生成一个距离 d
- 使用
x = r cos θ
和 y = r sin θ
转换为笛卡尔坐标
这是不正确的,因为它会导致点在中心聚集;例如:
一种正确但低效的方法是通过 rejection sampling:
- 均匀生成随机
x
和y
,每个超过[0, 1]
- 如果
sqrt(x^2 + y^2) < 1
,return点
- 转到 1
说明了正确的方法 here:
- 在
0
和2π
之间随机生成一个角度θ
- 在
0
和您的磁盘半径 r
之间随机生成一个距离 d
- 使用
x = sqrt(r) cos θ
和 y = sqrt(r) sin θ
转换为笛卡尔坐标
我正在尝试在用 C 编码的光线追踪器中实现不同类型的灯光。我已经成功地实现了聚光灯、点灯、定向灯和 矩形区域 灯。
对于 矩形区域光 我在 space 中定义了两个向量(U 和 V),我使用它们移动到它们形成的虚拟(分隔)矩形中。
根据光的强度,我在矩形上取了几个样本,然后计算到达一个点的光量,就好像每个样本都是一个聚光灯一样。
使用矩形很容易找到各种样本的位置,但是当我尝试用 圆盘灯 做同样的事情时,事情就变得复杂了。 我发现很少有关于它的文档,而且它们中的大多数已经使用现成的函数来做到这一点。 我发现的唯一有趣的事情是这个文档 (https://graphics.pixar.com/library/DiskLightSampling/paper.pdf),但我无法利用它。
你知道如何用矢量运算帮助我获得类似的结果(下图)吗? (例如,具有圆盘的原点、方向、半径和样本数)
这方面的任何建议或文档都会对我有很大帮助。
这个问题简化为:
How can I pick a uniformly-distributed random point on a disk?
一种天真的方法是随机生成 polar coordinates 并将它们转换为笛卡尔坐标:
- 在
0
和2π
之间随机生成一个角度θ
- 在
0
和您的磁盘半径r
之间随机生成一个距离d
- 使用
x = r cos θ
和y = r sin θ
转换为笛卡尔坐标
这是不正确的,因为它会导致点在中心聚集;例如:
一种正确但低效的方法是通过 rejection sampling:
- 均匀生成随机
x
和y
,每个超过[0, 1]
- 如果
sqrt(x^2 + y^2) < 1
,return点 - 转到 1
说明了正确的方法 here:
- 在
0
和2π
之间随机生成一个角度θ
- 在
0
和您的磁盘半径r
之间随机生成一个距离d
- 使用
x = sqrt(r) cos θ
和y = sqrt(r) sin θ
转换为笛卡尔坐标