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 草を追加する

先週調べた以下の草を使用して家の周りに草を植えてみます。

以下の場所に草を配置しています。

結果です。

こんな適当に並べただけでもそれなりに本物っぽくなりました。

Foliageを使用してPaintしてみます。

結果です。

Bookmark1です。

かなりPhoto-Realisticになって来ました。

Bookmark3から見た風景です。

木が揺れすぎてる感がありますがそれでもかなり良くなっています。

Bookmark4です。

これはBookmarkした位置が悪い気がします。

配置したCameraから見た風景も確認します。

Camera1から見た風景です。

あれ。

地面が見えます。

もう少しだけPaintします。

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

Camera2からの映像です。

こっちは今の状態でも十分にPhoto-Realisticです。

2.2 Unreal Engine 5 for Architecture - 2023 Full Beginner Course [2]の勉強の続きをやる

<Light Source>

Light Sourceを勉強します。

UEでは3つのLight Sourceがあります。

  • Material(Emissive Color)
  • 実際のLight (Point Light、Directional Lightなど)
  • HDRI Lighting

だそうです。

HDRI Lightingは何の事は分かりません。

とりあえずTutorialの説明を聞きます。

HDRI LightingはImage全体から生成されるLightだそうです。

うーん。

意味分からん。

Imageって何を指しているんでしょうか?

画面の事でしょうか?

公式SiteにHDRI Backdrop [3]がありました。

TutorialのHDRI Lightingがこれと同じ事を言っているのかは不明ですが、少なくともこのHDRI Backdrop [3]の方法は最後に画面上に光と影を追加しています。

で、TutorialはPoint LightをLevel上に追加しました。

Lightがまぶしすぎます。

のでPoint LightのDetailを調整します。

まずLightの明るさを下げるために以下のIntensityの値を8から1に下げました。

Intensityの単位であるcdはCandelaとよむそうです。

Lightの明かりが眩しくなくなりました。

知らない話だけ記録します。

Source Radiusについてです。

以下のようにSource RadiusをAttenuation Radiusより小さくすると

このLightによって生成される影がSoftになります。

これは知らなかったです。

今度は影についてです。

以下にPoint Lightから作成されたBedの影を示します。

全然、Photo-Realisticではありませんね。

これを直します。

まずShadowには2種類あります。

Cascading Shadowと以下に示したCast Ray Traced Shadowsです。

Cast Ray Traced ShadowsをEnableします。

Shadowの計算はもっと厳密になります。

結果です。

この状態でSource Radiusを10に下げました。

結果です。

Bedの影の形状が正確になっているのが確認出来ます。

うーん。

成程。

なんで映像系のUE5のTutorialがRay Tracingを強行に進めて来るのか今一納得出来てなかったんですが、今のこの説明でやっと納得しました。

確かにこれはRay Tracingを使用した方が良いです。

今度はSpot Lightの説明です。

何とこのTutorialの作者、Bookmarkの使用方法を知りません。

視点をCinema Viewから通常のViewに切り替える度に全然違う場所に飛んでしまって、イライラしています。

結果です。

Point Lightで解説した内容以上の説明はなかったです。

今度はRectangle Lightの説明です。

以下の窓から入って来る光を作成するそうです。

Rectangular Lightの形状を窓にあわせるには

以下のSource WidthとSource Heightの値を変更します。

と説明していました。

これも今となっては常識となってしまいました。

2023-12-03のBlogでしっかり自分で解明していました。

もう一寸早く教えて欲しかったです。

今度はDirectional Lightの説明です。

以下の場所に来ました。

この状態でもかなり綺麗に見えます。

Cast Ray Traced ShadowsをEnableします。

結果です。

これは凄い。

こういう結果を見せられるとRay Tracingが絶対必要という意見も納得出来ます。

今度はMaterialのLightingについてです。

これも知らない事だけ記録します。

SphereにEmittingするMaterialを張り付けて以下のようにしました。

Shimmering(ちらちら光る事)が確認出来ます。

しかしMaterialのこの光をLight Sourceにする事は出来ないそうです。

それは以下の例を見るとわかるように

Sphereを小さくするとGrainy(粒粒)な影が生成されるようになってしまうからです。

設定をLumenに変更するとGrainy(粒粒)な影はもっと顕著になります。

これは流石におかしく見えます。

この問題の解決策も紹介されていました。

以下のようにPoint Lightを同じ場所にセットすれば良いそうです。

更にPoint LightのCast ShadowをDisableします。

結果です。

前よりはましになっていますが、それでもオカシイ部分があります。

これはMaterialの光は使用しない方が良い気がします。

うーん。

これは良い事知りました。

前にNiagaraの勉強でLight Rendererが何で必要なのかよく分からないと書きました。

2022-02-28のBlogの記録です。

これは新たな知見を得ました。

やっぱり映像関連のUEのTutorialはGameのTutorialと比較して質が高い部分があります。

最後の影の微調整の方法を説明しています。

Directional LightのSource Angleを変更して

以下のように影を非常にShapeにしたり

逆にSource Angleの値を大きくして

以下のように影をぼやかしたりしています。

こっちの方がPhoto-Realisticですね。

この画面が少しGrainyだと思ったら以下のScreen Percentageの値を増やす事で調整する事で直す事も出来るそうです。

Tutorialでは200 Percentにしていました。

しかしPCがその計算の負荷に耐えれなくて綺麗な画像は生成されませんでした。

これは最後に映像として出力する時に考慮すべきParameterのようです。

一応、記憶の片隅に留めておきましょう。

これでLightingの節が終わりました。

結構勉強になりました。

2.3 How to 3D Gaussian splat from Aerials to Unreal 5 (Free plugin)[4]を勉強する

先週、以下のように書きました。

のでこれを勉強します。

全部、勉強してやっぱり出来なかったとかになったら時間の無駄になります。

3D Gaussian SplattingのDataをどこから手に入れているのかだけ先に確認しておきます。

Luma Unreal Engine Sample Scenes [5]でDataを得ていました。

うーん。

試しに一個Clickしてみます。

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

うーん。

どれをDownloadしたらいいのか分からないですね。

まあ、でも2024-01-14のBlogで勉強した時のSiteとは違うので

UE用の3d Gaussian SplattingのDataも無料でDownload出来そうです。

とりあえず勉強してみます。

<Intro>

3D Gaussian Splattingの例を表示しているだけです。

<What is a Gaussian Splat?>

超基本的な3D Gaussian Splattingの説明をしていました。

<Luma AI>

Luma AIについて説明しています。いますがFreeで使用出来るという事しか説明していません。

2024-01-07のBlogで確認しましたが、前に使用したUEのPluginはLuma AIのではありませんでした。

<Video Recording>

3D Gaussian Splatting に使用するVideoの撮影方法について説明していました。

こんな所から自分でやらないといけないんでしょうか?

誰かが撮影したDataを使用出来ると思っていたんですが?

以下のWebsiteに行ってStart Now on Web for FreeをClickします。

<Gaussian model creations>

すると以下のBoxが表示されますので

撮影したVideoを以下のBoxにDragします。

次の画面でTitleやCameraのTypeを指定してUploadを押します。

30分ぐらいProcessingにかかるそうです。

以下の画面に代わりました。

Thumb nailをClickすると以下の画面が表示されます。

え。

こんなに簡単に3D Gaussian Splattingって出来るの?

この時点で右上の以下のIconを押すとDownloadが出来ると言っています。

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

おお、Gaussian Splatting & Unreal Engineの項目もありますね。

以下のGaussian SplatをDownloadすれば良いそうです。

でも先程のSiteのBoxにはそんな選択肢は表示されていませんね。

これは後で検証します。

<Luma Unreal Engine plugin>

今度はLuma Unreal Engine PluginのInstall方法の説明です。

以下のSiteに行きます。

このSiteのAddressはこのTutorialのDescriptionに書いてありました。

来週実装する時はここからこのSiteに行きます。

以下のPluginをDownloadしていました。

私の場合は5.3ですしCinematic Filmも試したいのでこのVersionはDownloadしません。

ここでやっと先程のSiteについての解説がありました。

もし自分で撮影したProjectが無い場合はここからSampleをDownload出来ると説明していました。

うーん。

親切。

以下のDataをDownloadしていました。

おお。

どうやらこのやり方なら3d Gaussian Splattingを完全にFreeで出来そうです。

Unreal baked Gaussian Splat scene>

あれ?

ここからいきなりUE5が始まっています。

既にPluginも入れてDownloadした3D Gaussian SplattingのDataも開いている状態です。

うーん。

これはどうやったのかの説明がいるでしょう。

もしかすると

がUE5のProject込みなのかもしれませんね。

それだと開くだけで済みそうです。

Post Processing以外のAssetを全部消すそうです。

そしてPy FileをContent DrawにDrag and Dropします。

すると以下のようにFolderが自動で形成されるそうです。

この辺はうまく撮影されていません。推測でこうやっているだろうとまとめています。

更にFolderの中には以下のようなFileが作成されてるそうです。

LightingがBakeされたものとされてないDynamic Lightingのもの別々に作成されているそうです。

TAAは質が低い代わりにPerformanceに優れているそうです。

BakedのFileをLevel上に配置しました。

凄い。

全部を表示するのはPCの負担が凄い事になるので一部のみを表示する方法を説明しています。

Cropboxを使用するそうです。

Enable Crop BoxをEnableします。

すると以下のようなCrop Boxが表示されます。

DefaultではCropBox1が表示されるようになっているそうです。

のでこれを移動して

表示したい場所を指定します。

この機能は前に勉強した3D Gaussian Splattingにもありましたね。

<Dynamic Lighting>

こっちではPoly camからSampleをDownloadしていました。

やり方は別なTutorialで教えると言っています。

うーん。

こっちも無料でDownload出来る方法があるでしょうか?

先程のPostProcessだけ残した状態から以下のSun and Skyを追加しました。

結果です。

こんなのLightingにあったかなと思ったら以下のPluginを使用する必要があると言っていました。

そしてLandscape ModeでLandscapeを作成しています。

正直、この辺の操作に関しては私の方が詳しいです。

だいたいこんな風にやると理解しておきます。

Lightが強すぎて何も画面に表示されません。

Post Processの以下のParameterを調整します。

結果です。

Exponential Height Fogを追加しました。

そしてSplatをDrag and Dropするそうです。

むむ。

このUEの設定は単に地面と空を作成しているだけですね。

いつもの方法でやった方が簡単でしょう。

もう少し適切なやり方がありそうです。

以下のようにSplatの新しいFolderが形成されました。

今度はDynamicをLevel上に配置します。

ナニコレ?

SizeとRotationが間違っているみたいです。

回転させて調整しています。

更にCrop Boxも使用して表示する箇所も限定しました。

この状態でSoler Timeの値を調整しました。

結果です。

うーん。

これじゃ3D Gaussian Splattingの質の確認は出来ないです。

<Combining models>

他のSplatのDataもUEにDrag and Dropしました。

そしてそれらをLevel上に配置しています。

うーん。あんまり意義を感じませんね。

<Outro>

なし

以上でした。

2.3 How to 3D Gaussian splat from Aerials to Unreal 5 (Free plugin)[4]を勉強した感想

このTutorialを作成した人は3D Gaussian Splat関連の専門家かもしれませんが、UEに関してはあまり知識があるようには思えませんね。

ただ3D Gaussian Splatを無料でDownloadする方法はこのTutorialで分かりました。

来週ためしてみます。

3. Niagara の勉強

3.1 先週の復習

先週は「Chapter 14 木の生成Simulation」の実装をやりました。

実装は完成したんですが、理解があんまりしてなくて今週はその理解を深める勉強をしたいと先週のBlogに書いてありました。

で、考えたんですがあんまり「Chapter 14 木の生成Simulation」の勉強をしたい気分じゃないので次の章を勉強する事にします。

3.2 「Chapter 15: Fluid Simulation(Logic)」を読む

この章ではSmoothed Particle Hydrodynamicsと言う流体Simulationの計算方法を勉強するそうです。

そしてVectorの簡単な復習をしています。GradientとかDivergenceとかの話です。

Laplacianを足すと画像がぼやけるのは知らなかったですが、画像処理の分野では基礎みたいです。

その次にSimulationの簡単な説明をしています。

ここでは兎に角、最新の加速度を決定する必要がある事が強調されていました。

最新の加速度が決定すれば、そのから最新の速度や最新の位置も計算で導く事が出来るからだそうです。

以下のように解説されていました。

加速度の値を保持する変数をA、速度の値を保持する変数をV、位置の値を保持する変数をPとすると

  • V = V + A
  • P = P + V

で求まると。

これは速度と加速度と位置は単位が違うので実際の計算はこの通りにはならないですが、考え方の方針としては納得です。

そして最新の加速度の求め方ですが以下の加速度を足した値になるそうです。

  • Pressureからくる加速度
  • Viscosity(粘度)からくる加速度
  • Gravityからくる加速度
  • Wallからくる加速度

うん。

分かり易い。

それぞれの値の求め方についても説明してありました。

まずGravityですが、これは地球上では一定ですのでそれを使用します。

次にWallの加速度ですが、これも一定です。

壁の向こう側には行けないので、この値は今の加速度の逆の方向にするだけでしょうか?

Pressureの計算ですが、これは複雑でした。

以下のように解釈しました。

以下のような川があるとします。

とその水の流れの一部を四角く区切ります。

P1には水が入って来てP2からは水が出ていきます。

このP1とP2で区切られた空間内のPressureによる加速度は

となります。

mが流体のMass、NablaのPressureはP1とP2の差、そしてrhoは密度を表しています。

うーん。

流体のSimulationを自作したくて今まで何度も流体力学の教科書を読んでいたんですが、この部分はいつもよく分からなかったです。

今回が一番理解した気がします。

最後にViscosityですが、これは速度から計算していました。

でこの速度の計算に先程のLaplacianのぼやかす効果の話が出て来ます。

正直に言うとここはもう一寸物理の立場から厳密な解説して欲しかったです。

結論としてViscosityの加速度は以下の式で表せる事が分かりました。

そして全ての加速度を合計すると

となります。

はい。

ここまではほぼ完ぺきに理解しました。

こういう事を今まで読んだ流体力学の本は言っていたのか。

うーん。

この作者はUE5のNiagaraの教科書よりComputing Simulationの教科書を書いた方が世間からの評価が高くなりそうな気がします。

説明が素人にも分かり易くて何というか言っている内容を可視化しやすいです。

ここから今までの流体の理論をSPHの理論に落とし込むそうです。

まずカーネル関数について解説しています。カーネルはKernelの事でしょうか?

ここはカーネル関数を変形してGradientやLaplacianの形に変形したりしています。

むー。

この変形した式を後で使用する訳ですね。

カーネル関数自体の意味がよく分かってない部分がありますが先に進みます。

いきなり密度の式が出て来ました。

うーん。

段々分からなくなってきた。

Wのところがカーネル関数になるはずです。それに対してNablaをしています。

この計算方法がまず分からないです。

Gradientの式は以下のようになっているので

カーネル関数の計算結果にxやyで微分するんでしょうか?

その場合、カーネル関数の計算結果がxやyの値を持つ式である必要がありますよね。

でも教科書で紹介されていたカーネル関数の式は以下のようになっています。

XもYもありません。

あれ、でもその次のGraphには

XとYの空間内に描かれていますね。

これもう少し深堀したら理解出来そうです。

が、

これを理解する事がどれだけ大切なのかと言う別な問題があります。

実際に実装する段階になったらすっきりした形の式が既に出来ていて、しかもその式の導出にこの辺の理解が必要なだけかもしれません。

先行きますか。

あ、分かりました。

教科書に「近い距離にParticleが沢山ある」と密度が高くなる。と説明してありました。

つまり以下の式は

それを表しているんです。

残りのPressureとViscosityの導出方法は軽く読むだけにしておきます。

今度はそれぞれのKernel関数の計算方法についての解説です。

ここでPoly6のKernel関数に咥えてSpikyとViscosityのKernel関数が紹介されていました。

そしてPoly6のKernel関数を用いたGradientの計算方法が紹介されていました。

この部分だけ一寸真面目に読む事にします。

になっていました。

あ、分かりました。

Poly6のKernel関数は以下の式で表せます。

このrはx+y+zに変換出来るんです。

うーん。

成程。

教科書にしっかりと

と書かれていました。

残りの計算は軽く見て終わりにします。

次にKernel関数の可視化を行っていました。

Spiky Kernelって何のことかと思ったら

文字通りSpikyなKernelの事でした。

こういうのが一発で理解出来るのが可視化の強みですね。

どのKernel関数を使用するのかについて検討しています。

Poly6のKernel関数のGradientはrの値が0の時に0になってしまいます。のでこれは使えません。

最後に以下の式になりました。

この式を元にして次章で実装していくそうです。

以上でした。

3.3 「Chapter 15: Fluid Simulation(Logic)」を読んだ感想

Smoothed Particle Hydrodynamicsを理解したとはとても言えませんが、その香りというかSmoothed Particle Hydrodynamicsがどんなものなのかを感覚的とは言え感じる事は出来ました。

本当に分かり易かったです。

今まで、何度も流体力学の本を読んで理解しようとして挫折していたんですが、ここに書かれている理論をしっかり理解したら、今度は流体力学の本も理解出来そうな気がします。

この教科書は色々文句を言いたい箇所がありますが、この章の内容に関しては、今まで読んだ科学関連やSimulation関連の本と比較しても最高の出来だと思いました。

 

私は前々から言っているんですが、Game産業って持っても後10年だと思っています。

Gameの技術が余りにも進化しすぎて、Gameを作る人とGameをPlayする人に接点が無くなってしまっています。

のでGameを作る人達はGameをPlayする人達が欲しているモノが分からなくなっています。これは致命的な問題なんですが、この乖離は永遠に埋まらないです。

ので後10年したらGameをPlayする人はいなくなってGame産業は壊滅すると予測しています。

しかしGameを作成するために発展した技術、特に3D Graphicsの技術はGame産業の終焉とともに終わるのではなく、逆に別な分野に応用されて更に発展して行くと思っています。

その中で、もっとも伸びると思っているの分野の一つがUEの世界最高峰のGraphicsを利用した科学Simulationの可視化です。

会社で最高権力を持っている役員の連中にSimulation結果の重大さを数式で見せても全く理解されません。

しかしUEのPhoto-RealisticなGraphicsでSimulation結果(例えば津波が町を破壊する様子)を見せると一発でその重大さを理解させる事が出来きます。

可視化したSimulation結果を見せると信じられない位、役員の人達も話を聞いてくれまし、それだけでなくこっちの話を納得してくれます。

この効果は経験した人でないと理解出来ない位、劇的でしかも好意的です。

 

この本の筆者はこっちの分野の先駆者になった方が良い気がします。

4. Materialの勉強

4.1 Worn-Out LCD Screen Shader - Advanced Materials - Episode 25 [6]を実装する

先週勉強したBen Cloward先生のTutorialを実装します。

以下のTextureを使用していますが

これを作成するのは大変なので、

以下のTextureを使用します。

FlipBookノードを実装します。

Animation Phaseの実装も追加します。

これは何を計算しているんでしょうか?

あ、SubUVのどのImageを表示するかの指定をしているのか。

Dot Gridの実装です。

次に以下の実装をしました。

これは何をしているんでしょうか?

それは分かりませんがInvLerpのValueに先程のDot Gridの計算結果を繋げました。

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

この2番目のLerpノードのAlphaにInvLerpノードの結果を繋げます。

次に最初のLerpノードのAlphaに以下の実装の結果を繋げます。

次はVignetteの実装をします。

更にOne MinusノードとMaskノードのInputにはTexCoord[0]ノードの結果を繋げました。

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

見事なVignetteになっています。

その結果を以下のMultiplyノードのAに繋ぎます。

次にBrightness Flickerを実装します。

ここでTutorialではSineノードのPeriodの値は6.2 になっていましたが、要は2Piの値なので6.28にセットしました。

Brightness Flickerの結果は以下のMultiplyノードのBに繋げました。

Sizzle Linesの実装をします。

MaskノードのInputはTexCoord[0]ノードです。

Sizzle Linesの結果をDot GridのAddノードのBに繋ぎます。

Sizzle Lines のNoiseノードの設定を変更しました。

Screen Onの実装をします。

最初のMultiplyノードのAの値です。

MaskノードはTexCoord[0]ノードの値でした。

このScreen Onの結果を以下のMultiplyノードのBに繋ぎました。

これで完成でしょうか?

Previewの結果ですが

こんなになっています。

まったく時間経過とか表示していません。

もう時間がないので結果の検証は来週やる事にします。

今週はここまでとします。

5. Gaeaの勉強

PowerPointを直して録画をしました。

更に録画した動画を編集してYouTubeにUpload出来る状態にしました。

今回のTutorialは今まで勉強した内容の総集編なので35分の長編になってしまいました。

内容を減らして動画の長さをもっと短くするか、このまま行くのか一寸考える必要があるかもしれません。

後、説明の言葉が聞き取りにくい箇所があちこちにありました。

私は内容を理解しているので特に困ったりはしませんが、初めて聞く人にはどうなんでしょう。

意味が不明な箇所もあるかもしれません。

6. Houdiniの勉強

先週のBlogを読み直したら特に問題もなく実装が終わっていたのでその次のTutorialを勉強します。

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

また目次がありません。

ただ以下のKey Noteはありました。

これを元にして内容をまとめます。

<Intro>

今回はもっとNoiseを追加してBrickのばらつきを増やすそうです。特に上下のNoiseを追加するそうです。

<Attribute Noise>

以下のAttribnoiseを追加しました。

先週までの結果を繋げて可視化すると

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

AttribnoiseのAttribute Name Vectorの値をPに変更します。

PはPositionのPでしょうか?

結果です。

滅茶苦茶になりました。

今度はAmplitudeの値をかなり小さくしました。

結果です。

こっちはかなりマシですね。

XとZのNoiseはいりません。上下のNoiseだけが欲しいです。

先程値を変更したAttribute Namesの右端にあるXYZのIconのXZを外します。

結果です。

おお、上下のばらつきだけが追加されていますね。

今度はNoise PatternのElement Sizeの値をかなり大きくしました。

結果です。

Element Sizeの値を大きくする事でNoizeのCurveが緩やかになるそうです。

言われてみるとBrickの上下のばらつきは全体としてなだらかなCurveを描くようになっています。

次に直す必要があるのが、以下に示したWallの底の歪みです。

地面から盛り上がっています。

これを直すのにMask Awayする必要があると述べています。

このMask Awayの意味が分かりません。

単に隠して見えなくするって意味でしょうか?

ついでにWallの一番上の部分も平にするようにします。

そこでAttribnoiseノードの上にAttribwrangleノードを追加しました。

<Mask Noise>

追加したAttribwrangleノードの名前をAttribwrangle_MaskNoiseと変更しました。

更にWallの形状を管理するParameterを追加するので色を黄色に変更しました。

このNodeでColor Maskを作成するそうです。

<Color Mask>

Color Maskとは「色でどの場所には変更を追加しない。」と指定する方法のようです。

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

Relpointbbox()関数はBoxのBoundaryの値を返すそうです。

この値を利用して床とWallのTopにColor Maskを追加するみたいです。

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

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

真っ黒ですね。

この黒い部分はMaskが掛かってない場所という事になるんでしょうか?

次は以下の実装を追加しました。

Chanel Ramp>

これでBoundaryのYを表す部分は赤くなるみたいです。

以下のIconを押してParameter、Rampを作成すると

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

うーん。

これはYの値が1の場所つまりWallのTopは赤くなって、Yの値が0である床は黒いままです。

残りはGradientに変化しています。

<Ramp Parameter>

生成されたRampのParameterを弄ると

以下のようになります。

更にRampのParameterの設定を以下のように変形します。

結果、

となりました。

おお、これはWallの上と下をMaskしていますね。

後、凄いTipも言っていました。

このParameterの操作についてですが、追加したPointを消したい時は

Pointを選択したままGraph外にDragすると良いそうです。

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

この関数の機能については来週実装する時に調べます。

今、Tutorialの説明を聞いた範囲で理解した内容を書いておくと、rの値が0.5以下のPointをNoise Maskと言うGroupに追加するようです。

Parameterの最後のSetは何を指しているのかは不明です。

そしたらTutorialでFunctionの機能やParameterの設定が分からない時は、

その関数を選択した状態でF1を押せと言っていました。

F1を押すと以下のBoxが表示されました。

おお。

もうWallの色を変えておく必要は無いので

元に戻します。

Attribnoise1ノードに戻って

GroupにnoiseMaskをセットします。

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

これで完成かと思ったら、

次はBrickにヒビを追加するそうです。

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

下のNodeが見切れて見えませんが、以下のNodeが追加されました。

今までの結果をConnectivityノードにつなげて、

Foreach_Beginノードを選択します。

更に可視化しました。

結果です。

これは最初のBlockだけが可視化されている状態でしょうか?

もう10分すぎてしまったので残りの実装は次のVideoで行うそうです。

はい。

今回のTutorialはここまででした。

6.2 Houdini - Wall Tool 06 [7]を勉強した感想

段々、Houdiniの使用方法が見えてきました。

Proceduralな建物の設定に関しては、このWallの設定を複雑にすれば出来そうです。

WallのTutorialをもう2~3回繰り返したら、全容がもっとはっきりしてもっとすっきりした形で整理出来るでしょう。

7.UEFNの勉強

7.1 How To Tell Who Damages You In Fortnite - UEFN / Creative 2.0 [7]を実装します

<Intro>

特になしです。

以下のUIを表示するそうです。

これは2つの情報を表示していますね。

一つ目はDamageの量、もう一つは誰からDamageを受けたかです。

それぞれの情報をどうやって取得したのかが今回のTutorialの肝になります。

先週は、その辺の理解が甘いまま勉強をしたので、どうやってそれらの情報を手に入れたのか理解していません。

今週はその辺の確認のかねて実装する事にします。

<Initialize Modules and Player List>

hit_detect_device.verseを作成します。

VS Codeで開きます。

Fortnite.com/GameとFortnite.com/Characters moduleを使用出来るようにします。

次にPlayer型のArrayを初期化します。名前はPlayersとしました。

うーん。

VerseのArrayの宣言の仕方を忘れてしまっています。

復習します。

公式SiteのArray [8]を見ると

と書かれていました。

でもこれは変数の宣言ではないですね。

後、TutorialのArrayは

となっていて

中身は何も無いですが、

公式SiteのArray [8]は

要素が最初から指定されています。

Arrayが変数の場合は以下の方法で中身を変更出来ると書いてありました。

Setを使用すれば良いみたいです。

Array全体の値を変更する場合と、Arrayの特定のIndexの値を変更する方法の両方が紹介されていますね。

はい。

理解しました。

<Create and Subscribing HandlePlayerHit Function>

Playerに値をセットします。

これはこの方法でGameに参加している全てのPlayerを得る事が出来ると覚えるしかないですね。

次にPlayerがHitされた時にどうするかを指定する関数を作成します。

HandlePlayerHitと言う名前にしていました。

そしてこの関数を呼ぶ実装を追加します。

<Testing out Function>

GameをPlayしてPlayerの操作するCharacterがDamageを受けたらこの関数が呼ばれるかどうか確認します。

どうやったらDamageをPlayerに与えられるのかが分かりません。

Tutorialでやっていたように高い所から飛び降りたんですが、Damageが入りませんでした。

Guard Spawnerを配置しました。

これで敵のNPCがSpawnされるはずです。

それに打たれたらDamageが入るでしょう。

これで試します。

Damage食らっていますが何も表示されません。

hit_detect_device.verseをLevel上に配置するのを忘れていました。

もう一回Testします。

今度は表示されました。

されたんですが、あまりにも一瞬過ぎてScreenshotには撮れませんでした。

先週のBlogにまとめた画像とまったく同じでした。とだけ記録しておきます。

<Using damage_result struct>

誰が誰にDamageを与えたのかを知りたい場合はどうすべきでしょうか?

DamageResultを使用するそうです。

公式Siteのdamage_result struct [9]です。

これを見るとDamage_ResultはStructでDamage Eventが発生する度に生成されるみたいです。

そのStructのMemberには以下のものがあり、

TargetはDamageを受けたObjectの情報を保持しています。

TargetのTypeはDamageableとなっていますが、これってどんなTypeなんでしょう?

まあ良いです。こんだけ理解出来たら十分です。

<Getting Target who was Damaged>

次にTargetの中のObjectがfort_characterであるかどうかを確認します。

以下の実装で確認します。

以下の部分はTarget型をfort_character型にCastしているんでしょうか?

この用法はよく分かりませんね。

<Getting Damage Amount>

今度は受けたDamageも取得します。

これは先程のDamage_ResultのStructのMemberにあるAmountを使用すればいいだけです。

しました。

更にDamage量を表示するために以下の実装を追加しました。

<Getting Instigator / Player who Caused Damage>

ここが先週、何をしているか理解出来なかった場所です。

先程のdamage_result struct [9]によるとInstigatorの機能は以下のようになっています。

CodeやEnvironmentなどでPlayerがDamageを負った場合はFalseになるそうです。

うん。

これは理解しました。

次に以下の実装でInstigatorからDamageを与えたObjectがfort_characterかどうかを確認しています。

この実装はそれだけじゃないですね。

先週のBlogに書いてあった

これについてもう一回Tutorialを見て何と言っていたのかを確認します。

見ました。

InstigatorはOptionalで実際にあるかどうかは不明だから?をつける必要があると言っていました。

damage_result struct [9]のInstigatorの解説を見てもそんな事は書かれていません。

これはFaultだった場合の事を言っているのだと思います。

はい。

でもまあこの部分の実装の意味は理解しました。

次に行きます。

<Skip Here if you don't Care About Optionals lol>

次に以下の実装を追加します。

これが何をやっているのか意味不明です。

先週は

とまとめましたがそうなんでしょうか?

公式Siteのfort_character interface [10]を見ると

Exposed Interfacesの中にDamageableがあります。

このDamageableの公式Siteのdamageable interface [10]を見ると

以下のDamageというFunctionがあります。

これを読むと、Damageを使用するとそのObjectにDamageを与える機能のようです。

となると先週の解釈は合っていたのか。

これ結果はどうなるんでしょうか?

Playerが高い所から落ちてDamageを受けた場合です。

  1. PlayerがDamageを受ける

これで終わりです。

次にPlayerが他のPlayerからDamageを受けた場合です。

  1. Playerが他のPlayerからDamageを受ける
  2. Damage関数が呼ばれて先程の2倍のDamageを受ける

こうなると思います。

あれ、GuardからDamageを受けた場合はどうなるのかな?

一応、GuardもFort_CharacterなのでDamage関数は呼ばれるはずです。

そしてDamage関数によるDamageはCodeによるDamageなので更なるDamage関数は呼ばれないはずです。

更に以下の実装も追加しました。

これで他のPlayer(NPCも含む)からDamageを受けた場合、更に分かり易くなりました。

<Second Result>

この状態でTestしています。

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

うーん?

これってTutorialの結果と違いますね。

何が起きているか分かりました。

Damageを与えたPlayer(NPCも)が与えたDamageの2倍のDamageを受けていました。

でもそれだと何故GuardのCharacterがDamageを受けた時は以下のCodeが実行されないんでしょうか?

あ、分かりました。

多分ですが、以下のCodeが実行された時はまだ

Guardは生成されていないんだと思います。

のでGuardがDamageを受けた時はHandlePlayerHit()関数が呼ばれないんだと思います。

となるとこれで完成しちゃいましたね。

もしかしたらもう少し直さないといけない部分もあるかもしれませんが、最初の目的は達してしまったのでここまでとします。

来週はもう少し深堀するかもしれませんし、しないで次のTutorialに行ってしまうかもしれません。

今週はここまでです。

8.DirectX12の勉強

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

8.1.1 先週の復習

先週で今までやっと所まで追いついたはずです。

先週のBlogを読んで何を勉強したのかを確認します。

分かりました。

先週はDebug Layerの実装まで終わったんですが、その実装が何をやっているのかが全く理解してないのでその勉強を今週やる事にしたんです。

なので今週は先週実装したDebug Layerの内容について勉強します。

8.1.2 先週実装したDebug Layerの内容についての勉強

まずDebugLayer.hの実装です。

Member Functionは以下の2つだけですね。

これは普通のClassでもよくあるMember Functionですね。

次のCodeです。

Debugの場合のみにID3D12Debug6型の変数であるm_d3d12Debugと

IDXGIDebug1型の変数であるm_dxgiDebugを宣言しています。

これは前に作成したComPointerを使用していますね。

こっちも勉強する必要がありますね。

次のCodeです。

これはConstructorですね。

でもSingletonと書かれています。

これPublicだから別にどこでも宣言出来ると思うんですがそれでもSingletonになるんでしょうか?

一寸その辺が分からないですね。

次の実装です。

これは単なるGetterですね。

SingltonなのでSetterはないのは当然ですね。

最後のCodeです。

これは関数を宣言しているのか?

でもPrivateですね。

うーん。

これはSingltonの書き方をもう一回勉強する必要がありますね。

2023-06-11のBlogでSingltonの勉強をしています。

この辺の復習からやって行きます。

2023-06-11のBlogを読んでいたら以下のCodeとほぼ同じCodeがありました。

これはSinglton用のSetterでした。

いやこれがConstructorになるのかも。

2023-06-11のBlogの例はStaticを使用してSingletonを作成しています。

この例とはかなり違います。

ただ以下の意味は分かりました。

これはSingltonなので複製を作れない様にするための実装でした。

以下のGetterの意味がよく分かりませんね。

この中でDXDebugLayer型の変数InstanceをStaticで作成しています。

Instanceが既に生成されている場合は前に生成されたInstanceが返るはずです。Staticですから。

Instanceが無い状態でこのGetterが呼ばれた場合、どうなるんでしょうか?

以下の関数が呼ばれるのか。

となるとこれはConstructorになるのか。

うん。

確かにこのやり方でもSingltonになりそうですね。

次にDebugLayer.cppを勉強します。

まずInit()関数の実装です。

Debugでは時はFalseが返って終わりですね。

Debug時はGetDebugInterface()関数で何かをしてその後にEnableDebugLayer()関数でDebugをEnableしています。

これはID3D12Debug6型やIDXGIDebug1型を使用するための一般的な方法だったはずです。

確認します。

2023-10-09のBlogで勉強していました。

読み直したら、こことまったく同じ方法でDebug Layerを使用していました。

ただしここにはDXGIのDebugに関してはここには何も書かれていません。

2023-10-15のBlogを見るとDXGIのDebugは以下のように実装していました。

む。

_dxgiFactoryの型を確認します。

これは全然違う型ですね。

いろんなやり方がある位の理解に留めておきます。

一寸短いですが今週はここまでとします。

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

8.2.1 先週の復習

「4.6.3 D3DCompileFromFile()関数」を勉強していました。

それぞれのParameterの機能について簡単にまとめています。

そして以下の実装したargumentについて

簡単にまとめておきたいが時間がないので来週する。と書いていました。

今週はこれからやりますか。

8.2.2 D3DCompileFromFileのArgumentの機能を確認する

まずVertex Shader用の設定からみます。

最初のL"BasicVertexShader.hlsl"です。

元々このParameterは

となっています。

ので当然、以下のFile名が入る事になります。

2番目のArgumentは

です。

2番目のParameterは以下の機能となっています。

何も指定する必要がないのでnullptrになっていると思われます。

三番目のArgumentです。

三番目のParameterの機能は以下のようになっているそうです。

D3D_COMPILE_STANDARD_FILE_INCLUDEの機能について以下の解説が表示されました。

うーん。

まずany APIという説明が曖昧でどんなAPIなのか具体的には全く理解出来ません。

教科書見たら簡潔に解説してありました。

D3D_COMPILE_STANDARD_FILE_INCLUDEはShader内に書かれたIncludeで指定されたFileの全てをCurrent Directoryから参照してくれる機能があるそうです。

うーん。

そう言う事なのか。

最後の文のpSourcefileが何なのかは分からないままです。

四番目のArgumentです。

このParameterは以下の指定をします。

一番目のParameterではFile名を指名してこの四番目のParameterではShader名を指名しているんですね。

Shader名は以下の名称の事ですね。

そう言えば以下のPropertyの設定を変更した時に

EntryPoint NameにBasicVSを指定していました。

五番目のArgumentです。

このParameterはpTargetと呼ばれて以下の役割を分担しています。

これはVertex Shader用なのでそのままvs_5_0を指定しただけですね。

六番目のArgumentです。

このParameterはFlag1と言う名称で呼ばれ以下の役割を担当しています。

Argumentの機能については公式siteのD3DCOMPILE Constants [10]に簡単な解説がありました。

です。

教科書にも簡単な解説が載っていました。

D3DCOMPILE_DEBUGはDebug用に使用され、D3DCOMPILE_SKIP_OPTIMIZATIONはShaderの最適化を行わないそうです。

そのままですね。

七番目のArgumentです。

これは以下の説明しかなかったです。

八番目のArgumentです。

このParameterに関しては先週のBlogでは以下のまとめしかしてなかったです。

教科書にもこのParameterに関しては何の解説も無かったです。

D3DCompileFromFile function (d3dcompiler.h) [11]には以下の解説がありました。

後で何かに使用するんでしょうね。

最後のArgumentです。

そのままですね。

はい。

Pixel Shaderに関してはほぼ同じなので省略します。

はい。

今週はここまで力尽きました。のでここで終わりにします。

9.まとめと感想

なしです。

来週は軽い手術をする予定なので、もしかしたら休むかもしれません。

10.参照(Reference)

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

[2] Gediminas Kirdeikis. (2023, April 30). Unreal Engine 5 for Architecture - 2023 Full Beginner Course [Video]. YouTube. https://www.youtube.com/watch?v=bT8aSTkpkDY

[3] HDRI backdrop. (n.d.). Unreal Engine Documentation. https://docs.unrealengine.com/4.26/en-US/BuildingWorlds/LightingAndShadows/HDRIBackdrop/

[4] 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

[5] Notion – The all-in-one workspace for your notes, tasks, wikis, and databases. (n.d.). Notion. https://lumaai.notion.site/978320d3a9da4eec8b4f4590583a8282?v=cdf60ce52b6d4e1aa75eaa9bc7e75b43

[6] Ben Cloward. (2023, October 12). Worn-Out LCD Screen Shader - Advanced Materials - Episode 25 [Video]. YouTube. https://www.youtube.com/watch?v=i4EXZdpVdT0

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

[8] Array. (n.d.). Epic Developer Community. https://dev.epicgames.com/documentation/en-us/uefn/array-in-verse

[9] damage_result struct. (n.d.). Epic Developer Community. https://dev.epicgames.com/documentation/en-us/uefn/verse-api/fortnitedotcom/game/damage_result

[10] Stevewhims. (2022, February 13). D3DCOMPILE Constants (D3DCompiler.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/d3dcompile-constants

[11] Stevewhims. (2022, July 27). D3DCompileFromFile function (d3dcompiler.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/d3dcompiler/nf-d3dcompiler-d3dcompilefromfile