function - 是否可以将 2D 噪声函数与合理的导数一起转换为另一个函数?
问题描述
我有一个噪声函数 NoiseAt(x,y),它返回一个噪声值和两个导数 dx 和 dy。我想将此函数转换为另一个噪声函数 OtherNoiseAt(x, y) ,该函数也返回噪声和两个导数。
它是基于此处找到的实现的单纯形噪声: https ://github.com/simongeilfus/SimplexNoise/blob/master/include/Simplex.h
例如,对于大于 1 的 x 和 y 值,函数NoiseAt应该混合到函数OtherNoiseAt 中,并在 x 和 y 值大于 2 时完成混合。
我已经尝试过处理噪声和导数,但生成的导数是无效的。
IE。
Lerp(NoiseAt(x, y), OtherNoiseAt(x, y), blending_factor)
(其中当 x 和 y 值都小于 1 时 blending_factor 为 0,而当 x 和 y 值都大于 2 时 blending_factor 为 1)
有没有一种混合方法可以在整个混合过程中保持合理的衍生物?
换句话说,这个函数的主体是什么:
Blend(noise1, dx1, dy1, noise2, dx2, dy2, factor)
解决方案
您的混合因子也需要是可区分的。
为了看到这一点,让我们写出什么h = Lerp(f, g, a)
意思:
h = af + (1-a)g
一切都是x
和y
在这里的函数,包括a
它自己。使用链式法则求导(为了符号的简单,我忽略了这些东西是二维的事实):
h' = a'f + af' - a'g + (1-a)g'
因此,h'
为了无处不在,我们也需要a'
存在。但是,您并没有Lerp
在任何地方使用,而只是在转换发生的时间间隔内使用。就好像您在将其传递a
给. 从你的帖子中,我收集到看起来像这样:[0, 1]
Lerp
a
0 if x < 1 and y < 1
a(x, y) = ? "in between"
1 if x > 2 and y > 2
那是相当不明确的,所以让我们看一个一维的情况:
0 if x < 1
a(x) = x - 1 if 1 ≤ x ≤ 2
1 if 2 < x
这是一个连续函数,但它在x = 1
和x = 2
因为斜率突然变化而无法微分。
有几种替代方案在任何地方都有衍生产品。这些通常在 interval 上定义0 ≤ x ≤ 1
,因此您必须在评估函数之前进行一些平移和缩放。构建这些时的关键是确保导数在x = 0
和处为零x = 1
。
例如,对于余弦形状:
0 if x < 0
a(x) = 1 - cos(x/pi)/2 if 0 ≤ x ≤ 1
1 if 1 < x
或者使用三次样条(另见“平滑步”):
0 if x < 0
a(x) = 3x² - 2x³ if 0 ≤ x ≤ 1
1 if 1 < x