RayTracing:何时标准化矢量?

时间:2011-07-29 14:58:16

标签: graphics vector linear-algebra raytracing

我正在重写我的光线追踪器,并试图更好地理解它的某些方面。

我似乎已经解决了关于法线的问题以及如何将它们乘以变换矩阵的转置的倒数。

我感到困惑的是,我应该将我的方向向量标准化吗?

我正在关注某本书,有时它会明确说明我的矢量标准化以及其他情况并非如此,我发现我需要这样做。

归一化向量的方向相同,单位长度为1?所以我不清楚什么时候有必要?

由于

5 个答案:

答案 0 :(得分:5)

您永远不需要对矢量进行标准化,除非您正在处理矢量之间的角度,或者除非您正在旋转矢量。

就是这样。

在前一种情况下,所有的trig函数都要求向量在单位圆上着陆,这意味着向量是标准化的。在后一种情况下,你要分割幅度,旋转矢量,确保它保持一个单位,然后再将幅度乘以。规范化只适用于领土。

  • 如果有人告诉你坐标系是由n个单位向量定义的,那么知道i-hat,j-hat,k-hat等可以是任何任意向量( s)任何长度和方向,只要它们都不是平行的。这是仿射变换的核心。

  • 如果有人试图告诉您点积需要标准化矢量,请摇头并微笑。当您使用点积乘以获得两个向量之间的角度时,它只需要归一化向量。

但是,规范化不会使数学“更简单”吗?

不是 - 它增加了幅度计算和除法。 0..1之间的数字与0..x之间的数字没有区别。

话虽如此,你有时会正常化以便与他人合作。但是,如果您在调用方法之前发现自己将向量归一化为原则问题,请考虑使用附加到向量的标志来为自己节省一步。在数学上,它并不重要,但实际上,它可以在性能上产生巨大的差异。

再次......这是关于旋转矢量或测量其与另一个矢量的角度的全部内容。如果你不这样做,不要浪费周期。

答案 1 :(得分:2)

无论何时在某个受其长度影响的数学中使用方向向量,都必须对其进行标准化。

主要的例子是点积,它用于大多数光照方程。您有时也需要规范化在光照计算中使用的矢量,即使您相信它们是正常的。

例如,在三角形上使用插值法线时。常识告诉你,由于顶点的法线是 normal ,你通过插值获得的矢量也是如此。对于常识来说太多了......事实是,除非他们总是指向同一个方向,否则他们将更短。这意味着你将三角形阴影变得太暗(更糟糕的是,光源越接近表面,效果越明显,这是一个非常有趣的结果)。

另一个矢量可能会或可能不会被规范化的示例是交叉乘积,具体取决于您正在做什么。例如,当使用两个交叉产品来构建正交基础时,那么你必须至少标准化一次(尽管如果你天真地这样做,你最终会更频繁地做它)。 如果您只关心生成的“向上矢量”的方向,或关于符号,则无需进行标准化。

答案 2 :(得分:2)

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

不可否认,这是一个非常无趣的反思模型,但它抓住了讨论的高点。如果反射指向光线,则表面上的斑点是明亮的,如果不是,则表面变暗。

现在,请记住,编写此点积的另一种方法是向量的大小乘以它们之间角度的余弦的乘积:

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

如果uv具有单位长度(标准化),则等式将评估为与两个向量之间的角度成比例。但是,如果v不是单位长度,比如因为您在上面的光线模型中反映矢量后没有理由进行标准化,那么现在您的照明模型存在问题。使用较大v的表面上的斑点将比不使用较大{{1}}的斑点亮得多。

答案 3 :(得分:2)

我会回答相反的问题。你什么时候不需要正常化?几乎所有与光照相关的计算都需要单位矢量 - 点积然后给出矢量之间角度的余弦,这是非常有用的。一些方程仍然可以应对但变得更复杂(基本上在方程式中进行归一化)主要是交叉测试。

如果您有单位向量,则可以简化许多相交测试的方程式。有些人不需要它 - 例如,如果你有一个平面方程(单位法线)你可以找到光线平面交点而不规范光线方向向量。距离将以光线方向矢量长度表示。如果您想要的是与一堆这些平面相交(相对距离都是正确的),这可能没问题。但是只要你想用不同的距离进行比较 - 使用标准化的光线方向计算 - 距离值就无法正确比较。

您可能会考虑在执行一些不需要它的工作后对方向矢量进行标准化 - 也许您有一个可以在没有标准化矢量的情况下遍历的加速结构。但这并不重要,因为最终光线会碰到一些东西而你会想要用它进行光照/阴影计算。所以你可以从一开始就将它们标准化......

换句话说,任何特定的计算都可能不需要标准化的方向向量,但是给定的方向向量几乎肯定需要在过程中的某个点进行标准化。

答案 4 :(得分:0)

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

  • 如果要存储空间中的点(例如摄像机的位置,光线的原点,三角形的顶点),则不希望进行标准化,因为您将修改矢量的值,并失去了具体的位置。
  • 如果要存储一个方向(例如相机向上,光线方向,对象法线),你想要标准化,因为在这种情况下你不感兴趣的不是点的具体值,而是指向它的方向代表,所以你不需要幅度。在这种情况下,归一化很有用,因为它简化了一些操作,例如计算两个向量的余弦,如果两者都被归一化,可以使用点积来完成。