快速Python/Numpy 2d/3d柏林/单工噪声发生器

2024-05-19 12:51:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用世界一代制作一个Minecraft风格的体素引擎。我有块做以及网格建设。我的主要瓶颈似乎是高空地图和洞穴的柏林噪音。现在我必须使用循环(python noise library)一次生成一个点的值。 我正在寻找一种柏林或单工噪声实现:

  • 可以一次生成一块噪音,而不是每次调用一个点
  • 可以从特定坐标开始生成
  • 可以生成二维或三维噪波
  • 比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秒左右。看起来不多,但会导致较大的滞后峰值)


Tags: inselfforifdefnprangewidth