概要
UE5.7のSubstrateに追加されたBlendable GBufferを使用すると、Substrate以前のLegacy GBufferのレイアウトをSubstrate上で引き続き使えます。
今回、このSubstrateのシステム上で動くLegacy GBufferに対し、グローバルシェーダーを用いて描画を行いました。
上の画面に見える三角形が今回のグローバルシェーダーによる描画結果です。このシェーダーはUE5.4上、非Substrate環境で作成したものです。UE5.7で過去資産をSubstrate上で活かす道が開けました。
SceneViewExtensionとグローバルシェーダーを組み合わせたGBufferへの直接描画は以下の記事で書きました。よって今回はその描画手法の詳細は割愛し、その描画手法そのものがSubstrate上でどう扱われるかについてフォーカスします。
また、Blendable GBufferについては以下の記事で解析しましたので、参考にしてください。
なお本記事では説明の便宜上、以下の用語を使います。
- Legacy GBuffer ─ Substrate以前のGBufferレイアウト。Blendable GBufferが採用する形式と同一
- Legacy Shading Models ─ Substrate以前のShading Model体系(Default Lit, Subsurface等)
グローバルシェーダーによる描画について
本記事の三角形は、Static MeshやMaterialを一切用いず、usfファイルでピクセルシェーダーと頂点シェーダーを書いてLegacy GBufferを直接書き換えています。
以下の記事の解説で用いたプログラムと同一です。リンク先で作り方の雰囲気を掴んで頂けるかと思います。
Legacy Shading ModelsとComplexity
Legacy Shading Modelsのピクセルを自作グローバルシェーダーでBlendable GBufferに書き込む際は、そのShading ModelのComplexityをSubstrateに通知する必要があります。通知しない場合、Shading Modelによっては描画が省かれてしまいます。
冒頭の三角形はShading Model IDをDefault Lit(MSM_DefaultLit = 1)にして描画したものですが、例えばこれをSubsurface(MSM_Subsurface = 2)に変更して三角形を描画すると、以下のように見た目が破綻します。
この事象は、とある植物を画面に置くと解消することが確認されました。
SubstrateのMaterial Classificationビューモードで見ると、何が起こっているのか推察できます。上のタイル状の破綻は、Complexity毎の処理単位が可視化されたものです。緑色のタイルはSubstrateのSimpleというComplexityをもつ領域です。三角形がある場所がMaterial Classificationの表示対象として認識されていません。
先ほどの植物を置くと、植物と三角形が黄色のタイルで区分され、SingleというComplexityで認識されていることがわかります。植物はMegascansのアセットであり、Legacy Shading ModelのTwo Sided Foliageを用いています。
Substrate Infoビューモードで確認すると、植物を置くことによってIn View(CPU)のSingleがNoからYesに変わることが確認できます。
この検証から、この植物が画面内にあることでSingleのComplexityを用いることがSubstrateに通知されており、その通知によりSubstrateが当該Complexityのパスを実行する、と推察できます。
Complexityとマテリアル、およびMaterial Classificationビューモードについては以下の公式文書が詳しく解説しています。
今回の検証により、Legacy Shading ModelsはそれぞれSubstrateによって再解釈され、対応するComplexityが割り当てられることがわかります。今回の例では、Default LitはSimple、SubsurfaceやTwo Sided FoliageはSingleとされています。
SceneViewExtensionでComplexity通知を実装
用いるShading ModelのComplexityを自分で通知します。FViewInfoのSubstrateViewData.UsesTileTypeMaskに自分でビットフラグを立てます。
// FDrawInWorldSceneViewExtensionはFSceneViewExtensionBaseを継承
void FDrawInWorldSceneViewExtension::PostRenderBasePassDeferred_RenderThread(...)
{
...
FViewInfo& ViewInfo = static_cast<FViewInfo&>(InView);
#if UE_VERSION_NEWER_THAN(5, 7, -1)
if (Substrate::IsSubstrateEnabled()) // UE5.7以降のBlendable GBufferに対応
{
ViewInfo.SubstrateViewData.UsesTileTypeMask |=
GetSubstrateTileTypeAsUint8(ESubstrateTileType::ESingle);
}
#endif
...
FDrawInWorldSceneViewExtensionはFSceneViewExtensionBaseを継承して自分で定義したクラスです。
PostRenderBasePassDeferred_RenderThread はグローバルシェーダーで描画を行うメソッドです。
UsesTileTypeMaskはUE5.7で追加された変数です。もしこのコードをUE5.6以前の非Substrate環境でも使いたい場合は、UsesTileTypeMaskをUE_VERSION_NEWER_THANで囲うとコンパイルできます。
エンジンコードの調査
ビュー単位のComplexity
調査と実装が前後しますが、前述のビューの描画がタイル単位で欠落する事象を追うため、エンジンコードがビュー単位のComplexityをどう扱っているかを確認しました。
Substrate::GetSubstrateUsesTileTypeという関数により、FViewInfoのSubstrateViewData.UsesTileTypeMaskのビットフラグが確認され、Complexityごとの描画パスを省略できるかを判定しています。
以下のようなコードがエンジン上に複数箇所あります。
if (Substrate::GetSubstrateUsesTileType(View, ESubstrateTileType::EComplexSpecial))
...
if (Substrate::GetSubstrateUsesTileType(View, ESubstrateTileType::EComplex))
...
if (Substrate::GetSubstrateUsesTileType(View, ESubstrateTileType::ESingle))
...
if (Substrate::GetSubstrateUsesTileType(View, ESubstrateTileType::ESimple))
...
検証のため、GetSubstrateUsesTileTypeが常にtrueを返すように改造してみたところ、前項のUsesTileTypeMaskの設定を行わずともSingleパスが描画されることを確認しています。
Legacy Shading ModelsとComplexityの対応
前述の公式解説にある通り、Legacy Shading Modelsはフィーチャーとして分解・再解釈されており、フィーチャーはComplexityを決定します。
フィーチャーは、ESubstrateBsdfFeature というビットフラグで定義されています。ビットフラグに加え以下のようなビットマスクが定義され、各フィーチャーとComplexityの関係が示されています。
// Complexity masks
SingleMask =
EdgeColor
| Fuzz
| SSS
| SecondRoughnessOrSimpleClearCoat
| MFPPluggedIn,
ComplexMask =
Anisotropy
| SpecularProfile
| Eye
| Hair,
ComplexSpecialMask =
Glint
また、Legacy Shading Models からフィーチャーを組み立てるコードは以下の関数にあります。
- AppendLegacyShadingModelToBSDFFeature
- UMaterialExpressionSubstrateShadingModels::SubstrateGenerateMaterialTopologyTreeCommon
これらは、Legacy Shading Modelsを表す EMaterialShadingModel (MSM_DefaultLit、MSM_Subsurfaceなど)から ESubstrateBsdfFeature を組み立てています。
以上の動作はマテリアルエディタ上で確認可能です。たとえば、以下のように「Substrate Shading Models」BSDFノードを接続し、Single Shading Model を Subsurface もしくは Two Sided Foliage に設定すると 「SSS=1」と表示されます。その結果として、Complexityは「SINGLE」となります。
まとめ
Legacy GBufferに直接描画する過去資産としてのグローバルシェーダーは、Blendable GBufferと互換性があることがわかりました。Substrateは過去資産との互換性に配慮した設計がなされており、中間表現としてのBlendable GBufferに加え、Legacy Shading ModelsをSubstrateのフィーチャーとして分解・再解釈することで、新旧システムのシームレスな統合を実現しています。







