首页 > 解决方案 > 是否可以将 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)

标签: functioninterpolationnoisederivativeblending

解决方案


您的混合因子也需要是可区分的。

为了看到这一点,让我们写出什么h = Lerp(f, g, a)意思:

h = af + (1-a)g

一切都是xy在这里的函数,包括a它自己。使用链式法则求导(为了符号的简单,我忽略了这些东西是二维的事实):

h' = a'f + af' - a'g + (1-a)g'

因此,h'为了无处不在,我们也需要a'存在。但是,您并没有Lerp在任何地方使用,而只是在转换发生的时间间隔内使用。就好像您在将其传递a给. 从你的帖子中,我收集到看起来像这样:[0, 1]Lerpa

          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 = 1x = 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

推荐阅读