快速 Python/Numpy 2d/3d perlin/simplex 噪声发生器

时间:2021-07-13 14:42:04

标签: python numpy perlin-noise

我正在制作具有世界生成功能的 Minecraft 风格的体素引擎。我已经完成了分块以及网格构建。我的主要瓶颈似乎是高度图和洞穴的柏林噪声生成。现在我必须通过循环(python 噪声库)一次生成一个点的值。 我正在寻找一个 perlin 或 simplex 噪声实现:

  • 可以一次产生一大块噪音,而不是每次调用一个点
  • 可以从特定坐标开始生成
  • 可以产生 2d 或 3d 噪声
  • 比python“噪音”库+循环更快

到目前为止我看到的所有实现要么可以一次生成一个块,但不能从特定坐标开始,要么可以在特定坐标生成但一次只能生成一个点

到目前为止我所拥有的:

from noise import * # <-- noise library I'm using
import numpy as np

...
    def generate(self):
        gradient = [(i * 4) / CHUNK_HEIGHT for i in range(int(CHUNK_HEIGHT / 2), -int(CHUNK_HEIGHT / 2), -1)]
        self.blockIDs = np.zeros((CHUNK_WIDTH + 2, CHUNK_HEIGHT, CHUNK_WIDTH + 2), dtype='int16')

        @np.vectorize
        def caveNoiseGen(x, y, z):
            return 1 if (snoise3(x / 64, y / 64, z / 64, octaves=6) + (1.5 - (gradient[y]))) * 10 > 0 else 0

        @np.vectorize
        def heightNoiseGen(x, y, z):
            return 1 if (snoise3(x / 128 + snoise3(x / 8192, y / 8192, z / 8192, octaves=1), y / 8192,
                                 z / 128, octaves=6) +
                         (((snoise2(x / 512, z / 512, octaves=1) * 3) + 3) * gradient[y])) * 10 > 0 else 0

        time1 = time.perf_counter()
        self.blockIDs = np.zeros((CHUNK_WIDTH + 2, CHUNK_HEIGHT, CHUNK_WIDTH + 2), dtype='int16')
        x, y, z = np.meshgrid(np.arange(CHUNK_WIDTH + 2) + (self.position[0] * CHUNK_WIDTH) - 1,
                              np.arange(CHUNK_HEIGHT),
                              np.arange(CHUNK_WIDTH + 2) + (self.position[2] * CHUNK_WIDTH) - 1)
        caveNoise = caveNoiseGen(x, y, z)
        heightNoise = heightNoiseGen(x, y, z)
        print(caveNoise[5, 5, 5])
        for i in itertools.product(range(CHUNK_WIDTH + 2), range(CHUNK_WIDTH + 2)):
            for y in range(CHUNK_HEIGHT):
                self.blockIDs[i[0], y, i[1]] = int(heightNoise[y, i[0], i[1]] if caveNoise[y, i[0], i[1]] == 1 else 0)
            self.blockIDs[i[0], 0, i[1]] = 1
        
        print("generate: " + str(time.perf_counter() - time1))

(生成时间通常在 0.08 秒左右。看起来不多,但会导致很大的延迟峰值)

0 个答案:

没有答案