我一直在研究perlin噪音的应用程序我正在研究它基本上是一个'二维侧视图'看游戏(模拟)。我不完全理解perlin噪声是如何工作的,但是得到了一般的想法。
我发现这篇文章的代码为Perlin Noise,并决定在此之前给出它,我现在设置世界的方式是每个“块”有16x16块,我刚刚声明如果Y&gt ; = HEIGHT / 2使所有瓷砖'坚固''其他'空气'以便正常工作......但是土地非常平坦,正如您想象的那样。那就是我认为perlin噪音会进来的地方,所以我使用了上面网站上的代码,但我不确定如何将噪音转换成固体/空气砖。
正如你所看到的不是很逼真的地形
我正在寻找下面的地形。应该看起来像山脉和连绵起伏的丘陵)我不担心锋利的边缘(方形)
我不知道如何遍历tile数组以将噪音转换为
目前我正在迭代瓷砖阵列(2d),但正如您从第一张图片中看到的那样,它只是随机化瓷砖是否是实心的,它不会产生任何起伏的丘陵或山脉。
for(int Y = 0;Y < HEIGHT;++Y) {
for(int X = 0;X < WIDTH;++X) {
Tile Tile;
if(noise(X,Y) < 0) {
Tile.Type = BLOCK;
} else {
Tile.Type = Air;
}
// Then I push the Tile on to a vector
我还应该提到,在这个16x16'块'的右侧,还有另一个块需要与这个块匹配,之后的下一个块也是如此。如果有意义的话,块不应该和以前一样只是让它看起来不是单独的块。
非常感谢任何帮助!谢谢
更新
我已将perlin函数更改为this的函数,并且已实现phresnel建议的内容:
PerlinNoise *test=new PerlinNoise(0.25, 6); //0.25 is Persistance 6 is Octaves
float f,h;
float seed = 804.343;
for (int X=0; X!=MAP_WIDTH; ++X) {
f = test->GetNoise((X * ChunkX) * seed);
h = f * MAP_HEIGHT + (MAP_HEIGHT / 2);
for (int y=0; y<h; ++y) {
Tile tempTile;
tempTile.Tile = TILE_NONE;
Tiles[X][y] = tempTile;
}
for (int y=h; y<MAP_HEIGHT; ++y) {
Tile tempTile;
tempTile.TileID = TILE_BLOCK;
Tiles[X][y] = tempTile;
}
}
这样做后看起来好多了,我X * ChunkX
每个噪音好像我没有每个块都是一样的,所以现在它看起来像下面的
正如你所看到的,地形比我以前想要的更多,但仍然看起来不像真正的地形,因为它不是很光滑,有什么我可以做的顺利创建连绵起伏的山丘和平原
的整体外观我在该噪点值下删除了tile的创建,因此更容易看到范围
正如您所看到的那样,它只需要“平滑”,因此它们看起来不像伪随机值。我也想知道为什么左边看到的第一个块具有相同的值。
感谢。
答案 0 :(得分:4)
你的结果很好,因为你有岛屿,大陆,池塘和海洋。 Perlin噪声可以帮助您生成非随机字符的随机地形。
您基本上将噪声函数的(数学上)无限分辨率降低为仅包含两个不同图块的离散集合,以及块的非常有限的分辨率。鉴于此,您的结果似乎很好。
不同的事情可能会改善您的结果。例如,瓷砖图形之间的lerp:
// Exemplary p-code, fine-tuning required
Color color_at (x, y) {
Real u = x / width, v = y / height
Real f = min (max(noise(u,v), 0), 1);
Color c = water*f + hill*(1-f);
return c;
}
您可以为任何图块计数推广lerp函数。
锋利边缘的另一种可能性受Voronoi diagrams (1)的启发。您具有与上面相同的功能,但不是内插,而是采用最接近噪声值的图块:
Color color_at (x, y) {
Real u = x / width, v = y / height
Real f = min (max(noise(u,v), 0), 1);
if (f<0.5) return water;
else return hill;
}
这与你的相同,只是你以像素方式进行。同样,这可以概括。
一旦你有一个很好的设置,你可以使用噪音:植物/树木分布,敌人分布,动画(这将是一个噪音功能)等。
编辑您的评论:
如果您需要侧视图,如经典的2d-jump并运行,请考虑1d噪声函数,从0迭代到图像宽度,每次停止采样 f 对于噪声函数,将 f 转换为屏幕空间,然后上面的每个像素都将成为天空的一部分,下面的每个像素都将从你的瓷砖中取出:
for (int x=0; x!=width; ++x) {
// Get noise value:
f = noise1d (x/width);
h = f * height + (height/2); // scale and center at screen-center
// Select tile:
Tile *tile;
if (h < waterLimit) {
h = waterLimit;
tile = waterTile;
} else {
tile = terrainTile;
}
// Draw vertical line:
for (int y=0; y<h; ++y)
setPixel (x, y, skyColor(x,y));
for (int y=h; y<height; ++y)
setPixel (x, y, tileColor(x,y, tile));
}
再次,示例性伪代码。
噪音功能非常灵活。如果你想要更少的蓝色和更多的绿色,只需降低常数项,即不是if(h < 0) -> blue
,而是if(h < -0.25) -> blue
。
1:我从未尝试过这种方法,因为我正在进行三维地形渲染(picogen.org)