Math 棘手的柏林噪声问题。梯度函数如何使用标准化向量?

Math 棘手的柏林噪声问题。梯度函数如何使用标准化向量?,math,vector,noise,Math,Vector,Noise,我目前正在了解改进的柏林噪声。 我完全理解这个理论,但是,我对它的一个常见实现方面感到困惑,例如 我的问题是,grad()函数如何返回规范化向量(梯度和方向)的点积?我的意思是,归一化向量的点积的范围是-1到1,这是柏林噪声在混合(衰减)所有点积之后的正常输出。但是经过点积的向量不是标准化的(没有梯度函数,也没有方向向量)。那么,输出如何在-1到1范围内 我唯一的猜测是梯度向量都有根2的大小,方向向量的所有轴都在-1到1的范围内。所以,我假设这就是柏林噪声输出最终在-1到1范围内的原因。这是为什

我目前正在了解改进的柏林噪声。 我完全理解这个理论,但是,我对它的一个常见实现方面感到困惑,例如

我的问题是,grad()函数如何返回规范化向量(梯度和方向)的点积?我的意思是,归一化向量的点积的范围是-1到1,这是柏林噪声在混合(衰减)所有点积之后的正常输出。但是经过点积的向量不是标准化的(没有梯度函数,也没有方向向量)。那么,输出如何在-1到1范围内

我唯一的猜测是梯度向量都有根2的大小,方向向量的所有轴都在-1到1的范围内。所以,我假设这就是柏林噪声输出最终在-1到1范围内的原因。这是为什么?有人能证明或找到证据吗


谢谢大家,在中,
grad()
函数返回两个向量的点积,但我不明白是什么让你说这些向量应该有单位大小。采样位置可以连续位于立方体中的任何位置。假设一个单位大小的立方体,到采样位置的距离向量的大小可能在0到sqrt(3)之间。所以,它看起来像| |梯度向量| |=sqrt(2)和| |距离向量| |≤ sqrt(3),将
grad()的输出限定在−sqrt(6)和+sqrt(6)(≈ 2.45)。

矢量没有标准化(它们的长度是sqrt(2),正如所描述的另一个贡献者),并且噪声的总输出不是精确的-1:1。如果向量和所有符号排列都是可能的,那么我相信最大值就在每个立方体的中心。对于0.5^3,它将是点(梯度,偏移自顶点)=点(,)=1.5,/8,因为在3个方向的每个方向上都有一半的插值权重,*8对于有8个顶点,它再次取消。如果向量是标准化的,并且它们可以指向每个立方体的中心,那么点(/sqrt(3),)=1.5/sqrt(3)≈ 0.8660254037844387

但是,这两种情况都不是这样,因此噪声的实际最小/最大值更复杂。我以前在噪声上运行过梯度上升,使用你看到的梯度集,来找到它的真正最大值。最大值略大于1,且不在中心。将整个噪声乘以(或等效地将表中的每个梯度乘以)以校正输出范围的值为0.964921414852142333984375

顺便说一句,如果你还没有通过其他来源发现这一点:柏林河是伟大的学习,但它产生了大量的偏向主轴和产量低变化的角度分布的特点。好的单纯形噪声实现通常会产生更好的结果。如果您要使用柏林,我建议您选择垂直(或时间,或未使用的)方向,并在输入坐标上使用以下公式之一。您可以在分形求和之前执行此操作(更有效),也可以将其放入函数定义的开头(更方便)。一旦您这样做了,它就很棒了,而且在正确的情况下使用时,它比一些单纯形类型的噪波实现看起来更好。但是请注意,对于这种技术,您需要始终使用3D噪波,即使您的用例只是2D

如果Z为垂直、时间或未使用:

double xy = x + y;
double s2 = xy * -0.211324865405187;
z *= 0.577350269189626;
x += s2 - z;
y = y + s2 - z;
z += xy * 0.577350269189626;
double xz = x + z;
double s2 = xz * -0.211324865405187;
y *= 0.577350269189626;
x += s2 - y;
z = z + s2 - y;
y += xz * 0.577350269189626;
如果Y为垂直、时间或未使用:

double xy = x + y;
double s2 = xy * -0.211324865405187;
z *= 0.577350269189626;
x += s2 - z;
y = y + s2 - z;
z += xy * 0.577350269189626;
double xz = x + z;
double s2 = xz * -0.211324865405187;
y *= 0.577350269189626;
x += s2 - y;
z = z + s2 - y;
y += xz * 0.577350269189626;
之前(45度和90度零件的批次)

之后(方向偏差基本不可见)


好的,太好了,谢谢你提供的信息。我的困惑是假设柏林噪声的输出在-1到1的范围内,然而,源实现的真实范围实际上稍微大一些。非常感谢你。