Houdini Engine経由でHoudiniのHeight FieldをUnreal EngineのLandscapeにする

HoudiniのHeight Fieldで地形を生成し、Houdini Engineを使用してUnreal EngineのLandscapeとして読み込んでみます。

各ツールの使用しているバージョンは次のとおりです。

- **Houdini**: 19.5.349
- **Houdini Engine for Unreal**: 19.5.349
- **Unreal Engine**: 5.0.3

この記事ではHoudini Engine for Unrealを使用しますが、セットアップの方法については特に解説しません。

## HoudiniでHeight Fieldを作成する

ネットワーク全体は次のようになります。このネットワークをHoudini Digital Asset(HDA)として出力します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/47dda67c-4604-54f9-7e51-c174b2426e97.png" width="50%">

### 地形の作成

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/c8d38039-2fa7-385f-f631-237b25a0bc67.png" width="50%">

今回は地形の生成自体が本題ではないので、シンプルなHeight Fieldを作成します。`HeightField Noise`ノードで大まかな地形を作成し、`HeightField Distort by Noise`ノードで地形にディテールを追加します。`HeightField Erode`ノードで地形らしさを追加します。

### レイヤーの作成

Unreal EngineのLandscape Materialで使用するためのレイヤーを作成します。今回は`grass`(草地)レイヤーと`rock`(岩場)レイヤーを作成します。Houdini側ではレイヤーを作成しませんが、`grass`でも`rock`でもない箇所は地面(`ground`)になります。

#### 草地レイヤー

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/5d273bff-5b54-3143-ec7a-0fdf5878e616.png" width="50%">

`HeightField Mask by Occlusion`ノードでオクルージョンが小さい箇所のマスクを生成し、`HeightField Blur`ノードで境界を滑らかにします。生成した`mask`を`HeightField Copy Layer`で`grass`という名前のレイヤーにコピーします。作成した`grass`レイヤーは次のようになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/1fca31ab-5ac4-0436-4878-e7220b082ad0.png" width="50%">

#### 岩場レイヤー

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/f072ac18-48d3-d0aa-f910-418113888157.png" width="50%">

`rock`レイヤーは`HeightField Mask by Feature`ノードの`Slope`を用いて生成し、`grass`レイヤーと同じように`HeightField Copy Layer`ノードを用いてコピーします。作成した`rock`レイヤーは次のようになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/7e172cf7-e0da-5783-0b12-cbb1ca6c9e58.png" width="50%">

### ビジュアライゼーション

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/663655f2-c25d-9375-89f7-e43dca5ce42b.png" width="50%">

Unreal Engineへのエクスポートには不要ですが、作成したレイヤーを確認するために`HeightField Visualize`ノードで色付けします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/a3aecd5b-be0b-0f9e-ae6e-7ea1cef3bd09.png" width="50%">

色付けしたした結果、次のようになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/7c39ca3b-05aa-21bd-ea74-f400f1830fdb.png" width="50%">

### 不要なレイヤーの削除

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/1fcded23-a4ef-cca0-9dfe-15e5e5688380.png" width="50%">

`HeightField Erode`ノードで種々のレイヤーが作成されますが、Unreal Engine側では不要なので`Delete`ノードで削除します。この操作は必ずしも必要ではありませんが、その場合はUnreal Engineで読み込んださいにLandscapeのレイヤーに不要なレイヤーも表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/2b4a7535-93d3-c3ab-9fde-052c8500e51b.png" width="50%">

### Non Weight Blended Layerの設定

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/550d8653-1a11-364f-0d9d-7c8b32c34b74.png" width="50%">

通常、LandscapeのHDAをUnreal Engineに読み込むとレイヤーはWeight Blended Layerとして読み込まれますが、今回は他のレイヤーの重み付けに影響を受けたくないのでNon Weight Blended Layerとして読み込まれるようにします。そのために`unreal_landscape_layer_nonweightblended`attributeを設定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/af69f7a1-9eb5-f1e0-d318-7240b2887c84.png" width="50%">


## Unreal EngineでLandscapeを生成する

Houdiniから出力したHDAをUnreal Engineで読み込み、レベルに配置します。Landscapeが生成され、`grass`と`rock`のレイヤーがNon Weight Blended Layerとして存在することが確認できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/a21c23fd-9990-7b92-6acc-27852250ff17.png" width="50%">

### Landscape Materialを作成する

HDAから生成したLandscapeに適用するLandscape Materialを以下のように作成します。`Ground`レイヤーは最下層の地面になるレイヤー、`Grass`と`Rock`はHoudiniで生成した`grass`と`rock`のレイヤーに対応します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/6f5d459e-6f7d-2e77-6eff-5cfe7b072810.png" width="50%">

今回は地面→草地→岩場という順でオーバーレイされるように地形を塗りたいので、`Landscape Layer Blend`ノードの`Blend Type`はすべて`LB Alpha Blend`にします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/eaa87133-3601-8a7a-4679-fad9663f3909.png" width="50%">

作成したLandscape MaterialをLandscapeに適用します。`Ground`レイヤーの`Landscape Layer`オブジェクトが存在しないので、`Non Weighted Blended Layer`として作成し、右クリックから「レイヤーを塗りつぶす」ですべて塗りつぶします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/29ca25f8-4424-ef24-2f3c-270b60e35538.png" width="50%">

## 完成

HoudiniのHeight FieldをUnreal EngineのLandscapeとして読み込むことができました。
![ue_hda_with_material_2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/f61b3a39-ce2f-7e90-c1c7-2d98df9640ce.png)

## 参考

- [Houdini Engine for Unreal: Landscapes](https://www.sidefx.com/docs/unreal/_landscapes.html)