逼真的2D地形图生成

时间:2009-09-19 18:42:44

标签: 2d generator terrain

我正在寻找一些允许我生成逼真的2D地形图的算法。 通过现实我的意思是,这个人会将这样的地图视为“普通”地形图,而不是人工创建的。 我不想创建逼真的地图。只是类似于可以在地理地图集中查看的地图。

到目前为止,我正在使用perlin noise作为高度图,然后我将添加湖泊,河流,山脉,沼泽等。您可以在下面的图片中查看它的外观:

Terrain map http://www.freeimagehosting.net/uploads/1f1e9372bf.png

我对它不满意。这是不现实的,但我不能自己找出更好的东西。时间不是问题所以算法可能是繁重的计算。

感谢您的时间。

编辑后:

我想我找到了一篇可以提供帮助的文章:http://portal.acm.org/citation.cfm?id=1255047.1255077

然而,它无法免费获得,所以我仍然在寻找答案或想法。

4 个答案:

答案 0 :(得分:5)

我以前玩过地形。假设目标是位图,我找到了一种方法来制作像河流一样的东西,并且通常会让它看起来更好:侵蚀。

一旦你通过其他方式生成的地形侵蚀了一下:你需要以像素高度表示的世界。在地图上取一个点并将一个高度单位移动到最低邻居。将光标移动到该邻居并重复直到它不移动。重复其他像素。

使河流计算您通过位置移动位的次数。受到最多打击的地方是河流。

跟进:我没有像每个像素那么多地侵蚀每个像素,直到风化得足够多。实际上侵蚀它们的原因是它带有位并填充空洞。没有它,就没有河流,因为会有流动的陷阱 - 流动的像素会填满任何小洞并形成工作水道。

对不起,我不能提供任何样品,这是多年前的事情,虽然旧代码可能在某处,我不知道在哪里看。

答案 1 :(得分:2)

地形是由许多不同时间尺度上的无数不同原因造成的。为了真正创建逼真的地形,你必须模拟它们。

在“短”期内,水圈决定了大部分特征。您可以从包含主要特征(山脉等)的体素/粒子/高度图/网格地形开始,并将其视为不可变的,然后使用大量的水模拟进行后处理。您需要计算河流和湖泊的位置,它们如何侵蚀基础景观以及它们形成沉积物的位置。如果我必须对此进行编码,我可能会从3D体素世界开始。

这将是一项庞大的任务,我确信有很多技巧可用于生成需要毫秒而不是几分钟的特定地形类型。你想要创造什么样的地形?多山?低地?工业化?森林?沙漠?群岛?

长话短说:如果你想要对人类看起来很逼真的地形(毕竟这些人都是这方面的专家),你必须通过模拟实际的地质过程来创造它。

答案 2 :(得分:1)

我在Terra3D中的方法是生成随机高度值,然后进行3次平滑过程,并在算法中写入一点重塑。重塑导致水线下方的地形向下移动一点,水线以上的一切都向上移动了一点。虽然效果很好,但是很多山丘和小湖泊。这可能不是你正在寻找的东西。

但是,我不相信我的方法背后的原则不能用来得到你想要的东西。您可能只需要在整形/平滑算法中写入更多条件。例如,减少较高海拔地形上的平滑量将产生更多的岩石山峰外观。然后编写一个更复杂的平滑(或高斯)算法,进一步延伸到较低的高程,可以将这些湖泊拉到一起形成自然河流。

以下是您感兴趣的Terra3D中地形生成的代码:

  // GENERATE TERRAIN
  for (i = 0; i < MAX; i++)
  {     
    for (i2 = 0; i2 < MAX; i2++)
    {
        if (i<10 || i2<10 || i>MAX-10 || i2>MAX-10)
        field[i][i2].y=0;
      else
        field[i][i2].y=(GLfloat(rand()%151)-75)/50+(field[i-1][i2-1].y+field[i-1][i2].y+field[i-1][i2+1].y+field[i-1][i2-2].y+field[i-1][i2+2].y)/5.05;
    }
  }

  // SMOOTH/RESHAPE TERRAIN
  for (int cnt = 0; cnt < 3; cnt++)
  {  
    for (int t = 1; t < MAX-1; t++)
    {
      for (int t2 = 1; t2 < MAX-1; t2++)
      {
        field[t][t2].y = (field[t+1][t2].y+field[t][t2-1].y+field[t-1][t2].y+field[t][t2+1].y)/4;

        if (cnt == 0)
        {
          if (field[t][t2].y < -1 && field[t][t2].y > -1-.5) field[t][t2].y -= .45, field[t][t2].y *= 2;
          else if (field[t][t2].y > -1 && field[t][t2].y < -1+.5) field[t][t2].y += .5, field[t][t2].y /= 5;
        } 
      }
    }
  }

这是我10年前写的邋code的代码。 Terra3D是一个漫长的实验过程,在黑暗中摸索产生我想要的效果。但也许它会有所帮助。

答案 3 :(得分:1)

我知道这是一个非常古老的问题,但我正在回答这个问题,因为未来的人们正在寻找一个好的地形发生器,就像我一样。使用World Machine 2的免费版本。它是一个地形生成器,可以完全按照您的要求进行操作。它已被专业人士用于生成图像,3D世界地形,甚至是您所建议的地图。请注意,免费版仅用于非商业用途。