【问题标题】:How to normalize Perlin Noise Values to range [0, 1]?如何将 Perlin 噪声值标准化为范围 [0, 1]?
【发布时间】:2019-08-12 23:05:04
【问题描述】:

我正在使用一个 numpy 数组来保存 Perlin Noise 值。有人告诉我,二维数组中的 Perlin 噪声值分别在 [-0.7, 0.7] 范围内,但这似乎不是真的。当我调整八度音阶、持久性和空缺性的参数时,至少不适用于 Caseman 的“noise”库。

我会使用一个不同的库,除了我找不到任何可以以同样快的速度运行的 python 库。此外,无论如何,将值标准化为范围 [0, 1] 的典型公式似乎在这里不起作用。即使我得到未修改噪声的最小/最大值,它仍然没有给我想要的值范围。我只需要猜测最小/最大值使用什么,直到范围大致为 [0, 1]。

如何将 Perlin 噪声值标准化为范围 [0, 1]?

import noise
import numpy
import sys

def __noise(noise_x, noise_y):
    """
    Generates and returns a noise value normalized to (roughly) range [0, 1].

    :param noise_x: The noise value of x
    :param noise_y: The noise value of y
    :return: float
    """

    value = noise.pnoise2(noise_x, noise_y, 8, 1.7, 2)
    # Normalize to range [0, 1]
    value = numpy.float32((value + 0.6447) / (0.6697 + 0.6447))

    return value


map_arr = numpy.zeros([900, 1600], numpy.float32)

for y in range(900):

    for x in range(1600):

        noise_x = x / 1600 - 0.5
        noise_y = y / 900 - 0.5

        value = __noise(noise_x, noise_y)
        map_arr[y][x] = value

for row in map_arr:
    for num in row:
        sys.stdout.write(str(num) + " ")
    print("")

【问题讨论】:

  • 啊,我的错。为什么(map_arr - map_arr.min()) / (map_arr.max() - map_arr.min()) 不起作用?
  • @MarcusLim 我将不得不完全遍历数组以生成相关的最小/最大值。然后,我将不得不再次遍历整个数组以调整其中的所有值。这似乎效率低下。另外,我提到它不会让我得到接近 [0, 1] 的范围。
  • 恐怕我不明白。为什么必须执行迭代,因为您可以使用我评论中的代码应用矢量化操作?
  • @MarcusLim 因为map_arr第一次初始化的时候,全是零。
  • 所以你是说你想在生成数据的同时通过缓存已经看到的值来执行最小/最大计算?这很容易做到,但它真的会提升性能吗?

标签: python numpy noise procedural-generation perlin-noise


【解决方案1】:

map_arr = (map_arr - map_arr.min()) / (map_arr.max() - map_arr.min())(利用numpy broadcasting 和矢量化)就足够了。

【讨论】:

  • 您可能不需要使用 map_arr.max()/min()。在 2D 中,Perlin 噪声应绑定在 -math.sqrt(2)/2 和 math.sqrt(2)/2 之间(问题中提到的 OP 的“大约 0.7”)。
猜你喜欢
  • 2013-06-29
  • 1970-01-01
  • 1970-01-01
  • 2020-12-23
  • 2013-07-23
  • 2016-08-19
  • 1970-01-01
  • 2017-06-27
相关资源
最近更新 更多