【UE5】マテリアルピン(アウトラインマスクとカラー)を追加してみた – Unreal Engine 5.5

Unreal Engine
目次
  1. 水ノ茉の宣伝
  2. 始まり
  3. マテリアルピンとは?
  4. エンジン改造とは?
    1. 前髪を透かしたり
    2. 毛先まで綺麗に表現できるポストプロセスなアウトラインを描いたり
    3. キャラと背景を別々のシャドウマップに書き込んでセルフシャドウを抑制したり
    4. 髪影を落としたり
    5. 頂点IDノードを追加して、それを元に鼻に線を引いたり
    6. 独自のトゥーンパス群ですべて描いたり
  5. Substrate (旧: Strata) 非対応
  6. リポジトリ
  7. 実装
    1. Engine/Shaders/Private/MaterialTemplate.ush
    2. Engine/Source/Editor/MaterialEditor/Private/MaterialEditor.cpp
    3. Engine/Source/Editor/UnrealEd/Private/MaterialGraph.cpp
    4. Engine/Source/Editor/UnrealEd/Private/MaterialGraphNode_Root.cpp
    5. Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp
    6. Engine/Source/Runtime/Engine/Private/Materials/Material.cpp
    7. Engine/Source/Runtime/Engine/Private/Materials/MaterialAttributeDefinitionMap.cpp
    8. Engine/Source/Runtime/Engine/Private/Materials/MaterialCachedData.cpp
    9. Engine/Source/Runtime/Engine/Private/Materials/MaterialExpressionHLSL.cpp
    10. Engine/Source/Runtime/Engine/Private/Materials/MaterialExpressions.cpp
    11. Engine/Source/Runtime/Engine/Private/Materials/MaterialHLSLEmitter.cpp
    12. Engine/Source/Runtime/Engine/Classes/Materials/Material.h
    13. Engine/Source/Runtime/Engine/Classes/Materials/MaterialExpressionMakeMaterialAttributes.h
    14. Engine/Source/Runtime/Engine/Public/SceneTypes.h
  8. 簡単な動作確認
  9. おわり!!!
  10. 関連するエンジン改造
  11. えちえち Cloth Simulation Season 2
  12. えちえち Cloth Simulation Season 3
  13. オトメき グッズ
  14. 珈琲時間 Next 計画

水ノ茉の宣伝

準備中...
ゲームを作る予定なの
水ノ茉こおり

始まり

マテリアルピンを追加するエンジン改造をしていきます。

マテリアルピンとは?

Base ColorやMetallicなどの最終的な計算結果を接続する部分のことをマテリアルピンと呼びます。

実装を覗いてみるとマテリアルプロパティやインプットという名称も使われているので、またしても正式名称は知らんです。

相手に伝わるレベルの言葉の揺れは許してね。

パラメーターをシェーダーに渡したい場合は、マテリアルピンを追加する必要があります。

独自のコンスタントバッファを追加すればいいじゃんと思うかもしれませんが、Unreal Engineでそのやり方はまぁまぁな手間を要するので、一般的には実装までの導線が最低限確保されているマテリアルピンの追加が選ばれます。

エンジン改造とは?

ゲームエンジンのコードを書き換える行為をエンジン改造と呼びます。

尚エンジン改造という呼称が正式かは知らんです。

これ以上の真面目な説明はググればヒットするので割愛します。

以下、実際の描画まわりの改造事例です。

前髪を透かしたり

毛先まで綺麗に表現できるポストプロセスなアウトラインを描いたり

キャラと背景を別々のシャドウマップに書き込んでセルフシャドウを抑制したり

髪影を落としたり

頂点IDノードを追加して、それを元に鼻に線を引いたり

独自のトゥーンパス群ですべて描いたり

Substrate (旧: Strata) 非対応

Substrateはマテリアルピンの構成が異なり内部でピンの再接続が行われています。

再接続部分を対応していないので、Substrateは非対応という感じです。

尚5.7もしくは5.6からは対応する予定です。

リポジトリ

最新バージョンのみ保守しています。
過去バージョンが動かないと言われても基本的には知らんがなスタイルです。

実装

アウトラインマスクとアウトラインカラーを格納するピンを追加していきます。

アウトラインマスクの型はfloat、アウトラインカラーの型はfloat3を想定します。

Engine/Shaders/Private/MaterialTemplate.ush

ピクセルシェーダーでアウトラインマスクとアウトラインカラーを取得する関数部分です。

関数名の末尾にRawがある場合はノードの結果をそのまま取得、Rawがない場合はGBuffer等に格納するのを想定してクランプ済み、または正規化済みな値を取得する、といった感じで使い分けます。

マテリアルノード側でsaturateする必要が無いように整備してあげるイメージです。

githubで実装を見る(L3730-L3748)

Engine/Source/Editor/MaterialEditor/Private/MaterialEditor.cpp

アウトラインマスクの型であるfloatは、UMaterialExpressionScalarParameterに区分されます。

githubで実装を見る(L5162)

アウトラインカラーの型であるfloat3は、UMaterialExpressionVectorParameterに区分されます。

float2float4も同様にUMaterialExpressionVectorParameterに区分されます。

githubで実装を見る(L5174)

デフォルト値に戻す処理の対応です。

githubで実装を見る(L5371-L5379)

githubで実装を見る(L5425-L5426)

Engine/Source/Editor/UnrealEd/Private/MaterialGraph.cpp

ピンにカーソルを重ねた際に表示されるツールチップ部分です。

ピンの並び順も兼ねています。

githubで実装を見る(L319-L320)

Engine/Source/Editor/UnrealEd/Private/MaterialGraphNode_Root.cpp

Constantノードが接続されているか判断している部分です。

githubで実装を見る(L58-L59)

デフォルト値をUIから書き換えた場合の処理です。

githubで実装を見る(L130-L131)

マテリアルエディタを開いた際のピンの属性だったり、デフォルト値だったりの対応です。

githubで実装を見る(L228)

githubで実装を見る(L281)

githubで実装を見る(L329-L330)

Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp

アウトラインマスクとアウトラインカラーのシェーダーコードを常時展開として指定しています。

理想はCustomDataと同様に特定のシェーディングモデルに限定するべきですが、ToonLit以外で使わなければいいだけの話なので基本的には対応をサボっています。

githubで実装を見る(L767-L768)

githubで実装を見る(L1607-L1608)

Engine/Source/Runtime/Engine/Private/Materials/Material.cpp

static_assertの対応です。

githubで実装を見る(L2942-L2946)

マテリアルピンの接続を取得する関数です。

ツールチップ的な説明ではなく、構成要素の型とかの内部情報の説明です。

githubで実装を見る(L6185-L6186)

ピンに刺さっているノードのコンパイルまわりです。

githubで実装を見る(L6830-L6831)

githubで実装を見る(L7531-L7534)

githubで実装を見る(L7779-L7780)

Engine/Source/Runtime/Engine/Private/Materials/MaterialAttributeDefinitionMap.cpp

ピンが接続されていない場合の初期値を指定しています。

githubで実装を見る(L81-L89)

アトリビュートマップに追加したマテリアルプロパティを登録しています。

githubで実装を見る(L295-L296)

同様にアトリビュート関連です。

githubで実装を見る(L470-L473)

Engine/Source/Runtime/Engine/Private/Materials/MaterialCachedData.cpp

MakeMaterialAttributesノードに接続されているピンの更新まわりです。

githubで実装を見る(L565-L566)

Engine/Source/Runtime/Engine/Private/Materials/MaterialExpressionHLSL.cpp

MakeMaterialAttributesノード関連です。

githubで実装を見る(L3317-L3318)

Engine/Source/Runtime/Engine/Private/Materials/MaterialExpressions.cpp

マテリアルプロパティに対応した入力情報が詰まった変数を返している部分です。

githubで実装を見る(L7099-L7100)

ピンの接続性を64ビットフラグに突っ込んで返している箇所です。

githubで実装を見る(L7148-L7149)

static_assertの対応です。

githubで実装を見る(L7160-L7164)

シェーダーコンパイル部分です。

githubで実装を見る(L7195-L7196)

static_assertの対応です。

githubで実装を見る(L7257-L7261)

BreakMaterialAttributesノードの各ピンが出力するチャンネル数を指定しています。

githubで実装を見る(L7295-L7296)

BreakMaterialAttributesノードの原始的な紐づけ方法です。

githubで実装を見る(L7377-L7378)

Engine/Source/Runtime/Engine/Private/Materials/MaterialHLSLEmitter.cpp

HLSLMaterialTranslatorと同じです。

尚5.6ではMaterialHLSLEmitterが廃止され、HLSLMaterialTranslatorに一本化されます。

githubで実装を見る(L806-L807)

Engine/Source/Runtime/Engine/Classes/Materials/Material.h

ピンの接続関係を保持する変数です。

githubで実装を見る(L398-L402)

Engine/Source/Runtime/Engine/Classes/Materials/MaterialExpressionMakeMaterialAttributes.h

ピンの接続関係などを保持する変数のMakeMaterialAttributesノード版です。

githubで実装を見る(L78-L82)

Engine/Source/Runtime/Engine/Public/SceneTypes.h

マテリアルプロパティの列挙体にアウトラインマスクとアウトラインカラーを追加しています。

MaterialPropertyの頭文字を取ってMPです。

githubで実装を見る(L183-L186)

簡単な動作確認

追加したOutline MaskやOutline Colorを目に見える形で動作確認するためにはGBufferに格納しないといけないのですが、そこまでやるのは面倒なので簡単に確認できる方法を軽く紹介します。

型、ピンに対応したCustomノードを作成、接続します。

Window > Shader Code > HLSL Codeをクリック

下の方にスクロールしてCalcPixelMaterialInputsCalcPixelMaterialInputsAnalyticDerivativesの中身を見ると、Customノードの計算結果が格納されていることが確認できます。

おわり!!!

スカラーパラメータであるアウトラインマスク、ベクターパラメータであるアウトラインカラーをピクセルシェーダーに渡すためのマテリアルピンの追加でした。

関連するエンジン改造

えちえち Cloth Simulation Season 2

えーい。我慢の限界です。クロスシミュの続きをします。

カプセルコリジョンの実装です。

掴みであるGrabの実装です。

アニメーションを変位として伝播させて揺れ揺れです。

えちえち Cloth Simulation Season 3

S2は順調に進行できていますが、なんともいえないモヤモヤが生まれてきました。

少し整理しましょうか。

CoffeeLiveで初実装したS1の欠点は、クロスシミュを適用できる衣装に限りがあったことです。

描画メッシュの頂点を流用しつつ、Quadベースなクロス計算をしているため、ベースの頂点関係がQuadから大きく逸脱しているとクロスシミュが正常に出来ませんでした。

それを克服するためにS2ではQuadベースなクロス計算を廃止して、新たにTriangleベースな計算に刷新しました。

これにより衣装に制限なくクロスシミュを手軽に適用できるようになりました。

現状モヤっていることは、描画メッシュを流用することによる頂点数の肥大化と、そもそもとして描画メッシュを流用する必要性です。誰でも手軽に扱えるという点は利点ですが、前提として筆者が扱えればそれでいいです。プラグイン化するにしても使いやすさを意識する気は更々ないです。それを求めるなら『ChaosClothを使えよ』に帰着します。これに関してはソフボも同様の指針ですね。

もう1点は衣装以外にもクロスシミュをしたい欲が湧いてきたことです。

当初はGPGPUな揺れ骨を作る予定でしたが、ボーンベースな髪揺れは、処理速度に圧倒的な優位性がありますが、その代償として品質が弱いです。引きで見る分には特に違和感ないのですが、ヌキゲーだとカメラと近いので、想像よりも粗が目立ちます。あとシンプルに揺れ骨はKawaiiとSPCRが市場にあるので、自作の気力があんまり湧きません。

一度モヤったらそれを取り除かないと気が済まない性格です。

ということでそんな気分の移り変わりを理由にS2の開発は強制終了です。

S2の寿命僅か2週間程度で草生えますわ。殺す判断をしたのは自分だけども。

S3でやりたいことリストです。

  • シミュレーションメッシュをBlenderで作成
  • Quadベースなクロスシミュに回帰
  • 衣類以外の髪やアクセサリーなどに応用利用

QuadベースはS1、埋め込みはソフボ、基本的な実装は揃っているので気分が乗った時にパパっと作っちゃいましょうか。

そんなわけでS2の供養でした。

オトメき グッズ

気晴らしにBoothを開いてフォロー中という名の購入したことあるショップを眺めていたところ。

はっ!そういえばコミケか。

筆者は人混み絶対に無理なので、すっかり忘れていました。

事後通販は引きこもりに優しいです。

ということでタンブラー以外をぽちぽち。

プレイマットは既に売り切れていました。無念です。

ふぅ。任務完了です。

パーカー以外は実用性ないですけど、まぁ、グッズなんて、そんなもんですよね。

購入という手続きで満たされるのです。

そして届く頃には買ったこと自体を忘却しています。

いつものことです。

ちなみに前回のパーカーは暖かくて結構好きです。

真夜中のコンビニに行くときに重宝しております。

珈琲時間 Next 計画

地味に5.7対応は完了しています。

独自描画パス群のおかげでエンジンバージョンアップデート対応が圧倒的に高速化しました。

描画の方は爆速で終わりましたが、代わりに物理であるReinPhysics(Cloth, SoftBody)は、GpuSkinCacheの破壊的変更をもろに食らいました。

ReinPhysicsのプラグイン化もある程度は終わっているので、思い切ってプラグイン設計を真とするのもありなんですかねぇ。エンジンに直で組み込んだ方が最適化や拡張の幅は無限なんですけど、結局は保守が出来なければ全てを失う恐れがあるんですよねぇ。難しい問題です。

そして独自パス群の更なる最適化案を思い付いてしまいました。

ヌキゲー制作が終わったら、もしくは区切りが付いたら実証したいですね。

我ながらソフトボディの挙動が完璧過ぎる。