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

问题描述

我正在制作具有世界生成功能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,z):
            return 1 if (snoise3(x / 128 + snoise3(x / 8192,y / 8192,z / 8192,octaves=1),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,dtype='int16')
        x,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,z)
        heightNoise = heightNoiseGen(x,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],i[1]] = int(heightNoise[y,i[0],i[1]] if caveNoise[y,i[1]] == 1 else 0)
            self.blockIDs[i[0],i[1]] = 1
        
        print("generate: " + str(time.perf_counter() - time1))

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

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)