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

时间:2011-04-29 00:31:15

标签: math raytracing matrix-multiplication montecarlo affinetransform

所有

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

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

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

我还试过乘以源图元的变换矩阵,从原始空间到世界空间再乘以目的地逆变换,从世界空间到原始空间,但这是不成功的。

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

那里的任何专家都知道我的方法有哪些缺陷?如果需要更多信息,请随时询问。


此光线跟踪器的基本算法如下:

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(环)和M ^ -1(环空)检查与其他物体的交点的正确方法是什么。


一些其他背景信息:

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


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

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

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

2 个答案:

答案 0 :(得分:3)

逆转置变换矩阵使旋转分量保持不变,但反转缩放。这意味着缩放仍然存在。这对于法线是正确的:在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 的斜率,不再平行。

所以,我想我现在有两个问题。你的程序中实际上出错的原因是什么让你认为它不正确?什么是正确的行为?也许你可以制作2D情节。

答案 1 :(得分:1)

这是前几天在This question

中提出的

其中一个答案链接到Ray Tracing News文章,该文章讨论了对法线使用逆变换的转置。

我不得不同意JCooper在询问“究竟出了什么问题?”。我的第一个想法是你似乎在模拟辐射热传递,你必须要小心不均匀的物体缩放。如果在发射的物体表面上均匀分布“光子”,然后对该物体应用非均匀缩放,则会有离子表面的光子分布不均匀。这是一个可能的陷阱,但由于你没有说明出了什么问题,很难说这是不是你的问题。

要回答有关正确转换方式的问题,请按照This link to Ray Tracing News

进行操作