光线追踪:何时规范化向量?

7
我正在重新编写我的光线追踪器,并试图更好地理解其中某些方面。
似乎我已经掌握了关于法向量的问题,以及如何将其乘以变换矩阵的逆转置。
我困惑的是,何时应该对我的方向向量进行归一化?
我遵循某本书,有时它会明确说明需要对矢量进行归一化,而其他情况则不需要,我发现我实际上需要这样做。
归一化后的向量与原向量方向相同,但长度为1?所以我不清楚何时需要进行归一化处理?
谢谢。

1
这个问题无法用当前的形式进行回答。它完全取决于您的实现和所使用的代数方程式。 - Howard
你能否提供一些常见的使用情况?或者我应该添加哪些信息? - Setheron
5个回答

7
除非你处理向量之间的角度或旋转向量,否则不需要归一化向量。
如果是前者情况,那么所有三角函数都要求向量落在单位圆上,这意味着向量已经被归一化。如果是后者情况,你需要除去向量的大小,将其旋转,确保它仍然是单位向量,然后再将大小乘回来。规范化只是必要操作之一。
如果有人告诉你坐标系由n个单位向量定义,那么i-hat、j-hat、k-hat等可以是任意任意长度和方向的向量,只要它们没有平行。这就是仿射变换的核心。
如果有人告诉你点积需要归一化的向量,那么你可以摇头微笑。只有在计算两个向量之间的夹角时,点积才需要归一化向量。
但是,规范化是否会让数学更简单呢?实际上并不会——这会增加一个数量计算和一个除法运算。0到1之间的数字与0到x之间的数字并没有区别。
话虽如此,有时为了与他人顺畅配合而进行规范化。但如果你发现自己在调用方法之前始终对向量进行规范化,考虑使用附加到向量上的标志来节省一步。在数学上,这并不重要,但在实际操作中,它可以对性能产生巨大影响。
所以,总之......一切都和旋转向量或测量其相对于另一个向量的角度有关。如果你没有这样做,就不要浪费计算资源。

一个额外的要点:有一种情况是专门为了避免在不需要时对向量进行归一化的。如果你正在使用计算倒数平方根的SIMD指令(如SSE、AVX和NEON),当归一化向量时,你会想要避免它以保持一定的精度。 - tay10r

3

tl;dr:规范化向量可以简化您的数学计算。它们还可以减少图像中非常难以诊断的视觉伪影。

规范化向量与仅具有单位长度1的相同方向吗?所以我不清楚什么时候需要使用它?

在光线追踪器中,您几乎总是希望所有向量都被规范化。

最简单的例子是交点测试:弹射光线何时撞击其他物体。

考虑一条光线:

p(t) = p_0 + v * t

在这种情况下,沿着该射线的任何点 p(t) 都被定义为从原始点 p_0 和特定方向 v 的偏移量。对于每个参数增量 t,得到的 p(t) 将沿着与向量 v 长度相等的长度增加另一个增量。
记住,你知道 p_0v。当你试图找到这条射线下一次撞击另一个物体的点时,你必须解决那个 t。在表示中使用标准化向量 v 显然更方便,但并非总是必要的。
然而,同样的向量 v 也用于光照计算。想象一下,我们有另一个指向光源的方向向量 u。为了一个非常简单的着色模型,我们可以将特定点处的光定义为这两个向量之间的点积。
L(p) = v * u
< p > < em > 诚然,这是一个非常无聊的反射模型,但它捕捉了讨论的重点。如果反射指向光源,表面上的斑点就会很亮,否则就会很暗。

现在,请记住另一种写法是向量的大小乘积与它们之间夹角的余弦:

L(p) = ||v|| ||u|| cos(theta)

如果uv的长度为单位长度(已标准化),则该方程将评估为与两个向量之间的角度成比例。但是,如果v不是单位长度,例如因为在射线模型中反射向量后没有标准化,那么你的光照模型就会出现问题。表面上使用较大的v的点将比不使用这些点更亮。


我的书实际上告诉我保持射线的方向向量未归一化,因为当将向量转换为每个实例的对象空间时,它会出现问题。 - Setheron
我有一种感觉,这是因为缩放没有被保留。 - Setheron
@Setheron,这里有两件事情在起作用。想象一下一个被规范化为1米长的方向向量。在这种情况下,值t将表示您需要走多少米才能到达交叉点。另一方面,您可能会发现以“眼点和目标点之间的分离”为术语更为方便,其中t的范围从0到1(0 = 眼球,1 = 交点)。最后,您需要理解逻辑和数学。使用有效的方法。 - Bob Cross
我现在明白了。它是每个时间间隔移动的量。我想只要我明白何时需要保持其归一化,而不是它就可以了!谢谢 - Setheron
@Setheron,很高兴听到这个消息。祝你好运! - Bob Cross
我最终决定不对向量进行归一化,这样我就可以通过每个节点的变换将其转换到树形结构中。如果我将其限制为单位长度,则我发现的交点时间可能是不正确的。 - Setheron

2
需要在使用受其长度影响的数学计算中规范化方向向量。其中一个主要例子是点积,在大多数照明方程中都会用到。即使您认为它们是正常的,有时候您也需要规范化在照明计算中使用的向量。
例如,在三角形上使用插值法进行法线处理时。常识告诉您,由于顶点处的法线是正常的,因此通过插值得到的向量也应该是正常的。但事实并非如此......除非它们偶然指向相同的方向,否则它们将更短。这意味着您会使三角形变暗(更糟糕的是,随着光源越靠近表面,效果会更加明显,这是一个非常有趣的结果)。
另一个例子是叉积,取决于您所做的事情。例如,当使用两个叉积构建一组正交基时,至少必须规范化一次(尽管如果您这样做得不好,您最终会更频繁地这样做)。如果您只关心生成的“上向量”的方向或符号,则无需规范化。

当我思考向量长度的概念时,我感到困惑。如果向量是空间方向的概念,那么它的长度为什么会有意义呢? - Setheron
1
那就是问题所在。它不仅仅是空间中的一个方向,而是指向某个方向的长度。(1,1,1)和(100,100,100)会指向相同的方向,但它们的长度不同(勾股定理)。当你谈论一个“法向量”时,通常意味着不只是“任意矢量”,而是长度恰好为1的矢量。这具有一个很好的特性,即在比较一些点之间的方向时,数学不会给出奇怪、随机的结果,而是完全依赖于方向的东西。 - Damon

2
我来回答相反的问题。什么情况下不需要归一化?几乎所有与光照相关的计算都需要单位向量——点积可以给出向量之间夹角的余弦值,这非常有用。有些方程仍然可以处理,但会变得更加复杂(本质上是在方程中进行归一化)。这样,大多数情况下只剩下交叉测试。
如果你有单位向量,许多交叉测试的方程式可以简化。有些则不需要——例如,如果你有一个平面方程(带有单位法向量),你可以找到射线-平面交点而不需要对射线方向向量进行归一化。距离将以射线方向向量长度的形式呈现。如果你只想相交一堆这样的平面(相对距离都是正确的),这可能还可以接受。但是,一旦你想与不同的距离进行比较——使用标准化的射线方向计算的距离——距离值就无法正确比较。
你可能会考虑在执行不需要标准化向量的工作后标准化方向向量。但那也不相关,因为最终射线会撞击到某些物体,你要用它来进行光照/着色计算。所以你最好从一开始就对它们进行标准化...
换句话说,任何具体的计算可能不需要标准化方向向量,但是在过程中几乎肯定需要对给定的方向向量进行标准化。

这是我之前的评论:我的书实际上告诉我要保持我的光线方向向量未归一化,因为当我将方向向量转换为每个我测试相交的实例的对象空间时,它会出现问题。这就是让我感到困惑的部分。 - Setheron
我有一种感觉,这是因为缩放没有被保留。 - Setheron

1

向量用于存储两个概念上不同的元素:空间中的点和方向:

  • 如果你要存储一个空间中的点(例如相机的位置,光线的起点,三角形的顶点),你不想进行规范化,因为这样会修改向量的值,并丢失具体位置。
  • 如果你要存储一个方向(例如相机的上方向,光线的方向,物体的法向量),你想要进行规范化,因为在这种情况下,你关心的不是点的具体值,而是它所代表的方向,所以不需要大小。规范化在这种情况下很有用,因为它简化了一些操作,比如计算两个向量的余弦,如果两个向量都被规范化了,可以通过点积来实现。

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