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

4

大家好,

我正在编写一个非常不传统的光线追踪器,用于计算场景中各种物体的传热性质。在这个光线追踪器中,从原始物体的表面发射随机光线进入场景以检查交点。

这个特定的算法要求每个光线都在原始空间中进行开发,然后由源对象进行仿射变换到世界空间,然后再通过其他物体在场景中的原始空间中进行仿射变换,以检查是否存在交点。

一切都很好,直到我进行各向异性缩放,例如将对象按[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轴延伸的圆柱(单位半径和高度),以及一个在x-y平面上的环形,内径为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(cylinder)或M ^-1(cylinder)将光线r(os)正确地转换为世界空间r(ws)。
第二个问题是什么是将光线r(ws)从世界空间转换为对象空间以检查与其他对象相交的正确方法,使用M(annulus)和M ^-1(annulus)。
一些额外的背景信息:
此应用程序用于计算N个对象之间的辐射传热。该光线从对象上的随机点发射,其方向被随机选择以位于以该点处表面法线为定向的半球分布内。
以下是我的问题的一些可视化。当首次生成时,光线方向分布如下: “初始光线方向分布”src 如果我使用变换矩阵M将其转换为世界坐标: “由M变换的方向”src 如果我使用反变换矩阵M ^-1将其转换为世界坐标: “由M

这句话几乎无法理解:“现在,这个特定的算法要求射线在原始空间中确定,然后通过源对象进行仿射变换到世界空间,然后再通过场景中其他对象的原始空间进行仿射变换以检查相交。” 另外,请解释第二段中你为什么要做什么。需要更多的解释和数学知识才能帮助你。 - Chris A.
我在想,如果你能将有关算法的陈述编码为数学公式或代码,这可能会有所帮助,以明确乘法顺序等。 - Vusak
还有,请等一下。我不明白这与C++直接相关的地方在哪里。它听起来严格来说只是一个数学问题。 - Chris A.
1
你的变换矩阵是从基元空间到世界空间的线性变换,反之亦然吗?我不明白为什么你需要转置变换矩阵,除非你的变换矩阵是正交的。否则,对于线性变换矩阵A,对于给定向量x,A(INV)Ax=x。除非你引入某种非线性变换,否则这种关系不会被打破。例如,你是否还处理变换矩阵中的平移,并且如果是这样,你是否使用齐次坐标系统? - Jason
Chris,你说得对,这与C++无关,我已经删除了标签。最初我打算通过代码来解决它(它是用C++编写的),但后来我觉得我不需要这样做了。 - cubiclewar
2个回答

3
逆转置变换矩阵保持旋转分量恒定,但反转了缩放。这意味着缩放仍然存在。这对于法线是正确的:在二维中,考虑从(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(我多么希望SO使用Mathjax……)。只要重新规范化向量,这似乎是正确的。
编辑:
经过一夜的思考,我决定逆转置事情可能仅在法线情况下有效。考虑上面的例子。如果s = 2,则线段的斜率原来为1,变为1/2。同样,法线的斜率从-1变为-2。线段和射线之间仍然存在90度角。到目前为止还不错。现在…如果要考虑的向量实际上与线段平行,则我们得到一个斜率为2的向量,不再平行。
因此,我想此时有两个问题。您的程序中实际上出了什么问题?您认为它不正确的原因是什么?正确的行为是什么?也许您可以制作一个二维图。

我不确定我理解您所说的出站和入站转换术语。我已经尝试标准化方向向量。我找到的信息称,如果您标准化,则交点时间(t)将不正确。 - cubiclewar
我同意JCooper的观点,可能有某个非线性因素被引入了。如果您正在附加多个变换,则顺序很重要(即我认为您可能首先想要进行缩放,然后旋转,最后再将其平移到位置上)。如果您愿意,可以使用我的光线追踪代码作为参考,您可以在Python shell中编写几行代码来创建圆柱体、变换并检查光线交点 https://github.com/danieljfarrell/pvtrace 如果您需要指导,请告诉我。 - Daniel Farrell
在我运行的情况下,我要么只进行缩放,要么先缩放再进行变换,所以顺序不应该是一个问题。我不确定非线性会在哪里引入。 - cubiclewar
JCooper,这里有更多的背景信息。我的代码实际上计算了一个叫做视角因子的东西,它表示一个表面能够看到另一个表面的程度。从表面i到表面j的视角因子Fij被计算为离开i并击中j的光线数目除以离开i的总光线数目。现在我正在测试这个链接中的场景。当不使用缩放(或各向同性)时,我得到了正确的结果,但如果我按[2 2 1]进行缩放,则得到了错误的结果。通过M进行变换,我得到了较低的结果,通过M^-1进行变换,我得到了较高的结果。 - cubiclewar
@TDawg,所以你使用蒙特卡罗模拟来近似视角因子?这意味着需要从缩放后的圆柱面上随机采样光线,以避免使样本不均匀,对吧? - JCooper
JCooper,没错,需要在缩放后从表面随机采样光线。光线位置正确缩放,但我认为方向缩放后它们不再均匀地分布在半球上了。 - cubiclewar

1

这个问题在这个问题中提出了。

其中一个答案链接到一篇关于使用转置的逆变换来处理法线的光线追踪新闻文章。

我同意JCooper的看法,问“实际上出了什么问题?”我的第一个想法是,你似乎正在模拟辐射传热,并且必须小心对象的非均匀缩放。如果你在对象表面上有一个“光子”的均匀分布被发射出来,然后你对该对象应用非均匀缩放,那么你将会得到一个非均匀的光子分布离开表面。这是一个可能的陷阱,但由于你没有指出出了什么问题,很难说这是否是你的问题。

要回答你关于正确进行变换的问题,请参考这个链接到光线追踪新闻的链接


phkahler,你说得非常正确。我正在建模辐射传热,我的问题是在各向异性缩放后,我的“光子”均匀分布变得不均匀。因此,实质上我需要知道如何从对象空间转换到世界空间,以及从世界空间转换到对象空间,以保持均匀分布。 - cubiclewar
如果你在一个立方体的表面上均匀分布点,然后将其垂直拉伸2倍,顶部和底部的点密度不会改变,而侧面的密度会减半。这个问题也存在于球体上。我相信有解决方案,但我认为这不是转换本身的问题。 - phkahler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接