【Unreal Engine】LandscapeLayerBlendのBlend TypeとランドスケープレイヤーのWeight Blendの関係

Unreal EngineのLandscapeでマテリアルのブレンドの挙動がよくわからず思ったようにペイントできなかったので、それに関わるマテリアルの`LandscapeLayerBlend`ノードの`Blend Type`とランドスケープレイヤーの`Weight Blend`について調査しました。

## LandspaceLayerBlendノードのBlend Type

`LandscapeLayerBlend`の`Blend Type`プロパティには3つの選択肢`LB Weight Blend`、`LB Alpha Blend`、`LB Height Blend`があります。公式ドキュメントの解説はそれぞれ次のようになっています。

**LB Weight Blend**
> このモードは、World Machine などの外部プログラムのレイヤーを使用している場合や、レイヤーの順序を気にすることなく相互に独立したレイヤーをペイントできるようにしたい場合に使用します。

**LB Alpha Blend**

> 細部にペイントしたい場合や、レイヤーの順序が定義されている必要がある場合に、使用します。例えば、岩や草の上の雪をペイントすると、それらをオクルードできますが、雪を消すとその下の岩や草があらわれます。

**LB Height Blend**

> これは LB_WeightBlend と同じですが、高さマップに基づいたレイヤー間の遷移に詳細も追加します。これを使用すると、例えば、岩と泥との間のスムーズなブレンドの代わりに、レイヤーの遷移点にある岩どうしの隙間に土が現れるようにすることができます。

引用: [ランドスケープ マテリアル \| Unreal Engine ドキュメント](https://docs.unrealengine.com/4.26/ja/BuildingWorlds/Landscape/Materials/)


解説によると`LB Weight Blend`はレイヤーの順番によらず各レイヤーのウェイトに基づいてブレンドを行います。推測ですが、3つのレイヤー`A`、`B`、`C`があり、それぞれのウェイトが`1.0`、`0.5`, `0.3`のとき`A`、`B`、`C`それぞれの影響は`1.0/(1.0+0.5+0.3)=0.555...`、`(0.5)/(1.0+0.5+0.3)=0.277...`、`(0.3)/(1.0+0.5+0.3)=0.166...`のようになるのだと思います。
 `LB Alpha Blend`はレイヤーの順番が影響し、上のレイヤーが下のレイヤーを隠すようになるということが想定できます。上のレイヤーのウェイトが`0.8`のとき、`(1.0-0.8)*(下のレイヤー)+0.8*(上のレイヤー)`みたいな計算が行われるのだと思います。
`LB Height Blend`は高さも考慮した`LB Weight Blend`なようです。基本的には`LB Weight Blend`と同じで応用的な利用方法のようなので、この記事ではこれ以上は触れません。

## ランドスケープレイヤーのWeight Blend

ランドスケープレイヤーのWeight Blendには`Weight Blended Layer`と`Non Weight Blended Layer`の2つがあります。公式ドキュメントの解説はそれぞれ次のようになっています。

**Weight Blended Layer (normal)**

> 相互に影響を及ぼす従来のレイヤーです。ウェイトがブレンドされたレイヤーのペイントは、他のウェイトがブレンドされたレイヤー全てのウェイトを減少します。例えば泥のペイントは草を取り除いて、草をペイントすると泥が取り除かれます。レイヤー情報オブジェクトの中で最もよく使用されます。

**Non Weight Blended Layer**

> 互いに独立しているレイヤーです。ウェイトがブレンドされていないレイヤーをペイントしても、その他のレイヤーのウェイトに影響は及びません。このレイヤーは別のレイヤーに雪をブレンドするなど、より高度なエフェクトの作成に使用します。草、泥、岩 _または雪を作成する代わりに、重みがブレンドされていない雪レイヤーを「草、泥または岩」とブレンドして、「雪の積もった草、泥、または岩」を作成します。

引用: [Paint モード \| Unreal Engine ドキュメント](https://docs.unrealengine.com/4.26/ja/BuildingWorlds/Landscape/Editing/PaintMode/)


`Weight Blended Layer`と`Non Weight Blended Layer`の違いはペイントした際に他のレイヤーのウェイトに影響するかどうかのようです。`Weight Blend Layer`の場合はペイントするとそのレイヤーのウェイトを増加させるだけでなく、他のレイヤーのウェイトを減少させます。それに対して`Non Weight Blended Layer`は、ペイントしてもそのレイヤーのウェイトを増加させるだけで、他のレイヤーのウェイトには影響しないみたいです。例示されている使用方法を考慮すると`Non Weight Blended Layer`は`LB Alpha Blend`と組み合わせて使用すると良さそうです。

## 検証

以下のように`Red`と`Green`という2つのレイヤーを持つシンプルなマテリアルを使って検証していきます。
![Material.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/11a12700-72fd-a002-89f1-9d1a5b1296d3.png)

まず、`Red`と`Green`の設定を両方とも`LB Weight Blend`、`Weight Blended Layer`にして試してみます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/37c52242-5d3c-df69-b381-28804384b13c.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/de7be434-d98d-d72f-e392-167b9064e91f.png" width="50%">
`Red`が塗りつぶしの状態(赤色)で`Green`をペイントすると緑色になり、その上に`Red`をペイントすると赤色になります。`Green`をペイントすると赤色の成分がなくなることから、`Weight Blended Layer`の解説通り、ペイントしているレイヤー(`Green`)のウェイトを増加させるだけでなく他のレイヤー(`Red`)のウェイトを減少させていることがわかります。
![Blend-Blend_Weight-Weight.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/aef6fe0d-4c4c-1046-660f-66186f86a330.gif)

---

`Blend Type`は`LB Weight Blend`のままで、`Red`と`Green`の両方を`Non Weight Blend Layer`にした場合を試します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/37c52242-5d3c-df69-b381-28804384b13c.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/cd41bc2a-b35c-a601-1525-bce422cc1279.png" width="50%">
この場合は、`Red`が塗りつぶしの状態(赤色)で`Green`をペイントすると黄色になり、その上から`Red`をペイントしても変化が起きませんでした。先の解説の通り`Non Weight Blend Layer`では`Green`をペイントしても`Green`のウェイトが増加するだけで`Red`のウェイトは減らないので、両方のウェイトが最大となった結果、赤色と緑色を足した色である黄色になりました。すでに`Red`のウェイトは最大なので、この状態で`Red`をペイントしても何も変わりません。
![Blend-Blend_Non-Non.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/9fd506af-f5e9-576a-cf15-1ae4a132750a.gif)
`Red`を`Weight Blended Layer`にしても同じ挙動になりました。このことから`Weight Blend Layer`でのペイントも、`Non Weight Blend Layer`のウェイトには影響しないことがわかります。

---

`Red`を`LB Weight Blend`で`Weight Blended Layer`、`Green`を`LB Alpha Blend`で`Non Weight Blended Layer`にして試してみます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/4ca7c514-53f6-5b9b-efae-f55ce2495f9d.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/b585fc4d-5b7e-0bd4-18c9-7fab812c8494.png" width="50%">
`Red`が塗りつぶしの状態(赤色)で`Green`をペイントすると緑色になり、その上から`Red`をペイントしても変化が起きませんでした。`Green`は`Non Weight Blended Layer`なのでペイントにより`Red`のウェイトを減少させませんが、`Red`に対して上のレイヤーである`Green`のウェイトが増加したことで`LB Alpha Blend`により赤色が隠されて緑色になります。
![Blend-Alpha_Weight-Non.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/c47bc0cb-935e-340a-ee51-bd8f23a7df1f.gif)
`Red`の`Blend Type`を`LB Alpha Blend`にした場合や、`Red`を`Non Weight Blend Layer`をした場合でも同じ結果になりました。

---

`Red`、`Green`を両方とも`LB Alpha Blend`、`Weight Blended Layer`にしてみます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/f5f63c14-d877-7302-6764-baed4142761e.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/4367441e-a9c9-969c-b716-ce55479935fe.png" width="50%">

`Red`が塗りつぶしの状態(赤色)で`Green`をペイントすると緑色になり、その上から`Red`をペイントすると赤色になります。`Green`は`LB Alpha Blend`ですが、`Weight Blended Layer`になっているので、先ほどの挙動とは異なり`Red`をペイントすると`Green`のウェイトが減り赤色が表示されます。
![Alpha-Alpha_Weight-Weight.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/1d7dcd4e-50ee-1c39-4a6a-26f1079b8071.gif)

---

レイヤーが3つの場合のパターンもいくつか試してみます。
![Material2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/629fc374-16a0-6ae0-5f81-60d38f2d2e52.png)

`Red`、`Green`が`LB Weight Blend`で`Weight Blended Layer`、`Blue`が`LB Alpha Blend`で`Non Weight Blended Layer`の場合です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/ac52bcaf-9869-3f56-dd92-45574052e28c.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/8842e761-59c1-fc22-532f-adf9e109f843.png" width="50%">

`Red`と`Green`がウェイトに基づいてブレンドされ、その上に`Blue`がオーバーレイされます。
![Blend-Blend-Alpha_Weight-Weight-Non.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/400e635e-4842-ec48-b553-75475f9aec98.gif)

---

`Red`、`Blue`が`LB Weight Blend`で`Weight Blended Layer`、`Green`が`LB Alpha Blend`で`Non Weight Blended Layer`の場合です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/8cf59592-64e4-e3ba-828b-ddf7c627c53e.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/c9363347-7bb0-9bfc-3d3c-c48ba4d2f92e.png" width="50%">

`Red`と`Blue`がウェイトに基づいてブレンドされ、その上に`Green`がオーバーレイされます。レイヤーの順番的には`Green`よりも`Blue`の方が上ですが、それには関係なく`LB Alpha Blend`がオーバーレイするようです。
![Blend-Alpha-Blend_Weight-Non-Weight.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/137d69d4-51f4-5eb5-a722-0938c07cbc57.gif)


---

`Red`が`LB Weight Blend`で`Weight Blended Layer`、`Green`、`Blue`が`LB Alpha Blend`で`Non Weight Blended Layer`の場合です。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/f7281f1d-ce82-a4f4-965c-797f222436c3.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/07584683-f5a7-fd50-1a61-43f2a5ecf12a.png" width="50%">

`Red`の上に`Green`が、`Green`のさらに上に`Blue`がオーバーレイします。`LB Alpha Blend`が複数ある場合はレイヤー順にオーバーレイされていくようです。
![Blend-Alpha-Alpha_Weight-Non-Non.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/44ef74f3-8c9a-0877-e8e3-f84bf336bf87.gif)

## まとめ

検証結果を踏まえてわかったことです。

- `LB Weight Blend`はウェイトに基づいて他の`LB Weight Blend`のレイヤーとブレンドされる。
- `LB Alpha Blend`はレイヤー順に関わらず`LB Weight Blend`でブレンドした値の上にオーバーレイされる。複数の`LB Alpha Blend`がある場合はレイヤー順でオーバーレイされる。
- `Weight Blended Layer`はペイントすると自レイヤーのウェイトを増加させるだけでなく、他の`Weight Blended Layer`のウェイトを減少させる。
- `Non Weight Blended Layer`はペイントすると自レイヤーのウェイトを増加させるだけで、他のレイヤーのウェイトには影響しない。