Edited at

[DTL]バイオーム生成(パーリンノイズ法)🌏


🌏母なる大地を創造する🌏

今回はパーリンノイズ法を用いたバイオーム生成について簡単に解説します。


🌏パーリンノイズとは🌏

"パーリンノイズ"は地形生成に適した"ノイズアルゴリズム"です。

あの超有名なゲームである"マインクラフト"でも使われています。

また、マインクラフトのワールドでは バイオームを生成 しており

様々な生物群系 を取り入れています。



ゲームで使用されるパーリンノイズの例


🌏前回紹介した生成の応用🌏

[DTL]地形生成(パーリンノイズ法)🌏

で紹介したパーリンノイズ法による地形自動生成を用いてバイオームを作っていきます。


🌏バイオームを作るために必要なモノ🌏

バイオーム生成には

"年平均気温"と"年降水量"に近似した2つの変数が必要です。



実世界のバイオームの大まかな区分はこんな感じ。


🌏バイオーム変数を定義🌏


main関数

 using shape_t = std::uint_fast8_t;

constexpr std::size_t size_x{ 512 };
constexpr std::size_t size_y{ 512 };
//温度
std::unique_ptr<float[][size_x] > temperature(new(std::nothrow) float[size_y][size_x]);
dtl::shape::PerlinIsland<float>(6.0, 8, -20.0f, 60.0f).draw(temperature, size_x, size_y);
//降水量
std::unique_ptr<std::uint_fast16_t[][size_x] > amount_of_rainfall(new(std::nothrow) std::uint_fast16_t[size_y][size_x]);
dtl::shape::PerlinIsland<std::uint_fast16_t>(6.0, 8, 0, 4500).draw(amount_of_rainfall, size_x, size_y);
//標高
std::unique_ptr<shape_t[][size_x] > elevation(new(std::nothrow) shape_t[size_y][size_x]);
dtl::shape::PerlinIsland<shape_t>(6.0, 8, 200).draw(elevation, size_x, size_y);
//バイオーム
std::unique_ptr<shape_t[][size_x] > biome(new(std::nothrow) shape_t[size_y][size_x]);



"年平均気温"と"年降水量"に近似した2つの変数を作成しました。

処理がしやすいように単純にしています。

この2つの変数を用いてバイオーム分けしていきます。

ここで、標高といったまた別の変数が定義されていますが

これは 陸地と海を区別するため に用います。


🌏バイオームを生成🌏


main関数

 for (std::size_t row{}; row < size_y; ++row)

for (std::size_t col{}; col < size_x; ++col) {

//海
if (elevation[row][col] < 90) biome[row][col] = 0;
//ツンドラ
else if (temperature[row][col] < -5.0f) biome[row][col] = 1;
//砂漠
else if (amount_of_rainfall[row][col] < 500) biome[row][col] = 2;
else if (amount_of_rainfall[row][col] < 1500) {
//ステップ
if (temperature[row][col] < 20.0f) biome[row][col] = 3;
//サバンナ
else biome[row][col] = 4;
}
//針葉樹林
else if (temperature[row][col] < 3.0f) biome[row][col] = 5;
//夏緑樹林
else if (temperature[row][col] < 12.0f) biome[row][col] = 6;
//照葉樹林
else if (temperature[row][col] < 20.0f) biome[row][col] = 7;
//雨緑樹林
else if (amount_of_rainfall[row][col] < 2500) biome[row][col] = 8;
//亜熱帯多雨林
else if (temperature[row][col] < 24.0f) biome[row][col] = 9;
//熱帯多雨林
else biome[row][col] = 10;
}


図の数値通りにバイオーム分けするプログラムを書きます。



"年平均気温"と"年降水量"のみで作成したバイオーム。



"年平均気温"と"年降水量"と"標高"を用いて作成したバイオーム。

海と陸地を分けている。


🌏バイオーム画像の保存🌏


main関数

 dtl::storage::FilePNG<shape_t>("file_sample_biome.png", 3).write(biome, size_x, size_y, [](const shape_t value, unsigned char* const color) {

switch (value) {
//海
case 0:
color[0] = 41;color[1] = 40;color[2] = 159;
break;
//ツンドラ
case 1:
color[0] = 218;color[1] = 217;color[2] = 225;
break;
//砂漠
case 2:
color[0] = 223;color[1] = 203;color[2] = 140;
break;
//ステップ
case 3:
color[0] = 188;color[1] = 205;color[2] = 146;
break;
//サバンナ
case 4:
color[0] = 164;color[1] = 143;color[2] = 50;
break;
//針葉樹林
case 5:
color[0] = 97;color[1] = 154;color[2] = 96;
break;
//夏緑樹林
case 6:
color[0] = 101;color[1] = 163;color[2] = 56;
break;
//照葉樹林
case 7:
color[0] = 9;color[1] = 100;color[2] = 5;
break;
//雨緑樹林
case 8:
//亜熱帯多雨林
case 9:
//熱帯多雨林
case 10:
color[0] = 43;color[1] = 84;color[2] = 41;
break;
}
});
return 0;
}

生成したバイオームの画像をPNG形式で保存します。

これで出力は完了です。


🌏完成🌏

無事に実装できました。


🌏実装ライブラリ(ソースコード)🌏

今回解説した地形自動生成は"Dungeon Template Library""PerlinIsland"として実装されています。

ぜひ、活用してみてください!


🌏ソースコードのライセンス🌏

These codes are licensed under CC0.

この記事のソースコードはCC0ライセンスとします。

ぜひ、自由に改変して遊んでみてください。

"いいね"をつけてくださると大変励みになります。

最後までお読みいただきありがとうございました!