math - 光线追踪中的 3D 仿射变换问题

标签 math raytracing matrix-multiplication montecarlo affinetransform

全部,

我正在编写一个相当非传统的光线追踪器来计算场景中各种物体的热传递特性。在这个光线追踪器中,随机光线从原始对象的表面射入场景中以检查交叉点。

这个特定的算法要求每条光线在原始空间中展开,然后由源对象仿射变换到世界空间,然后仿射变换回场景中其他对象的原始空间以检查相交。

一切都很好,直到我做一个各向异性的尺度,例如按 [2 2 1] 缩放对象(各向同性尺度很好)。这让我相信我没有正确地转换光线的方向分量。目前,我通过将方向分量乘以源对象逆变换矩阵的转置将光线方向从原始空间变换到世界空间,然后通过乘以目标对象变换的转置将光线从世界空间变换到每个原始空间矩阵。

我还尝试乘以源基元的变换矩阵以从基元到世界空间并乘以目标逆变换以从世界空间到基元空间,但这是不成功的。

我相信从原始物体表面发射的光线(在随机点和随机方向)应该以与“常规”光线追踪中的表面法线相同的方式进行变换,但我不确定。

那里的任何专家都知道我的方法论的缺陷是什么?随时询问是否需要更多信息。

这个光线追踪器的基本算法如下:

For each object, i, in scene
{
    for each ray, r, in number of rays per object
    {
        determine random ray from primitive i
        convert ray from primitive space of i to world space

        for each object, j, in scene
        {
            convert ray to primitive space of object j
            check for intersection with object j
        }
    }
}

希望澄清这个问题让我们看一个例子。假设我有一个沿 z 轴(单位半径和高度)延伸的圆柱体和一个位于 xy 平面上的内径为 7 和外径为 8 的环面。我希望将圆柱体的比例缩放为 x 和 y 的 6 倍方向(但不是 z 方向)所以我的仿射变换矩阵如下:
M(cylinder) = |2 0 0 0|        M^-1(cylinder) = | .5 0. 0. 0. |
              |0 2 0 0|                         | 0. .5 0. 0. |
              |0 0 1 0|                         | 0. 0. 1. 0. |
              |0 0 0 1|                         | 0. 0. 0. 1. |

M(annulus) =  |1 0 0 0|        M^-1(annulus) =  |1 0 0 0|
              |0 1 0 0|                         |0 1 0 0|
              |0 0 1 0|                         |0 0 1 0|
              |0 0 0 1|                         |0 0 0 1|

现在假设我有一条射线,它在圆柱体 s 的表面上有一个随机起点,并且在远离圆柱体 c 表面的随机方向上给出了射线 r(os) = s + ct。

我想将这条射线从原始(对象)空间转换到世界空间,然后测试与场景中其他对象(环面)的交集。

第一个问题是使用 M(圆柱)或 M^-1(圆柱)将光线 r(os) 变换到世界空间 r(ws) 的正确方法是什么。

第二个问题是将光线 r(ws) 从世界空间转换到对象空间以使用 M(annulus) 和 M^-1(annulus) 检查与其他对象的交集的正确方法是什么。

一些额外的背景信息:

此应用程序用于计算 N 个物体之间的辐射传热。光线从物体上的一个随机点发射,其方向被随机选择以位于以随机点的表面法线定向的半球分布内。

这是我的问题的一些可视化。第一次生成时的光线方向分布:
Initial ray directional distribution

如果我使用变换矩阵 M 将变换应用于世界坐标:
Direction transformed by M

如果我使用逆变换矩阵 M^-1 将变换应用于世界坐标
Direction transformed by M^-1

最佳答案

逆转置变换矩阵保持旋转分量不变,但反转缩放。这意味着缩放仍然存在。这对于法线是正确的:考虑在 2d 中来自 的线段(0,0) (.707,.707) .正常是 (-.707,.707) .如果我们按 缩放(s,1) ,我们从 得到一个片段(0,0) (s*.707,.707) .在极限中,为 s 变大,我们基本上有一条平行于 x 轴的平线。这意味着法线应该指向 y 轴。所以我们得到了 的法线(-.707/s,.707) .然而,从这个例子中应该清楚的是,变换后的向量不再是单位长度。也许您需要标准化方向组件?

如果我们首先使用转换矩阵可以表示为夹在两个旋转之间的缩放比例(即 SVD)的属性,我们会得到您的出站转换矩阵如下所示: R2out*Sout^-1*R1out 然后您的入站转换矩阵如下所示: R1in^-1*Sin*R2in^-1 (我多么希望使用 Mathjax ......)。只要您重新标准化您的向量,这似乎是正确的事情。

编辑:

一夜之间思考这个问题,我决定逆转置的东西可能只对法线情况有效。考虑上面的例子。如 s=2 ,然后是线段的斜率,原为 1 , 变成 1/2 .同样,法线的斜率从 开始-1 进入 -2 .线段和射线之间仍有 90 度角。到现在为止还挺好。现在...如果所考虑的向量实际上平行于线段会怎样。我们得到 的斜率2 ,不再平行。

所以,我想我现在有两个问题。您的程序实际上出了什么问题/是什么让您认为它不正确?什么是正确的行为?也许你可以制作一个二维图。

关于math - 光线追踪中的 3D 仿射变换问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5826606/

相关文章:

algorithm - 高阶矩阵乘法

C++ 数学问题和 5/4*pi 与 5*pi/4

sql - 选择 sum where 子句 SQL

algorithm - 球面上的射线-多边形交点

c - 关于光线追踪算法相交测试性能的问题

c++ - 渲染中的区域采样与 BRDF 采样

python - 来自因子载荷和因子协方差的协方差矩阵?

algorithm - 确定有序素数对 (p, q) 的数量,使得 N = p^2+q^3 使得从 0 到 9 的每个数字都恰好出现一次

c++ - 检查数字是否是 C++ 中的回文

Numpy 矩阵乘法与自定义点积