使用Perlin噪声生成瓦片地形- Java

3

我目前正在将2d Perlin噪声生成到一个2d数组中,然后(经过插值)渲染结果作为高度图(基本上是array[x][z] = y)。

这对于一个数组来说很好,但是对于基于相机位置的瓦片加载不适用,而且我在瓦片应该在接缝处相遇时遇到了困难。

[噪声瓦片]

noise tiles

我最好的尝试是生成一个大的二维基础噪声数组(-1到1),然后将每个瓦片作为一个对象,存储一个偏移值,用于读取基础网格的哪个部分。

这使我能够采样(用于插值)比瓦片数组大得多的基础网格区域,但它仍然没有对齐!

我的目标是拥有一个飞行摄像头,可以在移动时加载瓦片,并且可以在不重复的情况下行驶非常远。


这种使用2d数组的方法足以处理目标吗?

如果是这样,如何实现正确的瓷砖或包裹?


我认为Perlin噪声不适合您的需求,因为每个瓦片都需要与其他瓦片共享所有4个边缘,并且它们具有不同的噪声梯度。您是否考虑过分形地形生成? - Tassos Bassoukos
1个回答

3

我以前遇到过类似的问题,经过大量调整和测试,我得出结论:普通的2D perlin噪声永远不会像自然地形一样,它本质上是白噪声(即没有巨大的山脉或峡谷,只有靠在一起的小山丘)。

我最近发现的一个好方法是使用多个Perlin噪声制作分形,但具有不同的“分辨率” - 如果您愿意,将它们相加以获得使用不同八度音高(即高八度=地形中的高噪声)的自定义地形分辨率。我通常使用增益= 0.5(这实际上不需要太多更改,看起来非常好),以及八度数=〜16。

注意:这是在Processing中完成的,Java可能具有一些不同的语法,但应该基本相同

float fractal(int x,int y,float gridSubs,float gain,int octaves){
  float total = 0;
  float freq = 1.0/gridSubs;
  float amp = gain;

  for(int f=0;f<octaves;f++){
    total += noise(x*freq,y*freq)*amp;
    freq *= 2.0;
    amp *= gain;
  }
  return total;
}

我在这里找到了相关网站:这里

如果你用这个替换你的noise()函数,最终可能会得到更好的结果。


至于你的接缝问题,你很可能把每个块中噪声函数调用的坐标偏移量设置错误了,应该像这样:

noise( localX * tileSize + (chunkX * chunkSize) , localZ * tileSize + (chunkZ * chunkSize) );

您可能需要添加一些分辨率系数,使噪声变得更平滑。


现在,您说您正在将高度值存储在2D高度图中,这很好,如果您需要经常更新它们或需要轻松访问它们,则可以很容易地访问高度值。

问题在于数组的大小非常大,我指的是非常大。根据我的经验,我曾经加载一个小地图(记不清了,但比你的小),耗用了4 GB 的存储器。不过,我使用的是浮点数组,使用整型数组可能会稍微减少内存使用。

现在我如何做是每当我需要更新几何图形时就重新计算地形中的每个点,我目前的设置会在移动时每次更改地形时引入轻微的延迟。好处是,我可以拥有4倍更大、更详细的地图,仍然只使用约1-2GB 的 RAM。

由于我理解您只是想在地形周围移动和查看它,因此最好不要将高度图存储在数组中,因为在生成地形后您实际上并不需要这些值(如果您手动平滑地形,情况可能有所不同)。


最后请注意一件事:我不是专业程序员,这只是我从使用随机生成的噪声中学到的经验。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接