UE4の勉強記録

UE4の勉強の記録です。個人用です。

UE5の勉強 -映像作品としてのLandscapeを作成する-

1.今週の予定

<映像作品としてのLandscapeの作成>

建築用のLevelの作成の勉強の続きをやります。

更に映像用のTutorialを何個かCheckします。

Niagara の勉強>

Unreal Engine 5で学ぶビジュアルエフェクト実装 基本機能からNiagara、シミュレーションまで」の実装の続きをやります。

<Materialの勉強>

Ben Cloward先生のTutorialを勉強します。

<Gaeaの勉強>

GaeaのTutorialを作成します。

<Houdiniの勉強>

Castle Wall Tool [1]の勉強をやります。

<UEFNの勉強>

Pi Equals Three氏のTutorialをやります。

<DirectX12の勉強>

DirectX 12の魔導書」の勉強をやります。

更にLötwig Fusel氏のDirectX12のTutorialをやります。

2.Landscapeの作成

2.1 今週の課題

先週、目の周りを切開して片目で作業していたので、実装する部分は全く出来ませんでした。

ので今週は実装する部分を重点的にやる事にします。

先週と先々週に勉強した内容が既に先週のBlogにまとめられていました。

これらの実装をやっていきます。

2.2 How to 3D Gaussian splat from Aerials to Unreal 5 (Free plugin)[2]を実装する

2024-01-29のBlogHow to 3D Gaussian splat from Aerials to Unreal 5 (Free plugin)[2]の内容を勉強しています。

それを元に実装してみます。

<Intro & What is a Gaussian Splat?>

特にやる事ないです。

<Video Recording>

ここも特に何もする必要はなかったです。

Tutorialでは自分で撮影した映像を元に3D Gaussian SplattingのDataを作成しています。

そのためのVideoの撮影についての話でした。

<Gaussian model creations>

撮影したVideoを3D Gaussian SplattingのDataに変換する方法について解説しています。

次の節で元々用意されている3D Gaussian SplattingのDataを使用する方法が説明されているのでそれを使用します。

<Luma Unreal Engine plugin>

ここから実際の作業が必要になります。

Tutorialでは以下のSiteから

以下のPluginをDownloadしていましたが、

今、このSiteを読むと

Plug-inはUEのMarketplaceにある事と書かれていました。

多分、2週間の間に内容が変化したんでしょう。

MarketplaceからこのPlug-inをInstallします。

これですね。

Freeとなっています。

UE5.3にInstallします。

しました。

Projectを起動させLuma AI Pluginが使用出来るようにします。

Projectは今、建物を作成しているMyArchitectureを使用する事にしました。

今度はUE様に3D Gaussian SplattingのDataをDownloadします。

Tutorialに以下のSiteからDownload出来るとありました。

このSiteを開くと以下のようになっていました。

全部試してみたいですが、取りあえずは一番左のDataをDownloadして試してみます。

以下のDataをDownloadしました。

DownloadしたFileのExtensionはlumaになっていました。

これは2024-01-29のBlogの予測とは違っていましたね。

先程のPluginをDownloadしたSiteに詳しい説明がありました。

このPluginはExtensionがlumaでもplyでもどっちでも開けるそうです。

うーん。

何となくですがGaussian Splatting専用のExtensionであるplyの方がUEの負担が少なくすみそうです。

こっちをDownloadします。

しました。

これですね。

でもSizeを確認したらPly Fileの方が4倍位Sizeが大きいです。

うーん。

なんで?

Unreal baked Gaussian Splat scene>

ここからどうやってUEにDataをImportするのかが分かりません。

Tutorialにはこのやり方は書いていません。

以下のSiteに

と書かれていました。

このSiteはこの後も何回も引用しそうなのでしっかりとまとめておきます。

Luma Unreal Engine Plugin (0.41) [3]です。

うーん。

単にDrag & Dropするだけか。

あれProjectがFreezeした。

と思ったらなんか計算しています。

数秒間経ったら以下のFolderが生成されました。

中身です。

Blueprint内です。

Texture内です。

ふええ。

なんか凄いですね。

Luma Unreal Engine Plugin (0.41) [3]によると

BPをLevel上にDragすれば使用出来ると言っています。

更にそれぞれのBPの違いについても説明していました。

試してみます。

まずBP_Drawbridge_Bakedから試してみます。

Bakedの特長を読むと

となっていました。

UEのLightを含むEnvironmentの影響を受けないGaussian Splattingと理解しました。

結果です。

何これ?

中を見てみます。

うーん。

なんも見えない。

以下の2つと消してみます。

結果です。

おお。

見えた。

始めて3D Gaussian Splattingの結果をUEで見る事に成功しました。

Cameraを移動させると以下のようになります。

ならない箇所もありますが、

うーん。

これは実用に耐えれるLevelではないでしょう。

Tutorialではこの後にCropを使用しています。

Luma Unreal Engine Plugin (0.41) [3]によると

Gaussian SplattingのBPをLevel上にDragするとCropBoxは自動で生成されるそうですが、

私のLevel上にはCropBoxは生成されていませんね。

その代りなのか分かりませんが、Gaussian SplattingのBP内には以下のParameterがありました。

ひょっとするとこのSampleのSizeが小さいのでCropBoxは生成されなかったのかもしれません。

他のBPも試してみましょう。

Dynamicです。

DynamicはLuma Unreal Engine Plugin (0.41) [3]によると

と説明されています。

Lightの位置を変更しようとしたら何故かDirectional Lightがありませんでした。

どうもDefaultで空のあるLevelではDirectional Lightはついてないみたいです。

EmptyのLevelから作り直しました。

ここにDynamicのBPを配置した結果です。

Directional Lightを動かしてみます。

おお、確かに夕焼け感が出て来ました。

でもそれぞれのObjectに特有の影が追加されている訳ではないので、はっきり言うと写真のRGBの値を変更しただけの感じがします。

正直凄いとまでは言えませんね。

今度はCroppedを試します。

Luma Unreal Engine Plugin (0.41) [3]によると

となっていました。

今度はCropしたGaussian Splattingを試せそうです。

BP_Drawbridge_Baked_Croppedです。

結果です。

うん。成程ね。

これが

の意味する所のようです。

以下の設定のようになっていました。

UEの座標軸とは全く一致してないですね。

今度はEnvironmentをみます。

Luma Unreal Engine Plugin (0.41) [3]では

と説明されていました。

BakedしたBPのEnvironmentで試してみます。

結果です。

この時点では特別違いは見られません。

ここでSkylightやSky AtmosphereのParameterを変更してみたんですが

よく分かりません。

変化しているようにも見えますが、変化してないようにも見えます。

もっと色々試してみたいですが時間が無くなってしまいました。

今週の3D Gaussian Splattingの勉強はここまでとします。

来週、もう少し検証してみます。

2.3 How to 3D Gaussian splat from Aerials to Unreal 5 (Free plugin)[2]を実装した感想

やっと3D Gaussian SplattingをUEで試す事が出来ました。

その感想ですが、まだ一例しか見てませんので断言する事は出来ませんが、期待していたほど凄くは無かったな。と言うのが正直なところです。

以下の欠点を感じました。

  • 中心以外の場所では映像のどこかに歪みが生じている
  • Cameraを移動した時にブレが生じる
  • 写真を張り付けたみたい

それぞれについて簡単に説明します。

<中心以外の場所では映像のどこかに歪みが生じている>

例えば以下の場面ですが

一寸だけ横を向いてみました。

左端の建物やその周りが歪んで見えます。

これが実際の風景というより写真をBillboardに張り付けて配置しているかのような印象になっています。

<Cameraを移動した時にブレが生じる>

これ、これがある限りUE内のEnvironmentとして使用するのは無理です。

<写真を張り付けたみたい>

これはDirectional Lightの位置を変更してもそれぞれのObjectに影が形成されないためにそう見えるみたいです。

以下の画像がそれを表しています。

影の影響を見るために以下のAssetを配置してみました。

結果です。

うーん。

Static Meshの影をGaussian Splattingの上に投影する事は出来るのね。

これは凄い。

それは兎も角として上の画像で灯篭はDirectional Lightの角度に対してしっかりと影を形成していますが、Gaussian Splattingで生成されたObject、例えば橋の両端にある円柱や標識は影がまったく形成されていません。

これがなんか写真っぽく見える原因な気がします。

これらの欠点と感じている部分は操作方法に熟達したら解決する問題なのかもしれません

なんせ、まだ一日しか触ってないから、まだ赤子と同じです。

これも焦らずにじっくり勉強する事にします。

3.Niagara の勉強

今週は「16.3 Emitterの生成」の実装を行います。

3.1 「16.3 Emitterの生成」の実装をやる

<「16.3.1 Simulation以外の下準備」>

Niagara SystemにEmpty Emitterを追加して

新しいNiagara Systemを作成します。

名前はNS_FluidSimulationとしました。

以下のEmpty Emitterの設定を変更していきます。

まずPropertiesの設定からGPUに変更します。

Fixed Boundsの値はSample Codeが-10,000~10,000の範囲だったので同じ値をSetしました。

教科書を読み直したら、教科書にもFixed Boundsの範囲は-10,000~10,000としろと書かれていました。

更にLocal SpaceにもCheckを入れました。

次にUser Parameterの作成を行います。

User Parameterって何だったけ。と思ったら以下のやつでした。

はい。作成しました。

この節の教科書の解説はかなり親切で教科書に書かれている通りにやったら普通に再現出来ました。

Emitter Update SectionにSpawn Burst Instantaneous Moduleを追加し

Spawn Countに先程作成した[USER] ParticleNumを追加します。

Particle Spawn SectionにあるInitialize Particle Moduleの

Sprite Size Modeの値を以下のように変更しました。

更にShape Location Moduleを追加します。

以下の設定に変更しました。

ここは別に重要な設定ではないでしょう。

適当に決めたはずです。

あ、分かった。Sample Codeで見た最初の球がこれです。

次はPreviewの設定を変更しました。

DefaultでShow EnvironmentはOffになっていたのでEnvironment Colorの値だけ変更しました。

結果です。

本当に真っ黒にするとそれはそれで見にくいので黒に近い灰色にしました。

ここで「16.3.1 Simulation以外の下準備」の実装が終わりました。

教科書ではこの時点では以下の図のようになると述べられていました。

私の結果です。

全然違います。

うーん。

どこで間違えたんでしょうか?

ParticleのSizeが大きすぎるのかな。

ParticleのSizeは

Particle Spawn SectionにあるInitialize Particle Moduleで決まっています。

[USER] SpriteSizeのDefault値は0.6になっていました。

うーん。

あっていますね。

後、考えられるのはParticle Spawn SectionにあるShape Location Moduleが効いてない可能性、もしくは値が間違っている可能性です。

Sphere Radiusの値は2.214になっていました。

これは小さすぎる気もしますが、教科書が指定した値と同じです。

更に言うとSample Codeの値もこれでした。

試しにこの値を200に変更してみました。

結果です。

しっかりSphere上にParticleを生成していました。

という事はShape Location Moduleはしっかり効いているという事になります。

うーん。

多分、教科書の図の方が間違っています。

ここは無視して先に進む事にします。

<「16.3.2 Simulationに関するEmitterの作成」>

Propertiesの+StageのIconを押して

新しいSectionを追加し、その名前をSloveとしました。

成程、Emitter内でStageと呼んでいるのか、

うーん。

Sectionの方が分かり易いきがしますが、Stageの方が良いのかな?

もう3年以上は週一でNiagaraの勉強をしています。

その間ずっとSectionと呼んでいたので、今更Stageと呼び名を変更するのはかなり抵抗があります。

一寸だけ、調べたらSectionと呼んでいるSiteは見つからなくなっていますね。

最初にNiagaraを勉強し始めた時のBlogを確認して、どこでSectionと言う名称を知ったのかを調べます。

2021-04-26のBlogNiagaraの勉強を始めていました。

最初の頃はGroupと呼んでいますね。

何時頃からSectionと呼ぶようになったんでしょう。後、それには元になった文献が有ったと思うんですが、その元になった文献を確認したいです。

今、この当時のBlogを読み直すと結構面白いです。

EventについてのTutorialを読んで、CPUでしかEmitter間のやり取りが出来ないのならNSに複数のEmitterを使用するのは実務上不可能なのではないか?とか

とか述べていました。

結構、深い話をしています。

始めてSectionと言う言葉を使用したのは2021-09-06のBlogでした。

これ以前に全く説明もなく唐突にSectionと言っています。

オカシイ。

絶対のどこかの公式の文献でSectionまたはStageと呼んでいたのでSectionと呼ぶようになったんですが、その証拠となる文献が見つかりません。

うーん。

これからはStageと呼ぶようにしますか。

「君子は豹変する。」と言いますし、間違っていたら直ぐに直す方が賢明です。

Sectionという呼び方が見つからない以上、これからはStageと呼ぶ事にします。

兎に角、Solveと言う名称の新しいStageをParticle Update StageとRender Stageの間に追加しました。

次にParticle属性のParameterを追加するそうです。

ここで教科書は結構重要な事をサラッと言っていました。

武者 拓也. Unreal Engine 5で学ぶビジュアルエフェクト実装 基本機能からNiagara、シミュレーションまで (p.921). 株式会社翔泳社. Kindle 版.

変数の名前で最初に_があるのが結構あったんですが、理由が分からなかったです。

ここでは自分で作成した変数であると認識出来るように_を最初につけるとありました。

要するにMy○○と同じ意味で_を使用していたんです。

うーん。

これ知らんかった。

はい。

Particle Attributesに以下の3つの変数を追加しました。

Particle Spawn Stageにそれぞれの変数をSetします。

次にSolve Stageに3つのScratch Pad Moduleを追加します。

それぞれの名前も教科書通りに変更しました。

ここで丁度「16.3 Emitterの生成」が終わっています。

これだけだと一寸短いので何か別に新しい事をやります。

3.2 Niagaraの勉強を始めたばかりの頃のBlogを読み直す

前節の途中で、Stageの本当の名称はSectionである事を証明しようとして、Niagaraの勉強を始めた頃のBlogを読み直しました。

これが意外と勉強になったのでそれをここにまとめる事にします。

10個位読む事にします。

2021-09-06のBlog

ここでは、CGHOW氏のTutorialを勉強しても60%位しか理解出来ない。もっと別なTutorialで勉強する必要があるのではないか?と真剣に議論していました。

今、Niagaraをほぼ理解した状態でこの時に自分が抱えている疑問に対して答えるとすると

  • Niagaraを理解する基礎が出来るには週一回の勉強なら2年位かかる。

ので慌てて結果を求めても仕方ない。という事です。

しかし世間の要求はそうなってはいません。「3カ月位で使用出来るようになれ!」と言って来ます。

これは世間の要求の方が間違っているんです。

2021-09-12のBlog

まだCGHOW氏のTutorialを勉強すべきかどうかについて議論していました。

CGHOW氏のTutorialについて最終的に以下の評価に落ち着いています。

そして

と言っていました。

うーん。

これは言い得て妙です。

更に以下のような結果になった場合はどうすべきなのかについて検証すべきである。と述べていました。

これは、何事にも通じる教訓です。

虎穴に入らずんば虎子を得ず。は真理ですが、結果には

  • 虎子を得て生きて帰ってこれた。
  • 虎子を得たけど生きて帰ってこれなかった。
  • 虎子を得る事は出来なかったが生きて帰ってこれた。
  • 虎子を得る事も出来ず、更に生きて帰る事も出来なかった。

の4つがあるので、それぞれの場合において考えておく必要があるのは当然です。

今、私はNiagaraの仕組みをほぼ完全に理解出来ています。

その理解のほとんどはCGHOW氏のTutorialで勉強したお陰です。

結果的に言えば「生きて帰ってこれた上にダイヤも手に入れた」訳です。

しかも今CGHOW氏はそのTutorialをYouTubeで公開するのは止めてしまいました。

ので私の真似をする事も今となっては出来ない。という結果になり私の得たダイヤの価値は更に高くなっています。

うーん。

やっぱり3カ月で何かの結論を求めるのは性急かもしれません。

2021-09-19のBlog

CGHOW氏以外のTutorialを勉強した結果をまとめていました。

結局、CGHOW氏のTutorialを勉強する以外にNiagaraを理解する方法は無いと結論付ける事になるんですが、ここではまだ色々迷っていますね。

Cascadeの勉強を中止したのは慧眼でした。

こんなの今更出来るようになっても何の役にも立ちません。

2021-09-26のBlog

この週はCGHOW氏のTutorialで勉強しているだけでした。

2021-10-03のBlog

ScopeがTransientの変数について調査していました。

Transientなんて今使用していません。

こういうのが余計な時間がかかる原因なんですね。

私が作成するTutorialにはこういう初心者から中級者になるために必要ない事はどんどん省いていきます。

2021-10-10のBlog

以下のCharacterが消えるEffectについて勉強しています。

これと同じEffectを三年間の間に何回も実装していますが、いつもやり方を忘れています。

まあ必要になったら自力で実装出来るでしょう。

2021-10-17のBlog

先週の実装の続きをやっているだけでした。

この辺で復習は終わりにします。

今週のNiagaraの勉強はここまでとします。

4.Materialの勉強

4.1 Animated Flag - Advanced Materials - Episode 26 [4]の実装をする

先週勉強したAnimated Flag - Advanced Materials - Episode 26 [4]の実装をします。

まずMaterialを作成しました。

名前はM_AnimatedFlagとしました。

まず以下の実装を作成しました。

この時点でMaterialがどうなっているのかを知りたいです。

以下のようになっていました。

Sineノードを追加しました。

結果です。

微妙に動いています。

更に以下のNodeを追加しました。

これは上下の揺れだけ15倍にしているだけです。

結果です。

左右に動いています。

Tutorialと同じ結果になりませんね。

うーん。

SineノードのPeriodの値が違うのかもしれません。

まず使用しているPlaneの中心の位置が全然違っていました。

よし、もうこれは自分で考えて解く事にします。

取りあえずFlagが波打つところまで出来ました。

色々問題があったんですが、最大の問題はMeshでした。

World Position OffsetはそれぞれのVertexの位置をOffしているだけでした。

ので右のようなVertexが4つしかないPlaneはどうやってもはためかないんです。

後は向きの問題ですが、これは簡単でした。

以下のような向きの場合は

Local PositionはY軸、

最後に掛ける値はZ軸になります。

以下の2つの向きを考えるだけです。

後Local Positionの値をそのままPassしても波打たないので

3で割りました。

このLocal Positionについては後でもう少し深堀します。

端を固定するためにLocal PositionのGの値を掛けます。

結果です。

中心が波打たなくなりました。

Modeling ModeでPivotの位置を左端に移動しました。

以下のように左端は動かなくなりました。

ここまできて旗のはためく向きが間違っている事に気が付きました。

直しました。

結果です。

前後にはためくようになりました。

取りあえず色付けました。

今週はもう時間が無くなってしまったので残りは来週やる事にします。

<来週の課題>

以下の問題点があります。

  • カクカクしている
  • 波がsin波ではない。

この辺の問題は来週検討します。

後、計算と実際の現象の関係ももう少し深く追求します。

追加ですが、全く同じ方法で旗をなびかせているTutorialがありました。

Waving Flags in Unreal Engine | Unreal Engine Material Shader Tutorial [5]

このTutorialでは旗をBlenderで作成する所からやっていました。

使用するMeshについての問題はこのTutorialを見たら解決しそうです。

今週のMaterialの勉強はここまでとします。

この位は簡単に解けるはずですが、こんな問題が起きるとは思っていなかったので、解決するための十分な時間を確保する事が出来ませんでした。

来週がんばります。

5.Gaeaの勉強

5.1 Tutorialの作成

先週作成したPowerPointにAnimationを追加しました。

一回だけ録画したら、PowerPointの内容がよく整理されてない部分がある事に気が付きました。

それを直しました。

以下変更した部分の内容をまとめます。

まずLecture内容を以下のように整理し直しました。

以下の2つが大きく変わっています。

新しいGraphを使用するに当たってPortalを使用する事をここで明言しています。

PortalはGaeaにおける重要な要素ですので、はっきりと示す事が重要と考えました。

Fxノードについても何の説明もしていませんでしたので新たに節を設けました。

最初にその節で何を勉強するかを簡単に説明する事にしました。

見た目は悪いですが、これで理解し易くなります。

Graphが何なのかについての説明を追加しています。

先週は、Graphで作成したNodeの結果をColorにあるNodeにPassする方法みたいな、いきなり読んだら何を言っているのか全く理解出来ない文章を書いていました。

のでそこだけ直しました。

Fxノードに関してのSlideは全部直しました。

ここでは2つの内容を説明しています。

まずPortalを使用した場合、こんな問題が発生すると言う説明をしています。

この問題を解決するためにFxノードを使用します。

そしてFxノードについて解説しています。

Fxノードを使用すると先程の問題がすぐに解決する事を説明しています。

最後にまとめです。

Fxノードについて追加しました。

5.2 Klaus氏のTutorialを復習する

Klaus氏のTutorialを見直して抜けが無いか確認します。

今週はGaea Beginner Tutorial Series : Part 2 - Terrain Creation [6]を見直しました。

Mountainノードと平地を作成するためのNodeをCombineする所で重要なTechniqueを使用していましたが、この方法全く覚えてなかったです。

のでそれをここにまとめておきます。

まず以下のようにCombineしています。

まずこのCombineノードの設定ですが、以下のようにしていました。

MaxでRatioは100%です。

ここで平地用のLandの基準が非常に高い位置にある問題について述べています。

のでそのままCombineしても山が見えなくなってしまいます。

平地を作成したNodeのPost ProcessからDrop to FloorをEnableします。

するとLandの基準が低くなりました。

こんな機能があるなんて全く知らなかったです。

自分で試してみます。

Defaultの状態です。

Drop to FloorをEnableしました。

結果です。

一番低い場所の高さが0に合わされました。

うーん。

まだKlaus氏のTutorialは勉強すべき内容が沢山あります。

次はMountainノードのPost ProcessにあるClampを使用してMountainの高さを調整しています。

Clamp Minの値を上げるとMountainノードの全体の位置が上に上がるようです。

Clamp Minを10%にしてみました。

Mountainの基礎面が高くなっています。

これは凄い。

6.Houdiniの勉強

6.1 Houdini - Wall Tool 07 [7]を勉強する

また目次が無くてKey Momentだけセットされています。

仕方ないのでこのKey Momentを元に節にわけてまとめます。

<Intro>

Crack、ひびを追加していくそうです。

Foreach_Begin2ノードを選択して

最初のBrickを表示しています。

左上のBrickが表示されています。

私のProjectでは右下のBrickが表示されたはずです。

この違い問題にならないなら無視しますが、どうなんでしょう?

Foreach_Begin2ノードのCreate Meta Import Nodeを押します。

すると以下に示した様にforeach_Begin2_metadata1が生成されます。

そのNodeのOutputをAttrbwrangle2の2番目のInputに繋げます。

うーん。

これは前に勉強した事あるやつです。

調べたら2024-01-14のBlogで勉強していました。

これを読むとMetaDataにはDetail Attributeがあり

これを利用して色々出来ると書いてありました。

以下に示した様にAttrbwrangle2内の実装で、foreach_Begin2_metadata1のDetail AttributesであるIterationを使用していました。

成程。

こうやってMetaDataを使用するのか。

完全に思い出しました。

Attrbwrangle2の名称をAttribwrangle_CrackRatioに変更しました。

Run Overの値をPrimitivesに変更します。

そしてAttribwrangle_CrackRatioノード内の実装を行います。

まずRandom Numberを作成します。

これは2024-01-14のBlogでRandom Numberを作成した時と全く同じ方法です。

<An Integer Attribute>

IntegerのAttributeを作成するそうです。

うん。

これで出来たの?

調べたんですが出て来ませんでした。

まだ調べ方もよく分かっていないのでこれは後々の課題にします。

次に以下のIf節を作成しました。

Crack Probabilityは後で作成するそうです。これはParameterになると思われます。

細かい点ですが、ProbabilityのSpellが間違っていますね。後、CrackRatioがCrackRationになっています。

If節内の実装を追加します。

Crackedの値を1にしています。

Geometry Sheetを見るとCrackedの値が以下のようになっていました。

以下のIconを押してCrack Probabilityを作成します。

出来ました。

そしてCrack Probabilityの値を0.5に変更しました。

次はここで作成した値に基づいてBrickをSplitするそうです。

Splitノードを追加しました。

<Split Node>

Attribwrangle_crackRatioノードの結果をSplit1ノードに繋ぎます。

そしてSplit1のGroupに以下の実装を追加します。

<Cutting Geometry>

色々な方法でCrackを作成出来るらしいです。

今回はVoronoi Fractureを使用して作成します。

Voronoi Fractureノードを追加しました。

更にSplit1ノードの結果をVoronoi Fracture1ノードの左側のPinに繋ぎました。

Voronoi Fracture1ノードはFractureを生成するためには右側のInputにGeometry上にあるPointをInputする必要があるそうです。

そのPointを生成するために

Scatterノードを使用します。

そして以下のようにSplit1ノードの結果をScatter1ノードに繋ぎます。

すると以下のようなPointをBrickの周りに生成します。

Tutorialではこの後、以下のIconをEnableして

Pointの色を青くしていました。

まあ、これはあんまり重要ではない気がしますが、一応記録には残しておきます。

こんなに沢山のPointは要らないのでSplitノードのForce Total Countの値を1000から3に変更します。

以下のようになりました。

Scatter1ノードの結果をVoronoi Fracture1ノードの右側のInput Pinに繋ぎました。

Voronoi Fracture1ノードを可視化しました。

Scatter 1ノードのGlobal Seedの値を変えると

BrickのFractureの形状も変化します。

今度はMergeノードを使用して

Splitノードで分けたFractureの無いBrickを追加します。

まずMerge1ノードにVoronoi Fracture1ノードの結果を繋ぎます。

そしてFractureの無いBrickのDataはSplit1ノードの右側のOutput PinからMerge 1ノードのInputに繋ぐことで追加します。

Merge1の結果をForeach_end2ノードの左側のInputに繋ぎます。

Foreach_end2ノードを可視化した結果です。

以下の<の向きが間違っていたと直していました。

<Crack Ratio>

それは兎も角としてこれで、Crack Ratioの値を変更する事でFractureの数を調整出来るようになりました。

<Poly Bevel

この後何をするのか一寸理解出来なかったですが、兎に角Polybevel1ノードを追加しています。

Polybevel1ノードのDistanceの値を0.02に変更しました。

Polybevel1ノードを可視化した結果です。

それぞれのEdgeがBevelされているようですね。

近づくとBevelされているのがはっきり見えます。

これは分かったんですが、これを利用して何を作成するんでしょうか?

Brickの見た目が膨らんで見えるのはBrickのNormalがおかしいからだそうです。

なのでNormalノードを追加してそこを直します。

Normal1ノードのWeighting Methodの値をBy Face Areaに変更します。

Brickが平に戻りました。

この後はParameterを弄ってCrackがどう変化するかを確認しているだけでした。

これでこのTutorialは終わりでした。

いつもの通り実装は来週します。今週のHoudiniの勉強はここまです。

7.UEFNの勉強

7.1 MAKE JUMPSCARES IN FORTNITE With Cinematic Sequence Device - UEFN / Creative 2.0 Tutorial [8]を実装します

先週勉強した内容を実装します。

<Intro>

FeddyのSkeletal MeshをImportします。

まずFBX fileをDownloadしました。

UEFNにImportしました。

MaterialがImport出来ていません。

うーん。

何で?

Materialを開いたら以下の警告が表示されていました。

Substrateを使用出来るようにそれば良いみたいです。

UE5の公式SiteのSubstrate Materials Overview [9]でProject SettingからSubstrateをEnableする方法が説明されていました。

これを試してみます。

何とUEFNにはProject Settingの項目がありませんでした。

そりゃそうだ。

全てのProjectはFortnite上に公開されるんだから。

それは兎も角として色が全部灰色になっています。

ここに適当な色を追加して今回はお茶を濁してしまいましょう。

以下のように色付けしました。

こうなった理由も少しだけわかりました。

MaterialがImportされてないんです。

それでUEFNが自動でこのModelに対応したMaterialを作成していました。

このFeddyをLevel上に配置しました。

<Creating a Hollow, Black Cube for Scene>

Feddyの後ろの背景を黒くするために黒いCubeを配置します。

Modeling ModeはUE5でもあまり使用した事ないです。

のでここはしっかり勉強する事にします。

Modeling Modeに変更してBoxを選択しLevel上に配置しました。

以下のように表示されています。

ModelからExtrudeを選択して

Boxの内側に向かってExtrudeしました。

回転してScaleを変更しました。

Materialを変更しました。

結果です。

こんな感じです。

<Creating Cinematic Sequence>

新しいLevel Sequenceを作成します。

Freddyを追加しました。

このぬいぐるみ、FeddyじゃなくてFreddyが正しい名称なのか。

<The Basics of Editing Skeleton with FK Control Rig>

以下の機能があるBoxが表示されません。

Tutorialで確認します。

Tutorialを見たらLevel Sequence内からやっていました。

開きました。

うーん。

そんな選択肢はありませんね。

ないです。

ひょっとしてこのFraddy、Boneがついてないんじゃないでしょうか?

Skeletal Meshを開いて確認しましたがありました。

分かりました。

と言うか多分、同じ結果になる方法が分りました。

Pointはここです。

この手順が終わると以下のFKControlRigが追加されています。

以下のBake To Control RigからFK Control Rigが選択出来ます。

これを選択すると以下のBoxが表示されます。

このReduce Keysの部分がTutorialの次の工程の部分と全く同じです。

のでCreateを押します。

すると以下のようにFKControlRigが生成され

更に

でAnim Outlinerに以下のBoneが表示されるようになります。

ただし、FraddyにはBoneは表示されていません。

Anim OutlinerからBoneを選択して以下のPoseを作成しました。

Skeletal MeshからBoneが選択出来ないのでPoseを作成するのが大変でした。

以下のIconをEnableしたら

Boneの設定を変える度に自動でPoseをSaveしてくれました。

<Keyframes in Sequence Editor>

Key Frameを選択した状態でAltと左Clickを押したまま、DragするとKey FrameのCopyを別な場所に生成出来るそうです。

これも試してみました。

全く同じPoseを生成する事が出来ました。

<Modeling The Pose / Animation>

綺麗なAnimationを作るのが目的ではないので、これで完成とします。

<Adding the Sequence Camera / Camera Controls>

以下のIconを追加してCameraを追加しました。

こんな感じになっています。

Cameraは自動で記録してくれないので自分でFrameを指定しました。

<Making Model Move Closer to Camera>

一応Level Sequenceは完成したという事にして次をやります。

ここはLevel Sequenceの閉じ方とPolit Modeの終了の仕方を説明していました。

<Setting up Cinematic Sequence Device>

Cinematic Sequence DeviceをLevel上に配置します。

しました。

あれ?

Cameraが2つあります。

最初に作成したCameraは消したつもりでしたが消えてないみたいですね。

これはテストした後で検証します。

Cinematic Sequence DeviceのVisibilityは最初からEveryoneになっていました。

TriggerをLevel上に配置します。

これですね。

配置しました。

そしてこのTriggerをCinematic Sequence Deviceにセットします。

先週のBlogのまとめだとこの後すぐにTestしています。

Cinematic Sequence DeviceのSequenceに何もセットしていません。

はい。先程作成したSequenceをSetしました。

これで動くはずです。

<Jump scare Test Result>

テストします。

普通に指定した通りの動作をしました。

以下のTriggerの上に乗ったら

Level SequenceのAnimationが開始しました。

Animationの内容は私がCameraで指定した通りです。

<Adding Audio / Sound to Sequence>

最後にLevel Sequenceに音を追加します。

以下の方法でAudio Trackを追加しました。

動く事が確認出来れば良いので適当な音を追加しました。

<Final Result>

テストします。

普通に音がしました。

7.2 MAKE JUMPSCARES IN FORTNITE With Cinematic Sequence Device - UEFN / Creative 2.0 Tutorial [8]を実装した感想

今回の実装はUEでも私があんまり知らない分野を多用していました。

ので分からなかったところを簡単にまとめておきます。

<FBXのImport>

何故かMaterialがImport出来ませんでした。

<Modeling Mode>

ここは出来なかったところは無かったんですが、初めて使用したModeだったので一応記録に残しておきます。

<Animation ModeでBoneが表示されない>

これ多分、超基本的な事だと思うんですが、直し方が分かりません。

<Cameraを2つ追加していた>

これは一回試してやったんですがへんな挙動を示すようになったので追加したCameraを消して、新しいCameraを作成してやり直したんです。

その結果、2回目は上手くいったんですが、Level上に戻ってきたら、最初に追加したCameraもしっかり残っていました。

<まとめ>

まあ、Level SequenceやAnimationはUEでもほとんど触った事がない機能です。

この辺の使い方は映像作品を作成する過程でこれから勉強していくことにします。

UE5のAnimationを勉強するに当たって興味深いTutorial Seriesを見つけました。

How To Animate in Unreal Engine 5 | Part 1[10]です。

Round Table Animation氏が作成しているChannelでUEのAnimationに特化したTutorialを上げています。

このChannelのTutorialも勉強する事にします。

8.DirectX12の勉強

8.1 Lötwig Fusel氏のD3D12 Beginners Tutorialを勉強する

8.1.1  Debug Layer | D3D12 Beginners Tutorial [D3D12Ez] [11]の続きを勉強する

<ReportLiveObjects()関数について>

先週、ReportLiveObjects()関数について勉強する前で終わっています。

今週はここから勉強します。

Debug Layer | D3D12 Beginners Tutorial [D3D12Ez] [11]の13:04あたりからReportLiveObjects()関数について解説しています。

この関数はDirectX12とdxgi内にある全ての生きているCom Objectについて報告するそうです。

うん。

別に難しくないですね。

当然、この関数を使用すればその時点でReleaseされていない全てのCom Objectを知る事が出来ます。

更に以下のParameterについて解説していました。

これは先に公式SiteのIDXGIDebug::ReportLiveObjects method (dxgidebug.h)[12]のParameterの説明を見てから聞く事にします。

最初のParameterであるapiidはDCGI_DEBUG_IDの一つを使用するそうです。

公式SiteのDXGI_DEBUG_ID [13]を見ると

と書かれていました。

Private Appが何を指しているのかが分かりませんね。

まあでも全部のDataをよこせと言う事でDXGI_DEBUG_ALLを使用しているんでしょう。

次のParameterはFlagでどの程度の量の情報を報告するのかをここで指定するそうです。

こっちも公式SiteのDXGI_DEBUG_RLO_FLAGS enumeration (dxgidebug.h)[14]を見ると

となっていました。

TutorialではDXGI_DEBUG_RLO_DETAIL | DXGI_DEBUG_RLO_IGNORE_INTERNALを指定していましたが、|ってBitwiseでOrと言う意味ですよね。

実際は両方を採用するのかそれともどちらかを採用するのかが分かりません。

これくらい理解すれば今度はTutorialの説明を聞いても理解出来るでしょう。

うーん。

最初のParameterについてはあんまり分からなかったです。

2番目のArgumentですが、

DXGI_DEBUG_RLO_DETAIL | DXGI_DEBUG_RLO_IGNORE_INTERNAL

両方の命令を聞くみたいです。

後、Errorを消すために以下に示した

DXGI_DEBUG_RLO_FLAGSを追加する必要があるそうです。

この後はOutputDebugStringW()関数について解説していました。

前回、ここの説明聞いたときは何を言っているのか理解出来ませんでした。

X BoxとPCを繋いでDebugしたら云々と言っていて話を聞いている内に混乱してしまったんですが、今回よく聞いたら、別にこのTutorialを勉強している段階では全く必要のない知識の話でした。

次にMain()関数に戻って以下の実装をしてテストしています。

Testの結果です。

私のProjectのTest結果です。

まったく同じですね。

以上でした。

8.1.2 Device & Command Queue | D3D12 Beginners Tutorial [D3D12Ez] [15]を勉強する

ComPointer.hの実装について勉強しようかと思ったんですが止めます。

まずTemplate Classについての知識があんまりなく、更にC++をかなり長い間弄ってなかったので結構忘れています。

これらを復習しながらComPointer.hの実装について勉強するとなると結構時間が掛かります。

それは今は避けたいです。

ので次のTutorialであるDevice & Command Queue | D3D12 Beginners Tutorial [D3D12Ez] [15]を勉強する事にしました。

まずDeviceの説明から始まりました。

そして以下のようにComPointerを使用して

ID3D12Device10型のObjectであるdeviceを宣言しました。

次にD3D12CreateDevice()関数でdeviceを初期化しました。

これは今までのDirectX12の勉強でも散々勉強したんですが既にその勉強した内容に関しては忘れてしまっています。

一寸だけ復習します。

DirectX 12の魔導書」だけ見直しましたが、D3D12CreateDevice()関数のParameterについての解説がしてあるだけでした。

後、D3D12CreateDevice()関数のArgumentの設定もほとんど同じでした。

何と、このDeviceに関して独立したClassを作成するそうです。

うん。

そっちの方が分かり易いか。

新たにD3Dと言うFolderを作成してその中にDXContext.hを作成しました。

(後からよく見たらDXContext.cppも作成していました。)

DXContext.hの実装ですが、

ComPointer.hを丸Copyして名前だけ変更し、微調整をして完成としていました。

ここはSample Codeを参考にして作成する事にします。

DXContext.cppの実装です。

これは先程勉強したD3D12CreateDevice()関数を実装しているだけですね。

ここでDXContext Classの実装が終わっているので、今週のLötwig Fusel氏のD3D12 Beginners Tutorialの勉強はここまでとします。

焦って沢山やっても身に付きません。

ゆっくり進めます。

来週は、DXContext Classの実装をやる事にします。

8.2 「DirectX 12の魔導書」の勉強

もうDirectX12の勉強方法が分りました。

DirectX12は定型が決まっていて、それに沿って専門の関数を並べているだけなんです。

分かり易い例えで言うとLEGOで城とか盆栽を組むのがあるじゃないですか。

例えば城のLEGOって特殊な形状のBlockがあってそれを最初の土台として並べます。

次にその土台の上に並べるBlockも特殊な形状のBlockで、その場所でしか使用出来ません。

こういう特殊な形状のBlockの塊がLEGOの城シリーズとかでまとめられて売っているわけです。

DirectX12はこれとまったく同じ仕組みなんです。

単に特殊なBlockの代わりに特殊な関数があるだけです。

それらの特殊な関数は、端的に言えばその場所でしか使用出来ません。

ので、その場その場で常に新しい関数が出て来ます。

なのでこれらの新しい関数が出て来るたびにその関数の機能やParameterの設定方法を勉強する必要が出て来る訳です。

ここで問題なのは、その関数の機能やParameterだけを勉強してしまうと、その関数が全体のどこに使用されているのか、何故その関数だけがそこに使用出来るのか。などのもっと重要な内容がないがしろにされてしまうんです。

先程のLEGOの例で説明すると城を作成するのが目的でそのために特殊なBlockを使用しているのに、特殊なBlockの使い方を勉強する事が目的化してしまうんです。

そもそもDirectX12に使用される関数の数はとてつもなく沢山あります。それぞれの関数の機能を完璧に覚える事は不可能です。

それよりも全体の流れを理解するのが大切だったんです。

先程のLEGOの城の例でいえば、今は塀を作成している。塀にある小さな穴を再現するためにこの特殊な形状のBlockを使用している。という俯瞰的な視点の事です。

後、普通の関数のような汎用性の高さは無いのでどの程度勉強すべきなのかも全く違います。

その辺を心に止めながら、これからのDirectX12の勉強をしていきます。

8.2.1 「4.7 Vertex Layout」を勉強する

Vertex LayoutですがGPU側にこのDataはVertexの情報です。と教える役割をしているそうです。

その情報を渡すのにD312_INPUT_ELEMENT_DESC構造体を使用するそうです。

<「4.7.1 D312_INPUT_ELEMENT_DESC構造体」>

D312_INPUT_ELEMENT_DESC構造体を勉強します。

これですね。

Sample CodeのCodeは見にくいのでこれをCopyして私のProjectに張り付けて見やすく直します。

これを見るだけでもそれぞれの要素が何を指定しているのかは大体想像出来ますね。

PositionはこれらのDataがVertexのPositionを表している事を示しているはずです。

DXGI_FORMAT_R32G32B32_FLOATはこれらのDataがRGBの3つの32bit のFloatを持つVectorである事を示しています。

公式SiteのD3D12_INPUT_ELEMENT_DESC structure (d3d12.h)[16]を見ると

と書かれていました。

ここで重要なのはInput-Assembler Stageです。

今まではこの関数のParameterについて必死で勉強していましたが、それでは全体像が把握出来ません。

これからはこの関数が全体のどこに使用されているのかに注視して勉強します。

のでまずInput-Assembler Stageが何をしているのかを確認します。

公式SiteのPipelines and Shaders with Direct3D 12 [17]に以下の図がありました。

ここにInput Assemblerがありました。

あれ、この図どっかで見た事あります。

教科書の「2.1.1 Graphic Pipelineの概要」でこの図を勉強していました。

前にこの教科書の2章を勉強した時は、全くこの辺の内容に対して注意を払っていなかったです。

調べたら2022-11-14のBlogで2章を勉強していました。

今から数えると一年と2カ月前になりますね。一週間に一回しか勉強してないので、そういう意味ではあんまり昔でもないです。

これしか書いてなかったです。

これは「2.1.1 Graphic Pipelineの概要」の勉強をもう一回する必要がありますね。

8.2.2「2.1.2 Graphics Pipelineの各Stage」をもう一回勉強する

まず軽く読み直しました。

重い。

前読んだ時はその内容の重さが分らんかったですが、今読むとかなり重要な話がまとめられています。

まずGraphic PipelineがDirectX9の時から出来た。とあります。これはShaderを利用してSoft内でPipelineを組むと言う事でしょう。

今までHardで組んでいた部分をSoftで作成するようになった訳です。

Hardで組んだ方がより速く動きますが、自由度が限りなく0になってしまいます。それをSoftで作成出来るようにして、ある程度の速度は犠牲にする代わりに自由度を限りなく無限に近づけた訳です。

しかしこのSoft上で作成すると言う方式を採用した結果、今までHardで組んだ部品やその設計を個々のProgrammerがSoft上で個別に再現する必要が出て来ました。

このための設計図がGraphic Pipelineなんです。

もし個人でPCを組むとなったらCPU、Motherboard、電源、Video Cardなどは必ず必要になります。

どのCPUを使用するのかは個人で決定できますが、CPUは使用しません。という選択は出来ないんです。

この選択出来ない最低のLineを規定しているのがGraphic Pipelineです。

だからGraphic Pipelineは凄い重要なんです。

全部をまとめるととてつもなく長くなってしまうので今回はInput Assembly Stageだけまとめます。

<Input Assembly Stage>

ここはGPUがCPUからの情報を受け取るStageです。

以下の3つのDataを主に受け取ります。

  • Vertexの情報
  • Index情報
  • Vertex Layout

ここにしっかりとVertex Layoutについて書かれていました。

うーん。

因みにここではVertex LayoutはVertexについての情報を持っているとだけ書かれていました。

はい。

8.2.3 「4.7 Vertex Layout」の勉強の続きをやる

<「4.7.1 D312_INPUT_ELEMENT_DESC構造体」>

Vertex Layoutが DirectX12の全体像のどこに位置するのかが分かったので、今度はその中のD312_INPUT_ELEMENT_DESC構造体というBlockの機能の勉強に戻ります。

これです。

それぞれの要素を勉強します。

D3D12_INPUT_ELEMENT_DESC structure (d3d12.h)[16]では以下のようになっていました。

教科書の説明の方がこの公式Siteの解説よりはるかに分かり易いので教科書の説明をまとめます。

まずこれらの要素は以下の4つに分類出来るそうです。

  • Semantic名
  • Format
  • Slot関連
  • Instancing関連

それぞれについて解説していました。

<<Semantic名>>

SemanticNameが担当しています。

次の要素であるSemanticIndexもここに分類されるのかと思ったら、これについては全く述べられていませんでした。

ここはShaderの時のSemanticとまったく同じ役割で、このDataが何を表しているのかを文字で示すそうです。

<<Format>>

三番目の要素であるFormatだけが対象です。

Dataの形式を指定しています。

これは最初に以下のように推測しましたが、

この事からも明白です。

DXGI_FORMAT enumerationが使用されています。

教科書にはもっと詳しいFormatの指定方法が解説されていましたが、細部の話すぎるのでここにはまとめません。

<<Slot関連>>

ここは凄い解説(仮説?)が教科書に書かれていました。

SlotはGPUがVertex情報を一寸だけ見るための覗き穴だと考えると理解し易いそうです。

そういえばSlotの元々の意味は硬貨を入れるための細い穴を指していたと聞いたことがあります。

そういう意味では正しい解釈になります。

InputSlot、AlignedByteOffset、InputSlotClassがここに分類されていました。

Slotは一個である場合もありますが、複数ある場合もあるそうです。なのでそれぞれのSlotに番号がついているそうです。

その番号を管理するのがInputSlotだそうです。

今回はSlot番号の0しか使用しないので、0を指定しています。

あ、分かった。

これは覗き穴でもあるかもしれませんがDataをGPU側に入れるための穴としても機能しているはずです。

Coinの代わりにDataを入れる訳です。

一つのSlotから全部のDataを入れる事をインターリーブと呼ぶそうです。Interleaveで調べたんですが関連する説明は見つかりませんでした。

AlignedByteOffsetはそのDataの場所を指定しているそうです。

InputSlotClassはそのSlotにおけるInput Data Classを指定するために使用されるそうです。

<<Instancing関連>>

InstanceDataStepRateがここに分類されていました。

一度に使用するInstanceの数をここで指定するそうです。今回はInstanceは使用しないので0を指定するそうです。

ここでのInstanceが何のInstanceを指しているのか分からないので

この説明で納得するしかないです。

以上でした。

はい。

頭がこんがらがって来ましたので今週の「DirectX 12の魔導書」の勉強はこの辺で終わりにします。

9.まとめと感想

なしです。

10.参照(Reference)

[1] Castle Wall Tool. (n.d.). https://www.youtube.com/playlist?list=PLNbgmFvU__fiPhyUWHHzZ2Nv5ieM_bOdB

[2] Urban Decoders. (2023, November 18). How to 3D Gaussian splat from Aerials to Unreal 5 (Free plugin) [Video]. YouTube. https://www.youtube.com/watch?v=SDO1XdFXl8M

[3] Luma Unreal Engine Plugin (0.41). (n.d.). Luma AI. https://lumaai.notion.site/Luma-Unreal-Engine-Plugin-0-41-8005919d93444c008982346185e933a1

[4] Ben Cloward. (2023, October 19). Animated Flag - Advanced Materials - Episode 26 [Video]. YouTube. https://www.youtube.com/watch?v=ZV2YrrKzs9c

[5] RGBguy. (2021, May 11). Waving Flags in Unreal Engine | Unreal Engine Material Shader tutorial [Video]. YouTube. https://www.youtube.com/watch?v=L-CH_oYKD74

[6] Klaus. (2022, January 15). GAEA Beginner Tutorial Series : Part 2 - Terrain Creation [Video]. YouTube. https://www.youtube.com/watch?v=8smDHlNpoyg

[7] Rick Banks. (2022, June 20). Houdini - Wall Tool 07 [Video]. YouTube. https://www.youtube.com/watch?v=3DWk73lgB6Q

[8] Pi Equals Three. (2023, April 25). MAKE JUMPSCARES IN FORTNITE with Cinematic sequence device - UEFN / Creative 2.0 tutorial [Video]. YouTube. https://www.youtube.com/watch?v=Axxmn6wuwow

[9] Substrate Materials Overview. (n.d.). https://docs.unrealengine.com/5.3/en-US/overview-of-substrate-materials-in-unreal-engine/

[10] Round Table Animation. (2024, January 29). How to animate in Unreal Engine 5 | Part 1 [Video]. YouTube. https://www.youtube.com/watch?v=kxu6QHeEa0Y

[11] Lötwig Fusel. (2023, May 8). Debug Layer | D3D12 Beginners Tutorial [D3D12EZ] [Video]. YouTube. https://www.youtube.com/watch?v=FKTfuKB6LTc

[12] Stevewhims. (2021, October 5). IDXGIDebug::ReportLiveObjects (dxgidebug.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/dxgidebug/nf-dxgidebug-idxgidebug-reportliveobjects

[13] Stevewhims. (2021, January 6). DXGI_DEBUG_ID (DXGIDebug.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/dxgi-debug-id

[14] Stevewhims. (2022, January 31). DXGI_DEBUG_RLO_FLAGS (dxgidebug.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/dxgidebug/ne-dxgidebug-dxgi_debug_rlo_flags

[15] Lötwig Fusel. (2023, May 15). Device & Command Queue | D3D12 Beginners Tutorial [D3D12EZ] [Video]. YouTube. https://www.youtube.com/watch?v=nQzALY8nX1c

[16] Stevewhims. (2022, July 27). D3D12_INPUT_ELEMENT_DESC (d3d12.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_input_element_desc

[17] Stevewhims. (2021, December 30). Pipelines and Shaders with Direct3D 12 - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/direct3d12/pipelines-and-shaders-with-directx-12