rendering - 是否有一个简单的数学解决方案来采样磁盘区域光?(光线追踪)
问题描述
我正在尝试在用 C 编码的光线追踪器中实现不同类型的灯光。我已经成功实现了点灯、点灯、定向灯和矩形区域灯。
对于矩形区域光,我在空间中定义了两个向量(U 和 V),并使用它们移动到它们形成的虚拟(定界)矩形中。根据光的强度,我在矩形上取了几个样本,然后我计算到达一个点的光量,就好像每个样本都是一个聚光灯一样。
使用矩形很容易找到各种样本的位置,但是当我尝试用圆盘灯做同样的事情时事情变得复杂了。我发现很少有关于这方面的文档,其中大多数已经使用现成的函数来做到这一点。我发现的唯一有趣的事情是这个文档(https://graphics.pixar.com/library/DiskLightSampling/paper.pdf),但我无法利用它。
您知道如何通过矢量运算帮助我获得类似的结果(下图)吗?(例如,具有圆盘的原点、方向、半径和样本数)
这方面的任何建议或文件都会对我有很大帮助。
解决方案
这个问题简化为:
如何在磁盘上选择均匀分布的随机点?
一种天真的方法是生成随机极坐标并将它们转换为笛卡尔坐标:
- 随机生成和
θ
之间的角度0
2π
- 随机生成磁盘
d
之间的距离0
和半径r
x = r cos θ
用和转换为笛卡尔坐标y = r sin θ
这是不正确的,因为它会导致点在中心聚集;例如:
一种正确但低效的方法是通过拒绝抽样:
- 均匀地生成随机
x
和y
,每个超过[0, 1]
- 如果
sqrt(x^2 + y^2) < 1
,则返回该点 - 转到 1
此处说明了执行此操作的正确方法:
- 随机生成和
θ
之间的角度0
2π
- 随机生成磁盘
d
之间的距离0
和半径r
x = sqrt(r) cos θ
用和转换为笛卡尔坐标y = sqrt(r) sin θ
推荐阅读
- python - Python Pandas Dataframe - 迭代行并添加字典问题
- c# - 如何通过 C# 在 MS Visio 中获取组对象的详细信息
- bash - 只有在前一个进程完成后才运行一个进程 | 重击
- java - Junit 测试在 Eclipse 中运行,但因“gradle test”而失败
- go - 安装 Golang Kafka 客户端(Confluent)时出现错误消息
- email - 如何使用 JavaMail API 从分发列表中读取或获取电子邮件?
- python - Google Clode Datastore 客户端库创建实体
- java - 在 Spring Data JPA 中加入两个实体
- python - 如何使用python将jar文件输出发送到json文件
- c - 将 uint8_t 转换为 ascii 字符串 C