【UE4.24】新機能Hair Groomを使ってみた

## はじめに
こんにちは。
キャラクターアーティスト、コンセプトスカルプターのちろナモといいます。

この記事は
[Unreal Engine 4 Advent Calender 2019その2](https://qiita.com/advent-calendar/2019/ue4_deux)
の19日目として書かれています。


↓今回つくったもの
 オークの顔に髪の毛とヒゲを生やしてみました
https://twitter.com/you16_0823/status/1207309803749404672
![43c7fd47-4c05-40f0-9689-8ba0f313803e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/ef57406b-5f8c-c5a3-ded7-4efe19954919.png)
※背景アセットは [Enviroment Set](https://www.unrealengine.com/marketplace/en-US/product/environment-set)

## 概要
UE4.24で実験的に追加されたHair Groomプラグイン。MayaやHoudiniといった外部ツールでスタイリングしたものをalembic形式でインポートし、レンダリングやシミュレーションを行うことができるようになりました。ただしエンジン上でヘアスタイリングすることはできません。

ゲームエンジンで扱う髪の毛と言えばHair Cardと呼ばれる板ポリゴンにアルファ抜きしたテクスチャを使用する方法が一般的です。しかしこのプラグインを使えばCurveの一本一本を実際の毛として扱うことができ、毛の表現力が大幅に向上します。また各種マップのベイクやHair Cardを配置していく作業、複数チャンネルでのUV展開なども不要になりそうです。描画コストについては僕はさっぱり分からんですが、そこさえ解決されるならアーティストにとっては手放しで喜べる機能だと思います。

本記事ではHair Groomレンダリングしてみた感想や、今後期待することをつらつらと書こうと思います。

##使い方
https://docs.unrealengine.com/ja/Engine/HairRendering/index.html
↑公式ドキュメントに詳しく書いてありますので、英語ですが是非是非！

**■Alembicファイルを用意する**
まずはMayaやHoudiniといったツールから 毛をAlembic形式で書き出す必要があります。

Maya XgenからAlembicで書き出すには・・・
↓ XgenのDiscriptionを選択した状態で
　Generate > Cache > Export Cacheで書き出すことができます。拡張子は.abcです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/479211d2-f6e0-e622-1fa2-bc3061b68ea0.png)
`今回のオークのヘアースタイリングはBlenderで行いました。Blenderからエンジンに直接alembic形式で書き出す方法は検証しても見つからなかったため、一度Mayaにインポートして不要なポリゴンを削除したあとalembicで書き出しました。`
<br>

**■■エンジン側の準備**
↓編集 > プロジェクト設定 を開く
レンダリング > スキンキャッシュの計算をサポート を**ON**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/1b607bca-2a2d-9566-baba-3cde8d80337f.png)

↓アニメーション > スケルタルメッシュ初期化時のティックアニメーション を**OFF**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/a74b8686-692a-b108-8a55-09dcef17edd5.png)
以上2つは、Groomをスケルタルメッシュにバインドしてシミュレーションするには必要な設定のようです。

さらに、プラグインも有効化する必要があります。
↓編集 > プラグインを開き、Alembic Groom ImporterとGroomの2つをEnableにします。Restart Nowをクリックしエンジンを再起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/4e250bb9-7364-4094-ab52-b18b7fd5f53b.png)

**■■■エンジンにImport**
↓そのままImportをするだけで上手く読み込まれると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/3e5a7379-46b8-49e4-59ea-dbee5731d48b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/d74fc7e8-5b6e-8b22-dc5d-419367731f94.png)
`Blenderで毛を作成したので、そのまま書き出すとUE4ではサイズが100分の1になります。
そのため試しにImport OptionでScaleX, Y, Zをそれぞれ100にして読み込んでみました。
しかしそれではHairのレンダーが非常に汚い結果になってしまいました。
Exportする時点で100倍しておけば問題なく表示されました。`

<br>


**■■■■Hair Groomの設定**
レベルに配置してライトを当てるだけで非常にきれいなレンダリング結果になると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/48a8ca05-3997-debd-9868-a177448aa98b.png)
※背景アセットは [Enviroment Set](https://www.unrealengine.com/marketplace/en-US/product/environment-set)

GroomのDetailsで設定できる**Hair Width** と **Hair Shadow Density**は重要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/6bd12931-1ed9-07aa-b1fc-7f51551133a6.png)
**Hair Width**は髪の毛の太さです。
生やした本数にもよりますが0.015～0.03くらいの範囲で設定すればいいかと思います。

**Hair Shadow Density**の値を調整すると、Hair Card方式でいうAOマップの強度を調整したような結果になります。強度を上げれば奥行きのあるAOが乗り、全体的に暗めの髪色になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/f51762f7-f34c-34bd-e453-8061b1fbd964.png)
<br>

**■■■■■マテリアルの設定**
レベルに配置した時点で、エンジンコンテンツにあるHair Default Materialsが割り当たるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/79deeea1-13b1-2a41-7b87-bd93f431f10b.png)
このマテリアルを自分のプロジェクトフォルダにコピーして編集していきます。
↓Base ColorとRoughnessには、毛ごとにすこしランダムさを加えて自然な見栄えになるようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/ecf3d624-5bec-a9c1-2adc-ac551542f45f.png)
`現状ではワールドポジションオフセットやアンビエントオクルージョンなど、反応しないパラメータが多いです。
今後のアップデートで使えるようになるのだと思います。`



##雑感
まだ未実装の部分も多いですが、簡単に高クオリティのレンダリングがリアルタイムにできるってだけで、100点満点中100億万点です。楽しいです。
雑感としては以上です。

が、これでは素晴らしさを伝えられないので・・・

Groomプラグインが使われていないサンプルプロジェクト『Meet Mike』と比較してみます。
そうすればGroomプラグインによって何が便利になったのかが見えてくると思います。

↓ Epic Games Launcherからダウンロードできるデジタルヒューマンプロジェクト『Meet Mike』
　髪の毛はMayaのXgenのカーブを全てポリゴンにコンバートするという手法で作られています。しかも最適化のために一度Zbrushに持って行ったりして、泥臭くコンバートしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/bb485f33-d306-dfce-d6f3-efdd38782d6e.png)

**■毛がカメラを向く機能**
MayaのXgenなどには標準でついている機能です。毛の一本一本は厚みの無い板ポリゴンでありながら、常にポリゴンがカメラ方向を向くことで、どの角度からでも毛の厚みが一定に見える仕組みになっています。
『Meet Mike』プロジェクトではシェーダーのワールドポジションオフセットに刺さっている**「Min Width」**というマテリアルファンクションで行われていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/6efa6a49-ef40-55ce-497c-586941b6ec97.png)
↓**「Min Width」**の中身
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/9c9d6883-772c-a47b-090f-6cb0340f146b.png)

一方Hair Groomプラグインを使い、Groomとしてインポートしたものは勝手にCameraを向いてくれます。
シェーダーを触る必要は一切ありません。
便利！
<br><br>

**■■毛の太さ**
『Meet Mike』では毛の太さの調整についてもシェーダー内のワールドポジションオフセットで行っていました。
しかしGroomとしてインポートすれば、Detailsで変更することができるようになります。便利！
<br><br>

**■■■UV展開・テクスチャベイクが不要になるかも？**
↓『Meet Mike』で使用されているヘアポリゴンは、以下のようにUVが3チャンネル分展開されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/f1d849f7-9536-6203-1594-9c487a594c9b.png)
①すべてのStrand(髪の毛一本一本)がUVの0~1空間上に重ねられている。
　根本から毛先にかけて髪の色をグラデーションさせたり、ワールドポジションオフセットを使って太さを変えるときなどに使われる
②すべてのStrandが限りなく縮小されたうえで、重なりなく展開されている。
　Strandごとの色にランダムさを加えたり、↓のようなマスクを使用することで前髪だけ白髪を多く生やすような目的で使われる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/85c82ea3-89fd-6ee3-cacb-9d730fe81288.png)
③すべてのStrandが重なりなくある程度の面積を持った状態で展開されている。
　AOテクスチャやLightMap用として使う。これがあることで髪の毛に立体感・奥行きが感じられるようになる。実はめちゃんこ大事。

<br>
Groomプラグインを使用した場合はどうなるかというと・・・
そもそもAlembicの中身はただのカーブ情報なのでUV展開はできません。
その代わりシェーダー内でHair Attributesというノードを利用することで各種プロパティにアクセスできるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/db14354e-33e1-4c71-6e76-593b384e2813.png)
UとVを使用すれば『Meet Mike』の１つ目のUVチャンネルでやっていたことはすべてできそうです。
またSeedを使えばStrandごとのランダムさを出すこともできます。

『Meet Mike』の3つめのUVチャンネルを利用したAOっぽいことは、GroomのDetailsのHair Shadow Densityのパラメータをいじるだけです。便利！

`このHair Attributesに関してはオンラインドキュメントを探しましたが見つかりませんでした。使い方が良くわからず、あまり深堀り出来ていません。ピンはあるけど機能しない項目もあるかもしれないので、これ以上の検証はGroomプラグインの正式なリリースを待とうと思います。`　
<br>



##今後期待すること

まず公式ドキュメントに書いてある、Known Limitations（既知の制限事項）を確認しておきます。
>Decimation based on distance isn't yet implemented.

距離をもとにしたDecimation(ポリゴンの間引き)は未実装。

>Frame rate depends on the size of the groom, its resolution, and underlying hardware it's been run on. For example, you should expect a 30Hz or higher framerate with a 2080Ti for a human groom at 1080p.

フレームレートはgroomの量と解像度、ハードウェアによる。


>View Modes are not yet supported on Hair.

まだ表示モードがサポートされていません。
（↓Hairが表示されません）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/69723e10-338c-e7f8-c9bf-c5013c56b995.png)


>Multi-view (hair visible on several open windows) is not yet supported, or can cause artifacts to appear.

複数のビューで表示するのはまだサポートされていないようです。アーティファクツが出る可能性も
↓ カメラを選択した時の小窓にもHairは表示されません　　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/c28834a0-a0b7-6c90-e4b5-9f0683a7d225.png)


公式ドキュメントでは触れられていませんが、僕が検証した限りでは、Hairマテリアルで値をつないでも反応しない項目があるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/ec92970b-a156-152b-0c26-076746e00f30.png)
Scatter, エミッシブカラー、BackLit、アンビエントオクルージョンなどはピンはあるが使えないようでした。
また、ピクセル深度オフセットやワールドポジションオフセットも反応しませんでした。

 ↓ワールドポジションオフセットに値を入れると、
 ハイライト表示はズレていきますがシェーディング自体は変化しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/e8f77617-e147-0322-7204-5495a5a24e45.png)


ワールドポジションオフセットが実装されれば、真っ先に毛先と根本の幅を細くするシェーダーを組んでみたいと思います。
ピクセル深度オフセットが入れば、皮膚との緩衝部分をぼかすようなシェーダーが出来るんじゃないかとワクワクしています。
ちなみに『Meet Mike』では、毛の根元にポリゴンをおいてブラーでぼかしています。。大変！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539597/0913ddfa-ea09-d05c-6126-a0263176d57f.png)
____
尻切れトンボですが、今23:58なので日付が変わる前に締めたいと思います。
最後まで読んでいただいてありがとうございました!

___
■追記
テクニカル的なところは間違えてても「すみませんでした！アーティストなので許してください！」と言えるのですが、アートで大事なところを端折るのはなんとも気持ちが収まらなかったので追記します。ほとんどの人にとってはどうでもいい内容かもしれません。。。

個体差と人種によりますが、ざっくり人間の髪の毛は太さが0.01cm前後, 本数は10万本前後です。
上の記事の中で
>生やした本数にもよりますが0.015～0.03くらいの範囲で設定すればいいかと思います。

と書いていますが、これは現実の人間に比べてかなり太めに設定しています。
コスト度外視でリアルな人間を追求したいのであれば0.01前後（白人なら0.005程度）に設定するのもありです。
個人的な意見としては、多少髪の毛を太くしても不自然さは出にくいので、その分本数を少なめにしてコストを下げるのがいいと思います。UE4のデフォルト設定は0.025になっています。良いラインだと思います。

ただ実際より太めに設定した場合には注意が必要です。それは、**髪の生え際を丁寧に処理する**ということです。
特に髪の色が濃いと 生え際には毛と肌とで色のコントラストがつく為、人に見られやすいうえに不自然さがバレやすいです。
本来毛は根元が一番太いはずなのに CGでよく毛根を細くしてあるのは皮膚と毛をなじみやすくするためです。
Meet Mikeで生え際をなじませるためだけにポリゴンを大量に用意してブラーをかけているのも過剰ではないと思います。
人の視線がどこに向かいやすいかを把握したうえで、そこに重点的にコストをかけることが大切です。