バイオームのプロシージャル生成 - パーリンノイズアルゴリズム

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

![PN512](https://kasugaccho.github.io/DungeonPicture/Picture/Terrain/pibi512.gif)

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

# 🌏パーリンノイズとは🌏

**"パーリンノイズ"**は地形生成に適した**"ノイズアルゴリズム"**です。
あの超有名なゲームである**"マインクラフト"**でも使われています。

また、マインクラフトのワールドでは **バイオームを生成** しており
**様々な生物群系** を取り入れています。

![mcp](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213065/77c3394b-40e5-5bb4-c800-d4f1f6f68c5a.png)
**ゲームで使用されるパーリンノイズの例**

# [🌏前回紹介した生成の応用🌏](https://qiita.com/Gaccho/items/ba7d715901a0e572b0e9)

[**[DTL]地形生成(パーリンノイズ法)🌏**](https://qiita.com/Gaccho/items/ba7d715901a0e572b0e9)
で紹介したパーリンノイズ法による地形自動生成を用いてバイオームを作っていきます。

[![pib](https://Kasugaccho.github.io/DungeonPicture/Picture/Terrain/PIB256.gif)](https://github.com/Kasugaccho/DungeonTemplateLibrary/wiki/dtl::shape::PerlinIsland-(%E5%BD%A2%E7%8A%B6%E3%82%AF%E3%83%A9%E3%82%B9)) ![pii](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213065/1ee81ea3-6b99-e06d-3f80-963ee9956082.gif)

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

バイオーム生成には
**"年平均気温"と"年降水量"に近似した2つの変数が必要です。**

![PN512](https://kasugaccho.github.io/DungeonPicture/Picture/reference/biomehyou2.png)
実世界のバイオームの大まかな区分はこんな感じ。

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

```cpp: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]);
```

![PN512](https://kasugaccho.github.io/DungeonPicture/Picture/reference/biomehyou_p2.png)
**"年平均気温"と"年降水量"に近似した2つの変数を作成しました。**
処理がしやすいように単純にしています。
この2つの変数を用いてバイオーム分けしていきます。

ここで、**標高**といったまた別の変数が定義されていますが
これは **陸地と海を区別するため** に用います。

# 🌏バイオームを生成🌏

```cpp: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;
  }

```

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

![PN512](https://kasugaccho.github.io/DungeonPicture/Picture/reference/file_sample_biome_uminashi.png)
**"年平均気温"と"年降水量"のみで作成したバイオーム。**

![PN512](https://kasugaccho.github.io/DungeonPicture/Picture/reference/file_sample_biome.png)
**"年平均気温"と"年降水量"と"標高"を用いて作成したバイオーム。**
海と陸地を分けている。

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

```cpp: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形式で保存します。
これで出力は完了です。


# 🌏完成🌏

無事に実装できました。

[![PN512](https://kasugaccho.github.io/DungeonPicture/Picture/Terrain/pibi512.gif)](https://github.com/Kasugaccho/DungeonTemplateLibrary/wiki/dtl::shape::PerlinIsland-(%E5%BD%A2%E7%8A%B6%E3%82%AF%E3%83%A9%E3%82%B9))

# [🌏実装ライブラリ(ソースコード)🌏](https://github.com/Kasugaccho/DungeonTemplateLibrary)

今回解説した地形自動生成は**["Dungeon Template Library"](https://github.com/Kasugaccho/DungeonTemplateLibrary)**に**["PerlinIsland"](https://github.com/Kasugaccho/DungeonTemplateLibrary)**として実装されています。
ぜひ、活用してみてください！

[![logo640.gif](https://kasugaccho.github.io/DungeonPicture/Picture/Logo/logo_color640_3.gif)](https://github.com/Kasugaccho/DungeonTemplateLibrary)

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

These codes are licensed under CC0.
[![CC0](https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg "CC0")](http://creativecommons.org/publicdomain/zero/1.0/deed.ja)

この記事のソースコードはCC0ライセンスとします。
ぜひ、自由に改変して遊んでみてください。

**"いいね"をつけてくださると大変励みになります。**
**最後までお読みいただきありがとうございました！**