UE4の勉強記録

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

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

1.今週の予定

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

Videoを撮影してLama AIで3D Gaussian Splattingを作成してみます。

Niagara の勉強>

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

<Materialの勉強>

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

<Gaeaの勉強>

GaeaのTutorialを作成します。

先週出来なかった、Klaus氏のGaea2.0についての見解をまとめた動画を勉強します。

更に2024年のNividaのGTCで使用されたCGにGaeaが使用されていました。

についてもまとめます。

<UE5.4の新しい機能について>

UE5.4の新しい機能を解説した動画がそれなりに出て来ました。

重要そうなやつを何個かまとめる事にします。

<Houdiniの勉強>

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

<UEFNの勉強>

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

<DirectX12の勉強>

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

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

2.映像作品としてのLandscapeの作成

2.1 Luma AIで3D Gaussian Splattingを試す

携帯のCameraでVideoを撮影して来ました。

あまり上手く撮影出来なかったので、おそらくきちんとした3Dは作成出来ないと思いますが、最初のTryとしてこのVideoを使用して試してみます。

<携帯で撮影したVideoをPCに移動するまで>

こんなの記録する必要が無いほど簡単だと思っていましたが、結構大変でした。

まずVideoが保存されているFolderがどれなのか分かりません。

Extensionから調べたら簡単だと思ったんですが、そもそもこの携帯で撮影したVideoがどのExtensionで保存されているのか不明です。

仕方なく全部のFolderを開いて見ましたが見つかりませんでした。

Photoの設定を見たら保存先指定にSDカードとなっていました。

今度はSDカードの方を見ると

DCIMというFolderに

100IMAGEというFolderがあり

この中に保存されていました。

ExtensionはMp4だったのか。

開いて見ると普通に見れました。

ところがこれをCopyしてPCのFolderに移そうとすると

となって移せません。

調べたら

「要求されたリソースは使用中です。」の解決策を模索した話 [2]に解決方法が載っていました。

PC上で携帯のmp4を開くとこうなるそうです。

一端携帯を外してPCに繋ぎ直し、いきなりPCにCopyすれば良いと書かれていました。

その通りにやったら出来ました。

ここまでやるだけでかなり疲れました。

<Luma AIにVideoをUploadします>

以下の設定でUploadします。

以下の画面が表示されました。

先週のBlogを見たら以下のように書かれていました。

気長に待つことにします。

以下の表示が出て来ました。

うーん。

失敗したのか?

一応、以下の画面が追加されていました。

もう少し待ちます。

30分位経ちましたが変化ないです。

2つ目のVideoをUploadする事にしました。

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

やっぱり最初に上げた動画は何かおかしくなってたみたいです。

今度はPreprocessingが5%で止まってしまいました。

諦めかけたら突然35%まで上がりました。

もう少し待つことにします。

全く変化しません。

これは明日もう一回確認する事にします。

と思ったら急に90%まで行きました。

のでもう少しだけ待つことにします。

更に一時間待ちましたが出来ました。

中身を見てみます。

凄い。

写真と変わりません。

Videoに無い部分は抜けています。

でも最初にしたら十分に凄いです。

DownloadしてUE5でも見てみます。

下向きの矢印を押して

以下のBoxを開きました。

Gaussian Splatを押しました。

以下のZip FileがDownloadされました。

展開しました。

Ply Fileがありました。

UE5を開きます。

Luma AI PluginがEnableされている事を確認して

先程のPly FileをDrag and Dropします。

結果です。

おお、Fileが形成されました。

gs_SecondTest_B8_BakedをLevel上に配置してみます。

以下に一番見栄えが良い写真を示します。

うーん。

とても合格点を超えているとは言えませんが、最初にしてはまあまあでしょう。

gs_SecondTest_B8_Baked_No_TAAも試してみました。

この角度から見ると写真と変わりません。

しかし一寸角度を変えると

こんな感じです。

gs_SecondTest_B8_Dynamicです。

これはSkylightをEnableしないと何も見えなかったです。

gs_SecondTest_B8_Dynamic_No_TAAです。

どれがどう違うのかはまだよく分からないです。

後、色が白過ぎます。

この辺はSkylightやDirectional Lightの設定から調整出来るはずです。

これも後で考えます。

2.2 Luma AIで3D Gaussian Splattingを試した感想

今回は初めてのVideo撮影だったので、3D Gaussian Splattingは出来なくても良い位の気持ちでやっていました。

ので一応UE5で展開出来る所までいったので良かったです。

ただ、Modelの出来はかなり悪いです。

人が写らないように撮影したんですが、人を消す機能がついていました。

沢山の人が写っていても全部の人を消せるのかは分かりません。

一つ分かったというか仮説ですが、中心のObjectよりも周りの風景が大切です。

Objectはなくても良いかもしれません。

円形に回転して撮影出来る環境だったらかなり綺麗な風景を再現できるはずです。

もう一つは回転しないでそのまま歩いて撮影したVideoから3D Gaussian Splattingを生成する事は出来るのかどうかを試してみます。

映像を生成するためにこのLumaから生成した3D Gaussian Splattingが使用出来るのかどうかですが、出来そうです。

特に木や草などのMeshで再現しにくい箇所を生成するのに使えそうです。距離で言うと中距離のObjectを生成するのに最適な気がします。

こんなImageです。

  • 近距離;Static Mesh
  • 中距離:3D Gaussian Splatting
  • 遠距離;Gaeaを使用したLandscape

近距離でも盆栽のような境界が複雑なものは3D Gaussian Splattingで生成した方が良いかもしれません。

そう言えばKiri Engineでは3D Gaussian Splattingのまま3D ModelをUE5にImportする事は出来ないのでしょうか?

これも後で調べる事にします。

以上です。

<追記>

桜の3D Gaussian Splattingが作成したいので予定より沢山Testする事にしました。

間違えてLama AIにAccessしてしまいました。

もう少しでLuma AIと同じPasswordを入力する所でした。

危なかったです。

Luma AIが正しいWebの名称です。

<<Test3>>

自分を中心にぐるぐる回って動画を撮影しました。

これでも3D Gaussian Splattingは生成出来る気がします。

とりあえず撮影した動画をUploadしました。

後で確認してみます。

出来ていました。

中身を見てみます。

それなりに出来ています。

結論としては自分を中心にグルグル回って撮影しても3D Gaussian Splattingの生成は出来るという事になります。

ただし今回の結果に限って言うと一寸でも軌道を外れると

こんな感じになります。

これは色々な角度の撮影がまだ足りないからだと思います。

今度撮影する時はもっと色々な角度で撮影するようにします。

<<Test4>>

道を散歩している過程で風景を撮影しました。

同じ道を何回も言ったり返ったりしてそのたびにすこしだけ向きを変えて撮影しました。

これで周りの風景を3D Gaussian Splatting出来ないとUE5の風景に利用するのはかなり難しくなります。

出来たら良いな位の感覚ですが、とりあえず試してみます。

こっちもUploadしました。

これも後で確認します。

こっちも完成していました。

これは単に歩いている時に周りの風景を撮影しただけです。

これが3D化したら凄いですが、どうでしょうか?

おお、出来てそう。

右を見ます。

右の建物は完全に消えていました。

ただ何故かその奥にあるBuildingは生成されていました。

左側の風景です。

こっちは全然駄目でした。

でもそれなりに生成出来ている箇所もあります。

その奥の風景に関してはかなり綺麗に生成されていました。

この通路を行ったり来たりして撮影したので同じ様に移動してみます。

少しだけ奥に移動しました。

右側の奥の風景はかなりぼやっとしていますね。

通路を抜けたところです。

うーん。

ここもボヤっとした風景になっていますね。

Uターンして左側を写しています。

この部分は全く生成されていませんでした。

今度は反対側を向いて見ました。

こっちも全然生成されていません。

この辺はそれなりに丁寧に撮影したつもりだったですが、駄目でしたね。

通路そのものはかなり綺麗に生成されていました。

自転車もそれなりに綺麗に生成されていますね。

結論。

このやり方でも3D Gaussian Splattingから3Dを生成するのは可能みたいです。

ただしもっと風景をしっかり撮影しないと色々な箇所で破綻が発生します。

3.Niagara の勉強

3.1 「16.8 水面のRendering」を勉強する

先週勉強した「16.8.3 背景の作成」を実装します。その後で、次の節である「16.8.4 diffuse Specularの作成」を勉強します。

3.1.1「16.8.3 背景の作成」を実装する

以下のような背景のImageを撮影しました。

Cameraからの映像です。

これをUEにImportして名前はT_WaterBGと名付けました。

そして不必要なObjectを全部消します。

TutorialではFloorも消していますが、元々このProjectはThird PersonのTemplateでPlayするとPlayerが操作するCharacterが生成されます。

それがへんな影響が出ないようにFloorだけは残しておきます。

Contents Browserを開くとRender TargetのImageが白黒になっていました。

これもTutorialの説明通りです。

一応、これで出来たことにします。

3.2「16.8.4 diffuse Specularの作成」を勉強する

教科書を読んでいきます。

いきなり新規でMaterialを作成して名前をPP_DiffuseAndSpecularと名付けよ。と書かれていました。

一応、Sample Codeで確認したら

以下のMaterialがありました。

またPost Processingと使用するのでMaterial DomainはPost Processingに変更するそうです。

このMaterialを開いて実装をします。

まずCustom HLSLノードを追加します。

名前をDepthToNormalにします。

Input Pinを4つ作成します。

それぞれの名前をdr、dl、du、そしてddとします。

これをEmissive Colorにつなぐそうです。

Sample CodeのDepth To Normalノードを見ると以下のようになっていました。

ResultノードのEmissive Colorにはつながっていません。

OutputはFloat4になっていました。

Codeは以下のように実装されていました。

上下、左右の差をとってNormalizeするのか。

何で上下左右の差をNegateしているんでしょうね。ここはよく分からないです。

この後、DrなどのInputの値を計算するための実装を追加しています。

ところが教科書の実装とSample Codeの実装が一寸だけ違っています。

おそらく最後には同じになると思いますが、今の時点では違います。

以下にSample Codeのdrの値を計算するための実装を示します。

赤線で囲った部分が教科書ではSceneTexture:SceneDepthになっています。

Preview画面も教科書には載っています。

PP_DiffuseAndSpecularのMaterial Instanceを作成します。

SceneCapture2D_DiffuseAndSpecularを選択して

以下のPost Process Materialsにセットします。

これはSample Codeの画面です。

PP_DiffuseAndSpecularのMaterial Instanceがセットされています。

今度はScene Captureの設定を変更します。

ここの教科書の解説が一寸難しいのですが、まず何をやったのかからまとめます。

Capture Sourceの値をFinal Color(HDR) in Linear sRGB gamutに変更しています。

この役割ですが、これが複雑です。

以下にまとめ直します。

Scene Capture 2DはDefaultの設定ではPost Processがかかる前のImageをRender Targetに書き込むそうです。

それではPost ProcessでParticleを水面に変更しても意味がありません。

のでPost Process変更後のImageをRender Targetに書き込むように変更するそうです。

その方法が、

「Capture Sourceの値をFinal Color(HDR) in Linear sRGB gamutに変更」

する事だそうです。

うーん。

言っている事は理解出来ましたが、何でこれを変更するとそうなるんでしょうか?

ここで教科書はこの結果をPreviewで表示しています。

そして次の「深度をぼかす」ための実装が始まっています。

あんまり沢山勉強して一個一個がおろそかになるのは避けたいので、今週のNiagaraの勉強はここまでとします。

来週は今週勉強した部分を実装します。

4.Materialの勉強

Ben Cloward先生のAdvance MaterialのTutorialですが、現在46まで行っています。

先週、実装が終わったのが28で今週勉強する予定なのが29になります。

もうこんなに進んじゃったの?

でもこれ一見沢山あるように見えて、

  • Procedural Brick関連
  • Vertex Shader関連
  • Water Surface関連
  • Particle System関連

の四つの話だけです。

いやそれでも多いです。

4.1 Procedural Brick Color Shader - Advanced Materials - Episode 29 [3]を勉強する

今週は先週作成したBrickに色を付けるそうです。

最初の半分はUnityにおける実装の説明なのでSkipします。

UEのところから勉強を開始します。

3つの方法で色を追加するそうです。

まず最初の方法です。

以下のように2つの色をLerpノードで繋ぎます。

更に前回の結果をAlphaに繋げます。

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

この時点でもかなり良いです。

しかしTutorialによると更にそれぞれのBrickの色を少しだけ変更するそうです。

以下の箇所にFloorノードを追加します。

FloorノードのReviewです。

ほとんどの箇所で、値が1より大きいのでどうなっているのかよく分かりません。

0.1を掛けます。

結果です。

これならそれぞれの値がどうなっているのか何となく分かります。

Floorノードの結果を、前に作成したMaterial FunctionであるHash23に繋ぎます。

このNodeはInputしたVector2の値からRandomなVector3の値を生成する機能があるそうです。

これ既に2回位実装した記憶があります。

ただ新しいPCになってから実装したかどうかは不明です。

どうせどうやって実装したのかも覚えてないので、新しく作り直す事にします。

Hash23ノードの結果です。

RGBの3つのRandomな値を得る事が出来ました。

ただここでは1個のRandomな値があれば十分なので

以下のようにMaskノードを使用してRの値だけ取り出します。

以下のように実装を追加する事でBrickの色に変化を付けます。

まあ、このやり方が一番基本的ですね。

結果です。

おお、それぞれのBrickの色が微妙に変化しています。

更に複雑な色の変化を追加したい場合は、Hash23ノードの結果を全て使用してHSVの値として代用して色を生成する方法があるそうです。

以下のようにHSVToRGBノードを使用して計算するそうです。

まずHash23ノードの結果に以下の計算をかけて

値のRangeを-1~1の間に変換します。

この値のまま色を変化したらBrickらしい色は全部消えてしまうので、以下の値をかけて変化を小さくします。

この結果を先程の色に加算します。

結果です。

おお。

先程の色の変化と比較するとこっちの方が現実の色の変化に近い気がします。

この結果をLerpノードのBにつなぎ

結果を見ると以下のようになります。

うーん。

Hueに沿って色を変化させるとRGBで変化させるより現実の色の変化に近づきますね。

良い事知りました。

Hueの調整する値を以下のように変化しました。

結果です。

基礎の色も少しだけ変更しました。

結果です。

うーん。

この辺の値はもっと色々試す価値がありそうです。

実装が完成したら色々試す事にします。

最後に以下の箇所の値を変更してBrickの数を変えても

以下のように

Brickの色の変化のPatternが重なる事は無い。という長所を紹介しています。

これはTextureを使用する場合と比較して優位な点の一つです。

以上でした。

最初に3つの方法で色を追加する。と言っていたはずですが一個しか方法紹介していません。

もう一回その部分を聞き直してみます。

やっぱり言っていました。

5.Gaeaの勉強

5.1 「Gaea 2.0の公開に関しての連絡」という動画を作成した

かなり難産でしたがやっと完成しました。

以下に内容をまとめます。

PowerPoint

題ですが、簡単にしました。

ここでGaea 2.0の無料版が出るまではこのTutorial Seriesを続ける事を説明しています。

Gaeaをめぐる3つの大きな環境の変化をここで説明しました。

最初の環境の変化、Gaea 2.0のEarly Accessについて解説しています。

特に2つの点

  • UIや機能は大幅に変更された?
  • Gaea2のHomepageを見ると無料版は無いみたい?

が問題であると説明しました。

UIや機能の変化が何故問題なのかについての説明です。

Gaea 2.0の無料版が無い可能性が高い事から、Gaea 2.0が有料版しかない場合はどうするのかについて議論しています。

結論を述べています。

今年のNvidiaのGTCでGaeaを使用して作成したCGが公開されました。

NvidiaのGTCがどれだけ注目された発表だったのかについての解説です。

Gaeaへの評価も「今までの無料で商業利用できるお得なSoft」から、「Landscapeを作成するなら一番高品質のSoftであるGaea」に変りました。

UE5.4が公開されましたが、新しい機能として88,000,000kmのLandscapeが作成出来るようになりました。

これによりGaeaの有料版を買う価値が上がりました。

それについて解説しています。

最後にまとめです。

<動画>

録画しました。

録画したのを聞くと内容がおかしかったり、PowerPointの間違いが見つかったりして結局、3回も取り直しました。

三回目の動画をDavinci Resolveで編集しました。

何故か爆発音のところだけ音がずれていたので、その部分を直しました。

その結果、結局3回作り直してやっと完成しました。

以上です。

6.UE5.4の新しい機能について

今週からUE5.4のMotion Designを勉強します。

6.1 Unreal Engine 5.4 Motion Design in 10 MINUTES! | 2024 [4]を実装する

先週、勉強したTutorialを実装します。

まずUE5.4を起動します。

始めて起動しました。

凄い時間がかかってやっと起動しました。

Pluginを開いてMotion DesignをEnableしました。

再起動します。

New Levelを開くと今度はMotion Designが追加されていました。

正しこのTutorialではEmpty Levelを選択します。

Motion Designを押します。

Editorが以下のように変化しました。

おお、今までのUEのEditorと全然違います。

今度はTool BarにあるCreate Defaultsを押します。

以下のBoxが表示されます。

Spawnを押しました。

Preview画面は真っ暗なままです。

なんか下の方に今まで見た事のないIconが並んでいます。

Motion Design Outlinerを見ると以下のようになっていました。

CameraをUnlockして自由に動くようにします。

今、Pilot Modeになっていますが、このままCamera動かして良いんでしょうか?

Tutorialを見て確認します。

TutorialではCameraを以下の位置までPilotで操作して

もう一度固定していました。

同じ様にしました。

ActorsからCloner Actorを選択したLevel上に配置しました。

原点に配置しました。

Cloner2のDefaultCubeを消します。

Lego Blockが見つかりません。

Tutorialを見直したらDescriptionに以下の場所からDownloadして下さいとありました。

以下のPageに飛びました。

これをDownloadします。

UEにImportしました。

赤しかないです。

青と黄色も作成します。

しました。

Cloner2にSM_LegoCube_Blueを追加しました。

結果です。

近づいて確認したら以下のようになっていました。

Tutorialの映像とは一寸違いますね。

まあ良いです。

ClonerのSpacingの値を以下のように変化させました。

Legoの隙間が無くなりました。

今度は赤いLegoを追加しました。

結果です。

ここで気が付いたんですが、Tutorialと比較するとLegoにPlastic感が足りません。

Materialの値をすこしだけ変更します。

以下のようにしました。

Mesh Render ModeをRandomに変更します。

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

おお、配置がRandomになりましたね。

Coloner2のCountの値を以下のように変更しました。

結果です。

おお、一気に凄くなりました。

Cameraから見るとこんな感じです。

LegoをNanite化しました。

したけど可視化して確認したらなって無いです。

なぜ?

まあ別にならなくても動きが遅くなったりはしてないのでこのまま続けます。

新しいClonerを配置しました。

次にCloner3を選択してConstraintをTextureにセットしTextureにLogoをセットしました。

TextureのLogoは今作成しました。

Cloner3に黄色のLegoをセットしました。

Count数を50に変更しました。

Spacingの値もCloner2と同じにします。

Block一個分だけZ軸に沿ってあげると

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

今度はEffect Actorを追加します。

と思ったらActorを追加するWindowがありません。

うーん。

どうやって開くんだったけ?

あ、

UEがCrashしてしまいました。

もう一回起動させました。

先週のBlogには以下のように書いてありました。

しかし私のは以下のようになっています。

見事にEditor Modeだけありません。

理由が分かりました。

以下の箇所がSelectionにセットされていたからです。

Motion Design Modeに直したら

以下のようにBoxが表示されました。

Effector Actorを選択して配置します。

こんな感じになりました。

このEffector Actorの名前をE_Planeに変更します。

しました。

次いでにCloner2とCloner3の名前も変更します。

Cloner_Planeを選択してEffectorsにE_Planeをセットしました。

今度はE_Planeを選択してTypeの値をUnboundに変更しました。

ModeをNoise Fieldに変更しました。

更にPanの値とLocation Strengthの値を変更しました。

波打つようになりました。

Frequencyの値を変化させました。

値が大きくなると波が増えます。

画像の処理がかなり遅くなってきました。

Nanite化しないと駄目っぽいです。

うーん。

調べたけど分かりません。

E_PlaneをDuplicateしてE_Textを作成しました。

これをCloner_TextのEffectorsにセットします。

文字も波打つようになりました。

ただ文字がPlaneの下に沈んで見えなくなるのは変です。

Tutorialは文字は常に見えています。

文字の位置がかなり高い場所にある感じです。

文字の位置を上げてみます。

Cloner TextのZの位置を500まで上げてみました。

結果です。

今度はイイ感じになりました。

最後にSpot Lightを追加します。

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

一応、これで完成とします。

7.Houdiniの勉強

7.1 Houdini 19 - Wall Tool 09 [5]を実装する

先週勉強したHoudini 19 - Wall Tool 09 [5]を実装します。

<Delete Small Parts>

Labs Delete Small Partノードを追加します。

Thresholdの値を0.4に変更します。

結果です。

Blockのいくつかが消えました。

更に黄色くしました。

次にする事は大変計算Costが高いので、WallのSizeを小さくしてからやるそうです。

Line_Widthを選択して

Lengthの値を3に変更しました。

結果です。

Resample_BrickRowノードを選択して

Segmentの値を6に落としました。

結果です。

今度はLine_Heightを選択します。

Lengthを2にします。

結果です。

はい。

これで準備が整いました。

Labs Edge Damageノードを追加します。

ただしこのNodeを使用すると大変計算が遅くなってしまうので、このNodeの必要な機能だけを持つ実装を別に作成してそれで代用する事にするそうです。

<Node Network>

For-Each Connected Pieceノードを追加します。

Foreach_begin3を可視化します。

結果です。

Remeshノードを追加します。

結果です。

なんかとんでもない形状になりました。

Target Sizeの値を0.03に変更しました。

結果です。

今度はMaskを追加してBrickにDamageを追加する箇所と追加しない箇所を指定します。

そのためにLabs Measure Curvatureノードを追加します。

Labs Measure Curvatureノードを可視化します。

結果です。

Tutorialの例と違って赤い部分と黒い部分しかないです。

Groupノードを追加します。

可視化します。

Group TypeをPointsに変更します。

結果です。

Group Nameの値をEdgeNoiseに変更しました。

更にBase Groupの値を@convexity>0.7にしました。

結果です。

赤い部分のVertexだけ選択しています。

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

結果です。

なんかとんでもない事になっています。

GroupにEdgeNoiseを指定します。

結果です。

Range Valuesの値をZero Centeredにします。

これは最初からなっていました。

Amplitudeの値を0.09に下げます。

結果です。

かなりBrickの形状に戻って来ました。

Element Sizeも下げます。

1から0.227に下げました。

結果です。

あれ、もっとひどくなりました。

<Boolean Intersect Node>

今度はBoolean Intersectノードを追加します。

Foreach_Begin3ノードの結果をBoolean Intersectノードの左Pinに繋げます。

Mountain1ノードの結果を右Pinに繋げます。

結果です。

色を消します。

Measure_curvature1ノードを選択してExport ColorをDisableします。

Export ColorなんてParameterはありません。

代わりにVisualize Outputを消すと

赤が消えました。

これで代用します。

<Smooth Node>

Smoothノードを以下の場所に追加します

AttributesにNを追加します。

Strengthの値を41.44に上げます。

この状態でMountainノードの結果を確認します。

まだおかしな見た目をしています。

今度はMountainノードとBooleanノードの間にPeakノードを追加します。

Distanceの値を0から0.012に上げました。

結果です。

もっとおかしな結果になったようにも見えますが、どうなんでしょうか?

Booleanノードの結果を可視化します。

あれ、すごく良くなっています。

MountainノードのAmplitudeの値をさらに下げます。

Amplitudeの値を0.032にしました。

Booleanノードの結果です。

物凄く良い感じになりました。

<Offset the Noise Pattern>

最後にOffsetを追加します。

まずForeach_begin3_metadataを作成します。

MetaDataノードは以下の場所から作成します。

作り方を忘れていたのでこの場所に辿り着くまで結構探しました。

名前をIterに変更します。

Tutorialでこれだけ名前を変更した理由は不明です。

先週のBlogではこの続きに

と書いていますが、当然Iterノードの結果をMountainノードにPassしたはずです。

Tutorialで確認します。

確認したら何もやっていませんでした。

単にMetaDataノードを作成すれば、そのMetaDataにあるDetail Attributeは使用出来るみたいです。

あ、違った。

MountainノードのOffsetにdetail(“../iter”, “iteration”, 0)と書かれていました。

Iterノードにあるiterationと指定したから、直接Node同士を繋がなくてもそのNodeの値を取ってこれるようになったんでした。

MountainノードのOffsetの値を変更しました。

Booleanノードの結果です。

そしてBooleanノードの結果をForeach_end3の左Pinに繋ぎます。

Foreach_end3の結果を可視化します。

おお、Brickの端が削れています。

Peakノードを黄色くします。

Distanceの値を小さくします。

結果です。

おお、Brickの削れている部分が増えました。

MountainノードのElement Sizeの値を変更します。

結果です。

こっちは削れている幅を大きくしたんでしょうか。

どっちにして結果は凄いです。

7.2 Houdini 19 - Wall Tool 09 [5]を実装した感想

前回のBlogで以下の感想を書きましたが、

前回よりは何をやっているのかは理解出来きました。

要は、このやり方をするとBrickの辺を削った状態に変更出来るんです。

ただし具体的な実装に関しては今回は深入りしません。

焦って勉強して全部ご破算になる可能性があるからです。

それよりも少しずつでも前進した方が良いからです。

この技術は色々応用出来そうです。

Robotや戦車の装甲に使用したら、戦闘後の激しさを表せそうです。

やっている途中で以下の画面が開いてしまいました。

記録のためにもう一回Houdiniを開いたら直っていました。

もう再現出来ませんが、直し方が分かりません。

まあ、Houdiniを再起動すれば直る事が分かったので再起動すれば良いですね。

8.UEFNの勉強

8.1 HOW TO ANIMATE YOUR CUSTOM PET - Fortnite UEFN / Creative 2.0 Tutorial [6]を勉強します

先週、 Spawn Custom Pets / Props in Fortnite - UEFN / Creative 2.0 [7]の実装が終わったのでその次のTutorialであるHOW TO ANIMATE YOUR CUSTOM PET - Fortnite UEFN / Creative 2.0 Tutorial [6]を勉強します。

2024-03-24のBlogで以下に示した様に少しだけ勉強していますが、

Spawn Custom Pets / Props in Fortnite - UEFN / Creative 2.0 [7]の勉強が終わった後でないと理解出来ない内容なので

最初からやり直します。

<Intro>

前回はStatic Meshを生成するだけでしたが、今回はSkeletal Meshを生成した上でそれを動かすそうです。

ModelのCharacterはここからDownloadしたそうです。

<Creating our Freddy Prop>

前回作成したPropのBPであるFredをDuplicateしてFreddyを作成します。

開きます。

Static Meshを消してSkeletal Meshを追加します。

先程のSkeletal Meshをセットします。

更にAnim to Playに以下のAnimationをセットします。

これってSkeletal MeshをDownloadした時についてくるんでしょうか?

これついてこなかったらその時点で話が終わってしまいます。

と思ったら取りあえずは何もセットしないそうです。

そしてLevel上にこのBPを配置しました。

<Creating Cine Sequence Devices>

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

名前をIdle Animationに変更します。

このCinematic Sequential DeviceをDuplicateします。

名前はFreddy Running Animationとします。

<Creating Animation Sequences>

今度はこのDeviceに使用するLevel Sequenceを作成します。

FreddyIdleとFreddyMoveと名付けます。

Level Sequenceを開いてFreddyを追加します。

Trackを押して以下のBoxを開きます。

Animationから以下のAnimation(手を振っている方)を追加します。

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

以下の赤いBarはSequenceの最後を示しているので

Animationの最後に移動させます。

もう一方のLevel Sequenceには走るAnimationを追加します。

Cinematic Sequence DeviceにLevel Sequenceをセットします。

Animationが8秒以上必要になる場合も考えてLoop PlaybackをEnableしておきます。

同じ事をもう一個のCinematic Sequence Deviceにも行います。

<Setting Up Creative Prop in Verse and Cinematic Sequence>

先週作成した以下の部分は使用出来ないと言っています。

このVerse内でSpawnしたObjectにAnimationの追加は出来なかったそうです。

うーん。

やっとこの部分の意味が理解出来ました。

のでまず以下の実装を追加して

Creative_propのConstantを宣言します。

実態はUEFNで追加します。

そして以下のVerse内でObjectをSpawnする実装を消します。

すると以下の部分がErrorになります。

のでここにPassするためのFunctionを新たに作成します。

最後のArgumentの値が違っていました。

動画では途中で切れていますが、

Freddy Propを追加しています。

先程のErrorが起きている実装のArgumentをこの関数に変更します。

でここからが一寸オカシイです。

なんと画面上から今作成した関数であるStartFollowingPlayerが消えてしまっています。

これはあれだ。

最後までTutorialを作成した後で、2つのAnimationをVerseで生成したPropには追加出来ない事が判明したんでしょう。

で、先程の部分だけ直した。

うーん。

最低のTutorialになったな。

Comment欄にも同じ事を指摘している人がいました。

更に動かないって書かれています。

は。

そらそうだ。

そして盲目的にほめている人達の群れ。

これはYouTube Cultやな。

そもそも今回のTutorialの目的はVerseで生成したSkeletal Meshを含むPropにAnimationを追加する方法を勉強する事だったはずです。

それが出来なかったので、UEFNで生成したPropを使用する事にしました。

この時点でグダグダです。

でも最後までやってからそれを直したら、まだTutorialとしては及第点を取れたでしょう。

でも最後まで見るだけは見てみましょう。

Running Sequenceの宣言を行います。

更にもう一個のLevel SequenceのためのConstantも作成します。

<Making Pet Follow at a Distance from the Player>

先週のTutorialではPetはPlayerの中心まで追いかけてきていました。

これは変なので、Playerの手前で止まるようにします。

そのためのConstantをまず作成するそうです。

そして以下のIf節をPetFollowsPlayer()関数に追加しました。

また画面が変になりました。

今追加したIf節がどっかに行ってしまいました。

仕方ないです。

ここは心の目で先程追加したIf節があると思って見ていきます。

でもバットボタンは押しておきましょう。

流石にこのTutorialは作り直すLevelです。

今度はPetがPlayerの右側に立つようにするそうです。

PlayerRightを追加しています。

そしてMove to()関数のArgumentを以下のように変更しました。

うーん。

これがあるなら先程のIf節は要らないかもしれません。

どっちにしろ、今回のTutorialはダメダメですけど。

<Programing Sequence Animations>

今度はAnimationを追加します。

まず以下のVariableを作成します。

そして以下の実装を追加しました。

それは良いんですが、今度はIf節が追加されています。

もう滅茶苦茶です。

Idleも追加していました。

更にElse節も追加しています。

これIdleじゃなかったらRunningのAnimationを流す訳だからどっちか一個で良いです。

今週のPi Equals Three氏は何をやってるでしょう。

今までの切れがまったくないです。

ここでIdleSequence.stop()関数を追加しています。

ここに追加するならElseの方にも追加する必要があるんじゃないの?

流石にこれは追加していました。

<Making Pet Face Player>

PetがPlayerの方を向くようにするそうです。

しかし最初は以下の実装をFollowsPlayer()関数に追加してCameraが上から写すようにしました。

このCodeを改良してPetの向きをPlayerに向けるようです。

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

ここはまあ納得です。

そして生成された値を以下の場所に追加します。

<Stopping Freddy from Flying>

ここはDirectに以下の実装を追加していました。

いや

に指定していました。

更にStartFollowingPlayer()関数に

を追加しました。

も追加しました。

<Last QOL Tweaks / Bug Fixes>

以下の箇所に0.75を追加しています。

Yの方にも追加しています。

UEFNに戻って以下の設定にしました。

ここではFreddyPropにLevel上に配置されたFreddyをセットしていました。

という事はこの時点では既にPropをVerse内で生成するのは諦めたという事になりますね。

<Final Result>

それなりに動いていますね。

FreddyはPlayerの方を向いていません。

出来てないです。

8.2 HOW TO ANIMATE YOUR CUSTOM PET - Fortnite UEFN / Creative 2.0 Tutorial [6]を勉強した感想

このTutorialヤバすぎます。

このまま作成しても多分、動かないでしょう。

でもそれ故にこのTutorialを自分で直して動かせるようにしたら、実力がつく気がします。

ので来週は一寸だけ試してみます。

9.DirectX12の勉強

9.1 Lötwig Fusel氏のD3D12 Beginners Tutorial [D3D12Ez]を勉強する

9.1.1 先週の復習をする

先週何をやったのかまったく覚えていません。

Blogを読み直します。

Fence & Command List | D3D12 Beginners Tutorial [D3D12Ez] [8]の最初の10分を実装していました。

FenceをEventを使用して実装していました。

9.1.2 Fence & Command List | D3D12 Beginners Tutorial [D3D12Ez] [8]の次の10分を勉強する

次はCommand Listについての話です。

OperateをするためにCommand Listを使用するそうです。

Command ListはCommand Queueによって実行されると説明していました。

Command ListやCommand Queueに関しては結構勉強しました。

前のBlogを見て確認します。

これこれ。

この関係さえ理解しておけば良いんです。

Tutorialでは口で説明してるだけで、訛りが凄くて何を言っているのか今一分かりません。

Command listがGPU側に行くと、ある値をCheckしてOKだった場合、そのCommand Listにある命令を実行する。みたいな解説でした。

後、Command Allocatorの機能についても解説していました。

この部分はFront EndとBack Endに例えて説明していました。

しかし何が言いたのかよく分からないです。

ID3D12CommandAllocator型のVariableを宣言していました。

そしてID3D12GraphicsCommandList7型のVariableを宣言します。

この辺は、Command List、Command Queue、そしてCommand Allocatorの関係を理解しておけば取りあえずは良いでしょう。

これらを初期化するための関数を追加します。

その前に以下のように実装を整理していました。

これ見るとCommand Queueは既に初期化していますね。

CreateFence()関数のCodeのSUCCEEDEDをFAILEDに変更します。

そしてCreateEvent()関数も以下のようにCodeを変更しました。

この時点でかなりSample Codeの実装と同じになっていますね。

そしてCommand Allocatorを初期化しました。

CommandListを初期化しました。

当然、初期化したものはReleaseする必要があります。

Shutdown()関数内に、Command ListとCommand AllocatorのRelease()関数を追加します。

Fenceは?

FenceはReleaseしなくていいの?

そしてCommand Listを使用するための関数を作成します。

名前はInitCommandList()としていました。

InitCommandList()関数の実装です。

最初にCommand AllocatorとCommand ListをResetしています。

ここで10分たったので、残りは来週以降やる事にします。

今週はCPUの命令をGPUに送るために必要なCommand ListやCommand Allocatorを作成しただけで終わってしまいました。

9.1.3 Fence & Command List | D3D12 Beginners Tutorial [D3D12Ez] [8]の次の10分を勉強した感想

Command ListとCommand Queueの機能は

以下の図を見ると一発で理解出来ますが、

Command Allocatorの機能は全く覚えていません。

過去のBlogを見直して復習します。

まずCommand Allocatorの話が最初に出て来たのは2023-02-19のBlogでした。

何をするためのObjectなのか全く分からないと書いていました。

その後、ずっとこのObjectの目的は不明と書いていて、

2023-03-20のBlogでやっと以下の回答を得る事が出来ました。

更に2023-03-27のBlogで以下のような説明をしていました。

うーん。

今、読み直すとこの説明もよく分かりませんね。

もう一回、「DirectX 12の魔導書」の「3.3.2 Command Listの作成とCommand Allocator」を読み直します。

でもその前にBlogでCommand Allocatorについて述べている箇所を全部、復習してしまいます。

2023-06-19のBlog

以下の用語の意味について復習していました。

む、Swap Chainとか、Render Targetとか、Descriptor Heapとかの機能はもう忘れています。

うーん。

ここでCommand Allocatorの復習もしていました。

更に実際の実装方法もここで紹介していて

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

そして以下のようにまとめていました。

うーん。

この説明、かなり的を得ている気がします。

Command Allocatorの目的は、Command Listを作成するために必要なもの。という理解にしておきます。

9.1.4 「DirectX 12の魔導書」の「3.3.2 Command Listの作成とCommand Allocator」を読む

もうCommand Allocatorの目的は大体理解しましたが、一応「DirectX 12の魔導書」の「3.3.2 Command Listの作成とCommand Allocator」は読み直します。

読み直しました。

要するにCommand ListにはMemoryが無いんです。だから作成した命令を貯めるMemoryを別な場所に確保する必要があるんです。それをCommand Allocatorが担当しています。

はい。

これでCommand Allocatorの理解は十分でしょう。

Command Allocatorの目的を調べるために過去のBlogを読み直したんですが、

なんと今週の最後で実装したCommand ListとCommand AllocatorのReset()関数について何週にも渡って議論していました。

これは来週、読み直す事にします。

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

9.2.1 前回の復習

「4.8 Graphic Pipeline Stateの作成」の実装をしていました。

そうだ。

先々週で「4.8 Graphic Pipeline Stateの作成」が終わったんだ。なので先週は、「4.8 Graphic Pipeline Stateの作成」の実装をしたんです。

実装するに当たって

Depth Stencil Stateの実装がSample Codeではあったのに、「4.8 Graphic Pipeline Stateの作成」では無かった事を記録していました。

これは忘れてしまいそうです。

いや、先週のBlogに書いていたのに既に忘れてしまっています。

もう追加してしまいます。

Commentにまだ教科書には書かれていないと書いておきました。

後で、この部分の実装が教科書で出てきたら、何でこの実装を既にしているのかをこのCommentで思い出します。

もしこの部分の実装がここで実装しておかないといけないものだった場合は、今実装しているので後で問題が起きる事は無くなります。

これでこの部分の実装について忘れてしまっても大丈夫です。

9.2.2 「4.9 Root Signature」を勉強する

では今週はその次の節である「4.9 Root Signature」の勉強を行います。

<「4.9.1 Root Signatureとは」を勉強する>

最初にRoot Signatureの機能について解説しています。

しかしその説明は「Descriptor Tableをまとめたモノ」と言うDescriptor Tableが何なのかを知らないと理解出来ない、なんとも不親切な説明です。

と思ったらDescriptor Tableの説明もありました。

Descriptor TableはDescriptor HeapとShaderのRegisterを関連付けるそうです。

Descriptor HeapもShaderのRegisterもどんな機能なのか覚えていません。

ここから調べないといけないのかと思ったらその後に、もう少しかみ砕いた説明がありました。

GPUにどのSlotからどのくらいのTextureやDataを使用するのかを教えるのが役割だそうです。

こっちは分かり易いです。

最初にこっちの説明をして欲しかったです。

<「4.9.2 (空の)Root Signatureを生成する」を勉強する>

この節は結構長くて更に内容も濃いみたいです。

慌てずにゆっくり勉強します。

まずRoot Signatureが無いとE_INVALDARG Errorになる事が述べられています。

あ、これ自分のProjectでまだ試してなかったです。

うーん。

来週、実装する時にこれもやる事にします。

今回は別にTextureを使用する訳ではないので、空のRoot Signatureを作成します。

以下の手順で生成するそうです。

  1. D3D12_Root_Signature_Descの設定
  2. (1で設定したD3D12_Root_Signature_Descを)Binary Codeに変換
  3. 生成したBinary Codeを使用してRoot Signatureを生成
  4. Graphics Pipeline StateにRoot Signatureをセットする

実際に生成するのは3までですが、一応4も追加しておきました。

ここからそれぞれの手順の具体的な実装方法が説明されています。

<<「D3D12_Root_Signature_Descの設定」を読む>>

D3D12_ROOT_SIGNATURE_DESC structureの設定方法について解説していました。

公式SiteのD3D12_ROOT_SIGNATURE_DESC structure [9]では

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

教科書の説明によると、今回は空のRoot Signatureを作成すれば良いだけなので

ここの設定は以下のFlagだけ指定すれば良いそうです。

公式SiteのD3D12_ROOT_SIGNATURE_DESC structure [9]では

このFlagは

と解説されていました。

という事はD3D12_ROOT_SIGNATURE_FLAGSにどんな種類があるか調べる必要があります。

公式SiteのD3D12_ROOT_SIGNATURE_FLAGS enumeration (d3d12.h)[10]です。

以下の種類がありました。

上から2番目のを使用していますね。

ここでInput Assemblerを使用します。と指定しています。

教科書によるとこれが、頂点情報だけあります。後は何もない空のRoot Signatureです。

という意味になるそうです。

うーん。

これ教科書の解説が無かったら全く意味不明ですね。

<<「Binary Codeの生成」を読む>>

ここで手順の2番目の作業である「2.(1で設定したD3D12_Root_Signature_Descを)Binary Codeに変換」をやるみたいです。

まず教科書を読んでみます。

これは簡単でした。

D3D12SerializeRootSignature()関数を使用すればいいだけでした。

公式SiteのD3D12SerializeRootSignature function (d3d12.h)[11]を見ます。

うーん。

Remarkとかもそれなりにしっかり読んだんですが、この関数がBinary Codeを生成してくれる。という最も肝心な説明な載ってなかったです。

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

Versionの設定で教科書では敢えて1.0を使用しています。

何故、敢えて1.0を使用したのかについての理由が詳しく書かれていました。

まあ1.0を使用すればその辺の問題は回避できるので今回はそのまま1.0を使用します。

Sample Codeの実装です。

3つ目のArgumentは以下のように生成されていました。

<<「Root Signature Objectの生成」を勉強する>>

「3. 生成したBinary Codeを使用してRoot Signatureを生成」の部分です。

CreateRootSignature()関数を使用して作成します。

当然ですが、このCreateRootSignature()関数はDeviceのMember Functionです。

Sample Codeを見ると

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

更にこの後すぐ、RootSigBlobを開放していました。

教科書では特にこの関数に関しての説明は無かったです。

一応、公式SiteのID3D12Device::CreateRootSignature method (d3d12.h)[12]も見ておきます。

今、気が付いたんですが、Copilotが以下の回答も表示してくれていました。

Root Signatureを生成するんじゃなくて、Root Signature Layoutを生成するんだ。と書かれているのは結構重要なPointかもしれません。

更にCreateRootSignature()関数のそれぞれのParameterについても詳しい解説が出て来ていました。

公式Siteの最初のParameterであるNodeMaskの説明です。

Copilotの説明です。

ほとんど同じです。

これはNY Times社がChat GPTはNY Timesの記事で学習しているんじゃなくて、盗んでいるだけだ。と訴訟を起こすのも理解出来ます。

まあDirectXとCopilotに関してはどっちもMicrosoftのものなので問題無いでしょうが。

<<Graphics Pipeline Stateに設定する>>

最後の部分です。

これでRoot Signatureの実装はお終いだそうです。

実行するとCreateGraphicsPipelineState()関数がS_OKを返すそうです。

以上です。

9.2.3 「4.9 Root Signature」を勉強した感想

やっぱし「DirectX 12の魔導書」は分かり易い。

他のDirectX 12の教科書やTutorialと比較して頭一つ、二つ抜き出ています。

これは最初はよく分からなかったですが、勉強を継続すると段々その凄さが理解出来ます。

噛めば噛むほど、味の出るスルメみたいな教科書です。

こういう教科書はもっと評価されるべきです。

10.まとめと感想

特にないです。

UEFNの勉強に使用しているPi Equals Threeの今回のTutorialは最悪でした。

前回のTutorialは凄い良かったので、まだ継続して勉強しますが、

このまま質が低下した状態で続くようなら、別な人のTutorialで勉強する事にします。

11.参照(Reference)

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

[2] KiironoMidori. (2024, February 13). 「要求されたリソースは使用中です。」の解決策を模索した話. パハットノート. https://kiironomidori.hatenablog.com/entry/android-file-copy-error

[3] Ben Cloward. (2023, November 9). Procedural Brick Color Shader - Advanced Materials - Episode 29 [Video]. YouTube. https://www.youtube.com/watch?v=sQB8VfN_EZY

[4] Reality Forge. (2024, March 23). Unreal Engine 5.4 Motion Design in 10 MINUTES! | 2024 [Video]. YouTube. https://www.youtube.com/watch?v=RJyajs-Cztg

[5] Rick Banks. (2022, June 21). Houdini 19 - Wall Tool 09 [Video]. YouTube. https://www.youtube.com/watch?v=s5LsbiXhkEU

[6] Pi Equals Three. (2023, May 30). HOW TO ANIMATE YOUR CUSTOM PET - Fortnite UEFN / Creative 2.0 Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=VTHH4S9VjAA

[7] Pi Equals Three. (2023, May 22). Spawn Custom Pets / Props in Fortnite - UEFN / Creative 2.0 [Video]. YouTube. https://www.youtube.com/watch?v=2-0t1mkQ6yc

[8] Lötwig Fusel. (2023, May 22). Fence & Command List | D3D12 Beginners Tutorial [D3D12EZ] [Video]. YouTube. https://www.youtube.com/watch?v=KsCZDeJDXDQ

[9] Stevewhims. (2024, February 22). D3D12_ROOT_SIGNATURE_DESC (d3d12.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_root_signature_desc

[10] Stevewhims. (2022, January 31). D3D12_ROOT_SIGNATURE_FLAGS (d3d12.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_root_signature_flags

[11] Stevewhims. (2022, January 27). D3D12SerializeRootSignature function (d3d12.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-d3d12serializerootsignature

[12] Stevewhims. (2021, October 13). ID3D12Device::CreateRootSignature (d3d12.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-createrootsignature