【问题标题】:Calculating Diffuse (Lambertian) Reflection计算漫反射(朗伯)反射
【发布时间】:2013-01-06 18:29:30
【问题描述】:

我需要帮助弄清楚如何计算 (Lambertian) 漫反射 - 即当光线撞击表面然后在随机方向反弹时。那么,如果我有一个源自光源的光向量 L、一个 3D 点 X 和一个点 X 的法线向量 N,我该如何计算随机反射的光线?

在我正在阅读的一本书中,他们说要使用这个等式:

Wd = (theta, phi) = cos-1(sqrt(rand1), 2*pi*rand2) 其中 Wd 是反射光线,rand1 和 rand2 是 [0,1] 范围内的随机数。

这对我不起作用。我使用了该方程,然后将球坐标转换为笛卡尔坐标,但这使得光线总是在相同的几个方向上反射,而不管法线的方向如何。

感谢任何帮助!

【问题讨论】:

    标签: reflection graphics vector normalization physics


    【解决方案1】:

    选择theta 为arccos(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。您只需选择球坐标,以便采样的半球为在表面的外侧。

    另一种选择:

    1. 在整个单位球面上随机绘制一个点(即theta = 2 * pi * u)
    2. 转换为笛卡尔点向量坐标
    3. 取法线和点向量的点积。如果结果是否定的,请从第 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)统一采样的。

    还有另一种完全不使用三角函数的方法(取自here):

    将x1 和x2 从[-1, 1] 统一采样。如果x1^2 + x2^2 &lt; 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)
    

    【讨论】:

    • 非常感谢!这是非常有用的。我现在有点困惑为什么我正在阅读的书(这是 Henrik Wann Jensen 的光子映射指南)推荐方程 (theta, phi) = (cos-1(sqrt(rand1), 2*pi* rand2) 如果该等式为假。
    • 抱歉,我无权访问那本书。这可能是一个错字,或者您可能以我无法正确理解的方式转录公式。
    【解决方案2】:

    我也在研究朗伯反射,您提供的代码确实有效,它只是从表面的法线向量中引用的。要获得正确的向量,您应该:

    1. 将曲面法线向量 N 绕曲面平面中的(任意)轴旋转角度 phi
    2. 将结果向量围绕表面法线向量旋转角度 theta

    可以从这里生成关于任意轴旋转矢量的代码: http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/

    【讨论】:

      猜你喜欢
      • 2021-01-08
      • 2015-02-05
      • 1970-01-01
      • 2018-09-28
      • 1970-01-01
      • 2018-07-09
      • 2011-05-08
      • 1970-01-01
      • 2011-06-06
      相关资源
      最近更新 更多