UE4の勉強記録

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

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

1. 今週の予定

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

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

建物の作成の続きをやります。

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 今週の勉強内容を復習する

先週の勉強内容を復習して今週勉強する内容を確認します。

Unreal Engine 5 for Architecture - 2023 Full Beginner Course [2]の勉強内容を復習します。

まずLandscapeに配置する草を探していました。

以下のAssetから配置できそうな草を探します。

次に室内にCameraを配置して以下の調整をしていました。

Cameraはもう一個室内に配置する必要があります。

これも今週やります。

最後に現実の映像とUEを組み合わせる方法を勉強しています。

今週は具体的にどれかのTutorialを勉強します。

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

これらのAssetの草や岩で使用出来そうなのを調査します。

先週、夜の回線速度が規制されてない時間に全部のAssetをInstallしておいたんですが、間違って別のProjectにInstallしてしまいました。

まあいいです。

このProjectにあるLandscape用のMaterialを使用して以下のLandscapeをテスト用に作成しました。

<Procedural Biomes>

まずBush系のAssetでは以下の物がありました。

静止画ではよく分からないですが質はあまり良くないです。

後白過ぎます。これが直せるのかどうか不明です。

落ち葉系のAssetです。

そのままでは使用出来ないと思いました。質が悪すぎです。

木の根っこです。

このAssetの質はともかくとして木の根っこはPhoto-RealisticなLandscapeを作成するには必須のAssetと思いました。

草のAssetです。

使えそうなのだけ配置しました。

ほとんどの草は日本では見た事ない草です。

これをそのまま使用できるのかとなるうーんとなってしまいます。

更に全部色が白過ぎます。

<Procedural Nature Pack Vol.1>

こんなのしかなかったです。

ここにある草は日本では全く見ない草ですね。

<Realistic Forest Pack>

これはInstallするのを忘れていました。

<Nature Package>

以下のGrassがありました。

まずこれです。

これドっから見てもタンポポですよね。

これは使えます。

隣の花も道端によく咲いている花です。

後以下の草はススキの代わりに使用出来そうです。

<Scanned Poplar and Aspen Forest>

以下の草がありました。

チューリップとか野生で咲いてる訳ないです。

<Spring Landscape>

これは草のMeshとかは無かったです。

以下のようなLandscapeが形成されていました。

うーん。

凄い。

Landscapeに使用されているMaterialの実装を見てみます。

Layerは12個ありました。

最初のLayerを見てみます。

色々なMaterialを混ぜてLayerを構成していてどれが最初のLayerなのかははっきりとは言えない構成になっていました。

以下にその要素の一つを示します。

あれ、このF_Grass_01ってどんなNodeなんでしょう。

Material Function Callって書いてありました。Material Functionを呼び出しているみたいです。

以下のMaterial FunctionがSetされていました。

中身をみます。

これはMaterialをそのままMaterial Function化していますね。

うーん。

これはこれで勉強になりそうです。

後でじっくり見る事にします。

<Stone Pine Forest>

以下の草がありました。

結構、日本の草に似た形状の草がありました。

以下に個別に示します。

名前は分かりませんがこんな感じの草生えてた気がします。

ヨモギに似ています。

こんな感じの雑草もありますね。

ドクダミじゃないですが似た葉っぱの形状のやつです。

これもありますね。

長い草のやつです。

<Tropical Jungle Pack>

以下の草がありました。

うーん。

笹はここにもないのか。

でもそこそこ使用出来そうな草がありました。

これ里芋の葉っぱにそっくりです。

次がこれです。

こんな草もそこら中に生えてそうです。

2.3 日本の草を調べる

よく考えたら日本にどんな草が生えているのかよく知らなかったです。

調べる事にします。

色んなSiteを見てこの雑草は見覚えあるというのをここにPickupしました。

後、私の近所だと野生化したアブラナがそこら中に生えてたりします。

後、ススキがないですね。

何でススキは雑草じゃないんでしょうか?

それぞれのImageも調べておきます。

ススキです。

春のススキって以下のような形状だそうです。

タンポポ

この雑草を知らない人はいないでしょう。

一応、Google検索の結果を以下に示しておきます。

ドクダミ

ドクダミって日陰に生えてる気がします。

ヒメジョオン

ハルシオンって名前だと思っていました。

エノコログサ

猫じゃらしの事ですね。

ヨモギ

ヨモギです。

<スギナ>

スギナです。

<ヤブカラシ>

これも良く見る雑草です。

2.4 似た草のAssetを選択しています

タンポポです。

ヒメジョオンの代わりです。

ヨモギの代わりです。

ヤブガラシドクダミの代わりになりそうです。

ヤブガラシは蔓ですが、そんな事まできにしないでしょう。

春のススキです。

秋のススキの代わりです。

この辺で試してみます。

ただし実際に試すのは来週にします。

2.5 もう一個Cameraを室内に配置します

Cameraの配置の方をやる事にします。

寝室にセットしました。

以下の設定の調整をします。

<画面が狭かったらCurrent Focal Lengthの値を下げる>

これはこのままでいい気がしますが一応値を変更して確認します。

Current Focal Lengthの値を20に変更しました。

ベッドに人が寝そべっている場合はこの位の画面が丁度いいかもしれませんが、部屋全体を表す時は元の画面の方が情報量が多くて良い気がします。

今度は逆に

Current Focal Lengthの値を10に変更しました。

今度はベッドの両端に情報の無い空間が発生してしまいました。

やっぱり最初の状態が一番いいですね。

<画面が暗かったらExposure Compensationの値を上げる>

これは先週が試していませんね。

以下のParameterです。

試しにExposure Compensationの値を5にしてみます。

おお、真っ暗です。

今度はExposure Compensationの値を15にしてみます。

これはまぶしすぎます。

最初の値に戻します。

この機能はUE内ではなくて現実の空間で撮影する時に重要なParameterと言えそうです。

Lightを自由に配置出来るUEでは、この機能に頼らなくても適切な明るさで撮影出来るからです。

Spheresを画面内に配置して画面の暗さなどを確認>

以下のようにSphereを配置しました。

何故か、この場所にセットしたCameraが別な場所に移動してしまいました。

Cameraの位置を元に戻します。

うーん。

完全に同じにはなりませんね。

これぐらいで我慢します。

<もう一回、Current Focal Lengthの値を調整>

Current Focal LengthはSphereを配置したからと言って変更する要素は特にないですね。

<もう一回、Exposure Compensationの値を上げる>

こっちは変更したらよくなる可能性があります。

黒のSphereの色がかなり明るい気がします。

Exposure Compensationの値を10から8.75に下げてみました。

うーん。

どっちも良い感じです。

ある条件だとどっちかが良いとかあるのかもしれません。

<Focus Distanceを調整>

これは忘れていました。

こんな感じで指定してみました。

結果です。

良くなっているのか不明です。

そもそも室内ではFocus Distanceの後ろの被写体もそんなに後ろに位置している訳ではありません。

それこそ誤差の範囲でしょう。

室内の撮影ではこの調整で見た目が変わるのか不明です。

2.6 現実の映像とUEを組み合わせる方法を勉強する

先程のBedに寝ている人でもCGで追加してみたいです。

その方法について調べてみます。

"Unreal Engine: Step-by-Step Green Screen Import Guide!" [3]でGreen ScreenをUE5で使用する方法が解説されていました。

この辺から勉強してみます。

最初の3分位は以下のMapの説明だけでした。

必要ないのでその部分はSkipします。

MediaからImage Media Sourceを作成します。

Test1と名付けました。

このFileを開いてSequence Pathに以下のImagesの最初のImageを指定します。

あれ?

こんなImagesの説明、いつしたんでしょうか?

そしてFrame Rate Overrideに

このImagesのFrame Rateをセットします。

Tutorialでは60 FPSをセットしていました。

今度はMedia Playerを作成します。

うーん。

画面が小さい。

ここで画面がZoom inしてくれました。

やっとBox内の文字がしっかり見えるようになりました。

Video output MediaTexture AssetをEnableします。

今度はTest1bと名付けていました。

これの名前を変更した瞬間に

Test1b_Videoが作成されています。

これって自動で作成されるものなんでしょうか?

何か編集で途中を間違って消してしまった感じにも見えます。

次にPlaneを配置しました。

ここにGreen Screenの映像を投影するんでしょうか?

先程、突然生成されたText1b_VideoをここにDragしました。

した瞬間に

以下のMaterial?が生成されました。

これ説明してほしいです。

そして以下の場所からLevel Sequenceを追加します。

以下に示したお馴染みの画面が表示されます。

まずFrame Rateを60 fpsに変更します。

+Trackを押してMedia Trackを追加します。

するとMediaが以下の場所に追加されます。

+Mediaを押してMedia Sourceを選択、そしてtest1を選択します。

以下のようになります。

Test1の辺りを右Clickして以下のBoxを表示させます。

Propertiesを選択してMedia Textureを選択し

Test1b_Videoを選択します。

すると以下のようなImageが表示されました。

これで完成だそうです。

この後はCameraをLevel Sequenceに追加する方法とか説明していました。

この先は別にまとめる必要ないかなと思っていたらCameraが動かないようにPinで止める方法を説明していました。

Cameraの画像が表示されている所の左下にPinがあるのでそれをClickするだけだそうです。

知らんかった。

試してみます。

Pin止めした後にPilot Actor ModeになってCameraを動かしてみました。

普通に動いています。

はい。

Pinが外れていました。

あ、分かりました。

このPinをしておくと

Cameraの選択を止めてもPreview画面がずっと表示されるようになります。

こんな感じです。

Tutorialを見直したら、このPreview画面をずっと表示したかったらPinで止めておけ。という意味で言ってるみたいです。

うーん。勘違いした。

Cameraの設定も色々弄っていました。

これも記録する必要ないかなと思ったら

Focus MethodでTrackingにセットしたりしていました。

後は特に記録しないといけない情報は無かったです。

うーん。

こんだけか。

まあUEにおけるGreen Screenの使用方法が分ったので良しとしましょう。

<追記>

How to 3D Gaussian splat from Aerials to Unreal 5 (Free plugin) [4]に無料で3D Gaussian Splattingをやる方法が載っているみたいです。

これも来週試してみます。

3. Niagara の勉強

3.1 先週の復習

先週、何を勉強したのかまったく覚えていません。先週のBlogを読み直して復習します。

「木の生成Simulations」の実装をやっていました。

思い出しました。

Custom HLSLノードの実装の手前までやったんです。

今週はCustom HLSLノードの実装をやります。

その前に木の生成のAlgorithmの復習をします。

これを実際に実装するため枝(幹)の始点と終点を管理してその間に線を引きます。

点は以下のようにそれぞれのIDが割り当てられています。

このIDはFloor((ID-1)/2)の計算でそれぞれの親のIDを求める事が出来ます。

つまりIDからそのPointからどのPointに線を引けば良いのかが判明します。

後は次の点の位置の決定方法です。

  • 親の進行方向のVectorを取得します。
  • その方向に前進します。
  • ある程度前進したらランダムな方向に移動します。

後、教科書ではこの点の始点についての解説は無かったですが、当然親の点の位置から開始しているはずです。と言う事は親の点の位置も取得しているはずです。これは実装する時に確認すると書いていました。

更に教科書には移動した後の位置を記録する話が書いてないです。これは絶対記録しているはずです。とも書いていました。

はい。

大体こんな感じでした。

うーん。まだ全体像がはっきりしてない部分がありますね。

まあ、最初なんでこれぐらいで簡単に済ませる事にします。

3.2 「14.3.5 HLSL Codeを追加する」を実装する

必要な変数を初期化します。

Boolean型の変数 _Validは初期値が無いですね。

教科書の説明によるとこの変数はAttribute Reader内でAttributeの取得に成功したかどうかを示すためのものだそうです。

次にRandom Numberを生成するための関数を実装しました。

これはSample CodeからそのままCopyしました。

教科書によるとこの関数の実装は4章で勉強したそうです。

4章は勉強してないので後で見る事にします。

次に自身のIndexとその親のIndexを取得します。

む、Indexなんて変数あったかな?

無いです。

実装を見ると

ResultがIndexの値を保持しているはずです。

Sample Codeで確認したら

ResultじゃなくてIndexが正しい変数名でした。

直します。

何故かこの変数だけ最初の文字がLower caseになっています。

次に親Pointの位置、親Pointの進んだ方向、そして親Pointが幹から枝分かれして何番目かを示す数を取得するための実装をします。

やっぱり親Pointの位置を取得していました。

次に枝の長さをDepthから計算するそうです。

これは初めて知りました。

たしかに深くなればなるほど枝の長さが短くなるのは当然です。

LengthFactorの値はMaxDepthからOutDepthを引いて決定しています。

これだと枝の先に行くほど数字が小さくなります。

簡単なTrickですが有効な方法です。

この実装で使用されている変数は全部確認しました。InputかOutputのどれかに該当しました。

そして終点の位置を計算します。

まずRandomな方向を計算します。

細かい計算については2度目の勉強で検討する事にします。

次にここで計算された値を使用してPositionを計算します。

OutForwardの計算を自身のPositionから親のPositionを引いて求めています。

これ何となくは理解出来るんですが厳密に正しいのかどうか検証しないと分からないです。

しかしそれは今はやりたくないのです。

合ってると仮定して先に進みます。

最後にIDが0の場合の計算を実装します。

うーん。

細かい計算や理論はともかくとして全体の流れは大体理解しました。

最初の勉強なのでこんなもんで良いでしょう。

Applyを押したらErrorになりました。

どうもDirectionMultiplyのSpellが間違っていたみたいです。

Lが抜けていました。

直したらErrorが消えました。

Niagara Systemに戻ってSolve Moduleの全てのParameterの値を代入しました。

Tutorialだと以下のようなPointがバラバラになったPreviewが表示されていますが、

私の結果は以下のようにPointが一個しか表示されていません。

うーん。

これはどっか間違えているみたいです。

Attribute Readerがないです。って言っていました。

Sample Codeを見ると以下のようにEmitter Spawn Sectionにある[EMITTER] Attribute Readerが無いです。

教科書を見直したら普通にAttribute Readerをこの位置にSetしていました。

先週のBlogを見直したらこの部分の作業を完全に抜かしていました。

Attribute ReaderをEmitter Spawn Sectionに追加します。

更に設定でEmitterの名前も追加しました。

これでCompileし直します。

またErrorになりました。

うーん。

理由が分かりませんね。

分かりました。

CustomHLSLノードのInputとOutputのTypeが何故か全部Niagara IDに代わっていました。

全部直しました。

結果です。

綺麗に出ました。

次に枝を作成します。

最初は枝を作るためのMaterialを作成します。

そしてRender SectionのSprite Renderer Moduleの

Materialにセットします。

更にAlignmentの値をCustom Alignmentに変更します。

教科書ではいつの間にかSprite Based Line ModuleがSolve Sectionに追加されていました。

追加します。

また教科書の図が間違っていました。

Sprite Based Line Moduleと書いていますが

これはRender SectionにあるSprite Renderer Moduleの設定のはずです。

確認のためにSample Codeを見たら

やっぱりそうでした。

以下のように変更しました。

結果です。

おお、凄い。

凄いけど色が一寸違いますね。

値を変更して以下の色にしました。

これなら一応木に見えます。

葉を追加します。

まず葉のためのMaterialを作成します。

Sample Codeで確認するとM_Lineと全く同じ実装でした。

葉の色を指定するためのParameterを作成しました。

User Parametersで作成しています。

ここで作成するとLevel上に配置した時にDetailで設定出来るようにようになるんでしたっけ。

葉のためのSprite Render Moduleを追加しました。

今はこんな感じです。

Color Bindingに先程作成したParameterであるLeafColorをセットしました。

結果です。

何故か葉が光っています。

でも綺麗ではあります。

Sample Codeの値を代入しました。

それでもでも光っていますね。

今度は葉を形成する位置を正しくします。

Depthの値が一定以下のPointには葉が形成されないようにします。

まずVector2D型の変数、LeafScaleを作成します。

うーん。

これでどうやってDepthの値を判別するんでしょうか?

まずこの変数をSolve Sectionに追加しました。

現状のParameterは以下のようになっています。

これを以下のように変更しました。

ここまで複雑だとProgrammingしているのと変わらないです。

Scratch Pad ModuleでCode書いた方が良い気もします。

どのくらいの複雑さまで許容すべきなんでしょうか?

最後に

Render Sectionの葉を形成する方のSprite Renderer Moduleの

Sprite Size Bindingに[PARTICLE] LeafScaleをセットします。

結果です。

綺麗に葉が生成されています。

枝の最後の部分だけ葉が形成されています。

はい出来ました。

今週はここまでにして、来週「木の生成Simulation」の総括をします。

もう少し理論的にもProgramming的にも深く理解したいので、もう一寸だけ勉強します。

4. Materialの勉強

4.1 Worn-Out LCD Screen Shader - Advanced Materials - Episode 25 [5]を勉強します

以下のような見た目のMaterialを作成するみたいです。

今回はUnity回みたいです。

Unrealでの実装は後の方にありました。

このAnimationを作成するために以下のTextureを作成していました。

これは結構大変です。

FlipBookノードを使用してこれらのTextureをAnimation化していました。

これはMaterialの設定を変えたらそのまま使用出来るはずですが、それを敢えてしないでこの方法で実装しているのか、それともBen Cloward先生がその設定方法を知らないのかは不明です。

Animation Phaseの実装は以下のようになっていました。

Animation Phaseは何を指定しているんでしょうか?

これは実装する時に確認します。

Dot Gridの実装です。

これ途中でLengthノードがあるのでその時点でVector2からFloatになっていると思うんですが、それがDot Gridの値なんでしょうか?

解説を聞くとやはり最初のNodeであるMultiplyノードのAの値はTexCoord[0]でした。

のでこの時点ではVector2です。

AddのBはSizzle Lineの実装結果をPassしているそうです。

これは後で説明するので今はSkipするそうです。

Flipbookノードの結果をLerpノードのAlphaに繋げます。

InvLerpノードのValueにDot Gridの実装を繋げます。

その結果を以下のLerpノードのAlphaに繋げます。

Dotの色を指定していると思われます。

最初のLerpノードのAlphaはどこで計算しているんでしょうか?

これはTutorialで直ぐに説明してくれました。

TexCoord[0]ノードの値に以下のMaskノードを追加して

Gの値を取り出したものだそうです。

ふーん。

だから横線がはっきりしているのか。

納得です。

次はVignetteの実装です。

Inputは全部、TexCoord[0]でした。

Vignetteって外枠がぼやっと黒くなるやつの事だったはずです。

Cameraの設定で何回も使用しています。

要はTexCoord[0]の値で0か1に近い所が黒く、つまり0に近い値になれば良い訳です。

そういう計算を実装している訳です。ここでは。

こんな結果になっていました。

その結果をMultiplyノードのAにつなげて更にBase Colorに繋げてました。

Brightness Flickerを実装してました。

これは画面の中央が白く光っているのを再現していると思われます。

ここのSineノードのPeriodの値は6.2に変更されていました。

結果はここに追加していました。

Sizzle Linesの実装です。

これは点滅するDotに僅かなばらつきを追加するための実装だそうです。

MaskノードはTexCoord[0]の値をInputしています。

当然、計算結果は最初に勉強したDot GridのAddノードのBに繋がっています。

ここで使用されているNoiseノードの設定です。

最後にScreen Onの実装です。

最初のMultiplyノードのAの値は以下の実装から持ってきていました。

Maskノードの方は予想どおりTexCoord[0]ノードの結果をPassしていました。

Screen Onの結果は以下のMultiplyノードのBに繋がっていました。

以上でした。

結構Volumeがありました。

来週実装しますが、どのくらい深堀するか、簡単にやって全部終わらせるか、それぞれの機能をしっかり勉強するかは来週実装する時に決めます。

5. Gaeaの勉強

今週は病院に行く予定が出来たのでPowerPointの作成だけやりました。

5.1 Tutorialの作成

先週で3つの工程の最初の工程である「地形(Terrain)の作成」が終わりました。

ので今週は今までのTutorialの総括編を作成します。

<3つの工程の復習>

Gaeaにおける地形の作成は以下の3つの工程によって構成されています。

  • 地形(Terrain)を作成
  • 色を付ける
  • Buildをする

前回までのTutorialで第一の段階である「地形(Terrain)を作成」が終了しました。

今回の総括編ではこの「地形(Terrain)を作成」の内容についてまとめました。

「地形(Terrain)を作成」は以下の3つで構成されています。

  • 粗削りな地形を作成
  • 表面に細部を追加
  • 時間経過(風や水による地形の変化)

<粗削りな地形を作成>

まずここでGaeaでは最初に配置出来るNodeはPrimitiveかGeo-Primitiveに属するNodeだけだという事を教えます。

その後で、全く訳が分からない初心者でもGeo-Primitive Groupに属するMountainノードを使用するとそれなりの地形が作成出来る事も教えます。

となるとまずMountainノードの使用方法を覚えるのが大切になる訳です。

そこでMountainノードのPropertiesの意味について解説します。

そのついでにProperty一般の操作方法についても解説しました。

<表面に細部を追加>

次に作成された地形に細部を追加します。

これはLook Dev Groupに属しているNodeが担当します。

ここでは地学的に重要な4つのNodeについて勉強します。

  • Fold,
  • Shear,
  • Stack,
  • Shatter

更にこれらと非常に関連の深い以下の2つのNodeについても勉強します。

  • Fault
  • Terrace

Gaeaには沢山のNodeがあり最初から全部のNodeの機能を覚えようとすると必ず失敗します。その結果一個もNodeを覚えられない結果になります。

のでこのようにGeologyの観点から重要な用語のNodeから使用方法を覚えると良いです。

更にこれらのNodeの使い方が分からない初心者に対してSurfaceノードの使用方法も解説しています。

<時間経過(風や水による地形の変化)>

最後に時間経過を地形に追加します。

これはErosion Groupのノードが担当しています。

ここはまず、Erosion Groupのノードの代表としてErosionノードについて勉強しています。

特に以下のPropertyについて勉強しました。

  • Apply Changes
  • Rock Softness
  • Strength
  • Downcutting
  • Inhibition

更にErosion GroupにあるGeologyに関連の深い用語を使用している以下の4つのNodeについても勉強しました。

  • Deposit
  • Sediment
  • Alluvium
  • Stratify

もう少し整理したかったんですが、ここまでしか出来なかったです。

残りは後でやります。

PowerPointのAnimationを直す>

直しました。

<まとめを作成する>

出来ました。

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

6. Houdiniの勉強

6.1 Houdini - Wall Tool 05 [6]を実装する

<Intro>

特にやる事は無しです。

<Meta Import>

Meta Import ノードを使用します。

ForEach_Begin1ノードを選択します。

ForEach_Begin1ノードのParameter Paneです。

ここにあるCreate Meta Import Nodeを押します。

以下のようにforeach_begin1_metadata1ノードが生成されました。

<Create Meta Import Node>

foreach_begin1_metadata1ノードのPropertyには以下に示した様に

Detail AttributesにIteration、numiterations、value、そしてivalueが表示されています。

Attribwrangleノードを追加します。

更にforeach_begin1ノードの結果を第一Pinに

foreach_begin1_metadata1ノードの結果を第二Pinに繋げます。

結果です。

それぞれのPointのNormal Vectorを表示しました。

ここからUp方向のVectorとCross Productsして内向きのVectorを作成します。

<Construct an Up Vector

Attribwrangle2ノード内のVEXpressionに以下の実装を追加しました。

ここでUp方向のVectorは{0,1,0}と表示します。

これはHoudiniにおいてY軸が上を向いているからです。

今度はこのv@sideを可視化します。

以下のIconを右Clickします。

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

Sceneの+を押して以下のBoxを表示させます。

そしてMarkerを選択します。

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

Lebelの値をsideに変更しました。

更にAttributeの値もsideに変更します。

Styleの値をVector Trailとしました。

Length Scaleの値を以下のように下げました。

結果です。

あれ?

何も表示されません。

Tutorialの結果は

となっています。

以下のIconがOffになっていました。

Enableすると

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

今度はRandom Valueを作成します。

“multi”を生成するために

を押します。

Multiが生成されました。

この生成されたRandom Valueに基づいてPointの位置を移動します。

AttribwrAngleノードの名前をAttribwrangle_BrickJitterに変更します。

最後にAttribwrangle_BrickJitterのNodeの色を黄色に変更しました。

これはAttribwrangle_BrickJitterノードが壁の形状を決定するためのParameterを持っているからです。

Attribwrangle_BrickJitterノードの結果をCopytoPoints2ノードのInput2に繋げます。

何故かDotで繋がっています。

Tutorialでは実線で繋がっています。

Foreach_end1ノードを選択し可視化します。

結果です。

Attribwrangle_brickJitterノードに戻り、Multiの値を変更します。

結果です。

おお。

Brickの位置がバラバラになりました。

今度はBrick同士の間に少しだけGapを追加します。

<Carve Node>

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

Attribwranble_brickJitterノードの結果をCarveノードのInputに繋ぎました。

Carveノードの可視化をします。

CarveノードのFirstUの値を変化させると

線の長さが変化しました。

Relative Channel Referenceを選択します。

ここでTutorialでは

となっていますがこのDrop Actionが表示されません。

Tutorialを見直したらFirstUの値をSecondUにDragしていました。

ここでSecondUの値を以下のようにしました。

ここで問題発生です。

Barが無くなって値を入れるBoxだけが表示されています。

分かりました。

FirstUをClickするとFirstUを囲んでいたBoxが消えます。

するとBarが表示されました。

これが原因でした。

結果です。

FirstUの値を変化させます。

線が伸びたり縮んだりしました。

0~0.5の間では線が縮みます。

0.5~1の間になるとPointの位置が逆になって線が伸びていきます。

Carveノードの名前をCarve_TweakBrickWidthノードと名前を変更しました。

更に壁の形状を指定するParameterがあるNodeなので色を黄色に変更しました。

Carve_TweakBrickWidthノードの結果をCopytopoint2ノードの2番目のInput Pinに接続しました。

Foreach_end1を選択して可視化します。

結果です。

おおBrick同士の隙間の生成されるようになりました。

前後左右の隙間が生成されたので

最後に上下の隙間を追加します。

Poly Extrude 1ノードの設定を少しだけ変更します。

最後に0.96を掛けました。

Foreach_end1を選択して可視化した結果です。

Brickの上下にも隙間が生成されました。

以上でした。

7. UEFNの勉強

7.1 How To Tell Who Damages You In Fortnite - UEFN / Creative 2.0 [7]を勉強する

今週はこれを勉強します。

<Intro>

以下のUIの表示方法を勉強するそうです。

<Initialize Modules and Player List>

突然以下の画面から始まっています。

Fortnite.com/GameとFortnite.com/Characters moduleをIncludeしました。

このVerseの名前はhit_detect_device.verseと言うみたいですね。

それだけ分かればこの画面まで行くのは簡単です。

次にPlayer型の変数を初期化しました。名前はPlayersです。

<Create and Subscribing HandlePlayerHit Function>

次にPlayerに値をセットします。

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

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

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

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

<Testing out Function>

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

呼ばれていました。

<Using damage_result struct>

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

TutorialによるとそれにはDamgaeResultを使用すると良いそうです。

その実装方法をここで勉強します。

以下の方法でDamageを与えた人が誰なのかを得る事が出来るそうです。

しかしTargetはCharacterではありません。

誰かを示している訳ではないです。

<Getting Target who was Damaged>

ここから以下の実装を追加します。

これで誰がDamageを与えたのかが分かります。

<Getting Damage Amount>

次のDamageの量を取得します。

これは以下のようにします。

そして以下の文をPrintする事でDamage量をUIに表示します。

<Getting Instigator / Player who Caused Damage>

今度は誰がDamageを負ったのかを示す実装をします。

ここではInstigatorに何で?をつけないといけないのかについて解説しています。

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

以下の方法でそのPlayerにDamageを追加しています。

更に以下の方法でPlayerにDamageが有った時に文をPrintoutするようにしました。

<Second Result>

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

高所から落ちてDamageを受けたら、以下の文が表示されました。

別なPlayerからDamageを受けた場合です。

2倍のDamageを受けていますね。

<Fixing Infinite Damage Bug / Boss Mechanic>

以下の実装が呼ばれるたびに

Damageが追加されます。

そしてこの関数はここですべてのPlayerに呼ばれます。

つまり全てのPlayerのInstigatorにあるCharacterがDamageを受ける事になるそうです。

うーん。

これ、Tutorialを見ただけではこのような結果になっているのかどうかよく分かりません。

この辺、実装した後のPrintoutの結果を見ないとTutorialの言っている事が正しいのかどうか分かりません。

これは来週、実装する時に確認します。

Tutorialでは以下のように実装を変更する事でこの問題を回避していました。

これだとPlayerがDamageを受けた時だけHandlePlayerHit()関数が呼ばれるようになりますね。

<Final Result>

テストしています。

結果です。

うーん。

これで正しいのか?

この後、PlayerがOpponentを銃で撃っていました。

その時は何も表示されませんでした。

うーん。

これで完成のようです。

実装は来週やります。

一寸理解してない部分があるのでそのあたりは来週までに勉強しておきます。

8. DirectX12の勉強

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

8.1.1 先週の復習

先週から全部やり直す事にしたんです。

それで全部終わらせようとして結局無理で2023-11-12のBlogあたりまで終わらせた位で時間切れになってしまいました。

そうだ今週。PCのOSをWindows11に変更しました。

その影響があるかもしれません。

一応、Sample Codeと自分のProjectを実行してErrorにならないか確認します。

まず自分のProjectです。

普通に動いています。

Sample Codeです。

なんだこれ!

三角がグルグル回っているAnimationが始まりました。

ふーん。

Windows10だとこのSample Codeは完全には動いてなかったみたいですね。

8.1.2 2023-11-19のBlogあたりの実装を行う

DirectX 12が使用出来るのか以下の実装を追加して確認しています。

結果です。

Cursorの位置が取得出来ています。

DirectX12は機能しています。

今度はLötwig Fusel氏が作成したCom Pointer用のClassを追加します。

まずFileを作成します。

今度こそ間違いないでやります。

まずShow All Files Iconが選択されている事を確認して

Support Folderに新しいH Fileを作成します。

名前はComPointer.hとします。

そしてLötwig Fusel氏が作成したCom Pointer用のClassがGitHubにあるのでその実装部分をCopy & Pasteします。

前にやった時と同じようにIUnknownの場所にErrorが表示されています。

ここは無視してMain.cppに戻ります。

そこでComPointer.hを追加します。

ここでComPointer.hがMain.cppから使用出来るか確認します。

はい。

普通に呼び出す事が出来ました。

8.1.3 Debug Layerの実装

今度は2023-12-10のBlogの内容をやります。

まずDebugと言う名前のFolderを追加します。

その中にDebugLayer.hとDebugLayer.cpp fileを作成します。

DebugLayer.hの実装をします。

まず以下に示したSingletonの実装をしました。

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

ここでもDirectX関連のLibraryやComPointerは使用するからです。

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

これでHeader Fileの実装は出来ました。

次にCpp Fileの実装をします。

Init()関数の実装です。

Shutdown()関数の実装です。

うーん。

この辺は何をしているのか理解していませんね。

2023-12-10のBlogを読んだらこの辺はまだ勉強しただけで実装はしていませんでした。

のでこのDebug Layerの実装からしっかり勉強する事にします。

ただ、今から一寸買い物に行かなければならなくなったので、この部分は来週やる事にします。

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

8.2.1 先週の復習

Vertex ShaderとPixel Shaderを追加していました。

Shaderを使用するにはVisual Studioの設定を変更する必要がありました。

これってOpenGLを勉強した時もこうしたのか覚えていません。

なんせOpenGLを勉強したのは10年以上前です。憶えていなくてもしょうがないです。

その後で「4.6 Shaderの読み込みと生成」を勉強していました。

8.2.2 「4.6 Shaderの読み込みと生成」を実装する

<「4.6.1 ID3DBlob型」を実装する>

これ先週はID3DBlobについて調査しなかったのでその調査をやります。

公式のID3D10Blob interface (d3dcommon.h)[8]です。

と書かれていました。

Remarkには以下の説明がされていました。

これ読むとVertex ShaderやPixel Shaderが正しくCompileされたかどうかを示すMessageを返すのにも使用されると書かれていますね。

この説明読むと、そんだけ理解出来たら十分みたいですね。

実装します。

どこで実装すべきなのかが不明だったのでSample Codeと同じ箇所に実装しました。

<「4.6.2 必要なIncludeとLink指定」を実装する>

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

これは特に調べる事も無いので次に行きます。

<「4.6.3 D3DCompileFromFile()関数」を実装する>

まず、先週勉強しなかったD3DCompileFromFile()関数について勉強します。

公式のD3DCompileFromFile function (d3dcompiler.h)[9]です。

もう当たり前すぎて逆に納得ですね。

Parameterです。

ではそれぞれのParameterを見てみましょう。

最初のpFileNameはFileの名前の事でしょう。

次のpDefineは何の事でしょう?

Optionとかかれているのでとりあえず無視します。

次のParameterはpIncludeです。

これも何の事か全く想像出来ないです。

説明見たらこれもOptionalと書かれていました。

ので無視して次に行きます。

pEntrypointです。

Shaderの開始するAddressを示すPointerのようです。

どのようにそのAddressを取得するのかは不明です。

pTargetです。

これも先程のpEntrypointとほとんど同じ説明ですね。

違いはこっちがTargetを指している事です。

TargetとEntryPointの違いが分かりません。

Flags1とFlags2です。

この2つのParameterはShaderのCompileの方法について指定しているようです。

ppCodeです。

これは説明のままですね。

ppErrorMsgsです。

こっちはCompileが失敗した時のError Messageを見るための変数をPassするためのParameterですね。

大体理解しました。

もう一回、教科書のこの部分を読んでみます。

全然違っていました。

もう一回教科書の内容を参考にしてまとめ直します。

pFileNameです。

これはFile名をInputします。

このParameterの解釈だけは合っていました。

ただしここではワイド文字列を使用する必要があるそうです。

ワイド文字列ってなんでしたっけ?

調べます。

ワイド文字列の英語名はwide-character-string literalだそうです。

Multibyte and Wide Characters [10]に以下の説明がありました。

この説明を読んで大体こんな感じに理解しました。

文字の表示方法にはmultibyte CharacterとWide Characterがあります。

一つがWide Characterです。これは一つの文字を表すのに必ず2 Byte使用します。

それに対してMultibyte Characterと言う文字を表す方法では1 Byteが基本ですが以上を使用する場合もあります。

このWide Characterを使用した文字列の事をwide-character-string literalと呼びます。

多分、この解釈で合っているでしょう。

wide-character-string literalで書き込むためにはL“○○”と書く必要があるそうです。

はい。

pDefinesです。

これはHLSLにおけるC++でDefineと同じ機能だそうです。

DirectX 12の魔導書」におけるDirectX12のそれぞれの関数の説明は本当に分かり易いです。

ただしこの分かり易さを実感するためには、自分で先に関数を調べてその機能を一人で理解しようとして無理だと実感する体験が必要になります。

これ今、気が付きました。

これからは教科書に出て来た関数は前もって調べてから教科書の説明を読む事にします。

pIncludeです。

これはHLSLにおけるC++でIncludeと同じ機能だそうです。

pEntrypointです。

ここはShader名をパスします。

pTargetです。

これが間違って理解していました。

ここはShaderの種類とそのVersionを指定するところでした。

"vs_5_0"とか"ps_5_0"と指定しています。

Flags1です。

これはShaderのCompileの方法について指定します。

そういう意味では最初の解釈であっていました。

分かってなかったのはD3DCompileFromFile function (d3dcompiler.h)[9]の説明で以下のように

OR Operationを使用すると説明していた部分です。

これは以下のように

2つ以上のCompileの方法について指定する時にOR Operationを使用すると言う意味でした。

Flags2です。

Shader Fileの場合は0を指定するそうです。

ppCodeです。

先程実装して作成した

を使用します。

ppErrorMsgsです。

これはError Messageを受け取るPointerを指定します。このParameterの解釈はあっていました。

ただ、ここにパスするPointerはどんな型になるのかとは分かってないです。

Sample Codeみたら

ID3DBlob型でした。

それでは実装します。

Vertex Shaderからです。

実装内容はSample Codeと同じです。

次にPixel Shaderを実装します。

これも実装内容はSample Codeと同じです。

具体的にそれぞれのArgumentについて簡単に解説したいんですが時間が無くなってしまいました。

それは来週やる事にします。

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

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] WeShootFilms. (2023, September 10). “Unreal Engine: Step-by-Step Green Screen import guide!” [Video]. YouTube. https://www.youtube.com/watch?v=OIaEAAs2Tiw

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

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

[7] Pi Equals Three. (2023, April 23). How to tell who damages you in Fortnite - UEFN / Creative 2.0 [Video]. YouTube. https://www.youtube.com/watch?v=Q73cYtoecfU

[8] Stevewhims. (2021, July 22). ID3D10Blob (d3dcommon.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/d3dcommon/nn-d3dcommon-id3d10blob

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

[10] TylerMSFT. (2021, August 3). Multibyte and wide characters. Microsoft Learn. https://learn.microsoft.com/en-us/cpp/c-language/multibyte-and-wide-characters?view=msvc-170