UE4の勉強記録

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

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

1. 今週の予定

1.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の魔導書」と「Direct3D 12 ゲームグラフィック実践ガイド」の勉強をやります。

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

2. Landscapeの作成

2.1 建物の内部を作成する

今週も建物の内部の家具や装飾品などを追加していきます。

何とか今週中には家具や装飾品の配置を終わりにしたいです。

先週の続きの勉強部屋の配置からやって行きます。

以下のAssetが使用されていました。

まずここを作成します。

出来ました。

今度は反対側です。

以下のAssetを使用していました。

はい。これを配置します。

出来ました。

最後、本棚です。

配置されている装飾品です。

一個だけ装飾品が無いですね。

これで配置します。

勉強部屋の家具や装飾品の配置も終わりました。

次の部屋の配置をします。

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

以下のAssetが使用されています。

まずこれを配置します。

以下のAssetが使用されていました。

作成します。

今度は以下の箇所の配置をします。

Demoでは以下のようにかぐや装飾品が配置されています。

以下の装飾品や家具が使用されていました。

机の上のモノもAssetです。

これらを配置します。

今度は棚についてです。

この装飾品の配置は勉強部屋の配置と同じです。

同じような配置をしました。

本棚です。

以下のAssetを使用しています。

これらを配置します。

それぞれの部屋をDoorから覗いてみます。

これで家具と装飾品の配置は終わったはずです。

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

来週はLightや光関連の配置をする事にします。

3.Niagaraの勉強

3.1 CGHOW氏の近況

CGHOW氏がTutorialの公開を止めてしまったらしいという噂を聞きました。

今週はこの確認を最初にします。

822 UE5 VFX Tutorials in 0.71$ IS THIS EXPENSIVE?? [2]に説明がありました。

TutorialはMembership Onlyに移したそうです。そしてMembershipの会員費は月$0.71だそうです。

これは日本円に直すと104.68円ですのでまあほぼ無料と同じ金額です。

CGHOW氏もお金を稼がないと暮らしていけないのでこれは仕方ないですね。

ただ私はもうCGHOW氏のTutorialから学ぶ内容は無いです。

のでまあMembershipになったとしても勉強はしないでしょうね。

3.2 先週の復習

一個忘れていたのですがRender Targetについて書かれていました。

DirectX 12におけるRender Targetの機能を一言で説明出来るように、DirectX12の勉強のところで復習しようと思っていたんですが、それをすっかり忘れちゃっていました。

これは今週やります。

先週は「GridのDataを作成する」を実装していました。

3.3 「13.4.6 GridのDataを作成する」の続きを実装する

まずSample Texture 2Dノードを分割しました。

更にCustom HLSLノードを追加して以下のように実装しました。

成程。

TextureをGrid 2D Collectionで指定した升目で分割してそれぞれのAlpha値からSTATEの値を決定しました。

これは一例と言う訳で別に絶対こうすべきと言う訳では無いですね。

ここで重要なのはこのやり方でNiagaraのTextureの情報をMaterialにPass出来るという事です。

<Main Logicの計算を行う>

Niagaraに戻ってきたら以下の警告が出て来ました。

検索しても全く引っかかりません。

取りあえずはこのままにしておきます。

今度はLogicの計算を行うために新しいGeneric Simulation Stageを追加しました。

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

ここで教科書では

とわざわざ警告をしてくれています。

これ前回の時に行って欲しかった。

Execute Behaviorの設定をNot on Simulation Resetに変更しました。

ここも教科書に大切な説明がありました。

1 Frame目は

ここで計算して2 Frame目から以下に示した

ここで計算をするわけです。

新しいScratch Pad Moduleを追加しました。

Solveと名付けたScratch Pad Moduleを開き

Map Getノードに

[EMITTER] Grid2D Collectionを追加しました。

ここは先程、作成したTextureToGrid2Dの結果を

使用するのかと思ったんですが違うんでしょうか?

教科書の書き込み方から推測しますと

以下に示した様にStack Context Sensitiveには

[STACKCONTEXT] Stateが存在しているはずなんですが、

無いです。

[STACKCONTEXT]のScopeの範囲がよく分からないんです。

以下の解説を読むと

[STACKCONTEXT]のScopeは1 Frameのようです。

となると

これは新しく作ってもおかしくは無いですね。

作ります。

Float型で作成しました。

これをMap Setノードに追加しました。

更にCustom HLSLノードを追加して以下のように繋ぎました。

ここからHLSLで実装します。

教科書の説明によると

以下の実装で対象のStack Contextの値を取得する事が出来るそうです。

GridCollection2D. SampleGridFloatValue <Attribute = name>(float2 uv, float value);

うーん。

Stack Contextの値でこの時点でまだ存在しているの?

ここのModuleが実行されるという事はFrameは2周目に入っている訳ですから、Stack Contextの中身は既に消えてしまっている気がします。

もしそうでないのなら

先程、このSolveを作成した時に

に何も表示されないのは何かを間違っているせいになります。

うーん。

取りあえず全部やってからこの問題については考える事にします。

残りの計算はGame of Lifeの設定をそのまま実装しただけです。

特に疑問な点は無かったです。

実際に一々書くのは面倒なのでSample CodeをそのままCopyしました。

うーん。

これは動かない気がしますね。

まあ、良いです。

兎に角最後までやってしまいます。

<Render Targetに結果を取り込む>

当然、これを行う為の新しいScratch Moduleを作成します。

名前はGrid2D_To_RenderTargetにしました。

中を開きMap Getノードに

[EMITTER] Grid2D Collectionと[EMITTER] Render Targetを追加します。

Set Render Target Valueノードを追加します。

IndexXとIndexYの値をRender TargetのLinear to Indexから獲得します。

Linear to IndexノードのLinearにはExecution Indexを繋ぎます。

ここがよく分かりません。

Execution Indexノードの説明には

以下のように書かれています。

そもそもこのSimulationにはParticleは存在してないのですから、何にも帰ってこない気がします。

それとも今、計算されているGridのIndexが返ってくるんでしょうか?

次にSample Previous Grid Float Valueノードを追加します。

あ、ここでExecution Index to Unitノードを使用していました。

これ前も使用していましたね。

という事は、Particleを使用しない場合もExecution Indexは存在しているという事ですね。

次にStateの値から色を指定します。

これは1なら白、0なら黒なだけです。

これで完成だそうです。

Preview画面を見ましたが何も表示されません。

Level上に配置しましたがここでも何も表示されません。

うーん。

やっぱり何かがオカシイんです。

Bugの問題は来週検討する事にします。

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

4.Materialの勉強

4.1 Retroreflective Road Sign - Advanced Materials - Episode 22 [3]を実装します

先週勉強したRetroreflective Road Sign - Advanced Materials - Episode 22 [3]を実装します。

<Reference Image>

ここは特にやる事は無いのでSkipします。

Photoshop

ここで以下の2つのImageを作成しています。

まじか。

これを最初に作成する必要があるのか。

今週は面倒なのでMediBang Paint Proで作成しました。

Sizeは256x256です。

これをPngのGray Scaleで保存すれば白黒になるはずです。

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

白い部分を透明として指定する必要があるかもしれません。

その辺は臨機応変に対応します。

Diamond Retroreflectiveです。

こっちもGray Scaleで作成しました。

<Shader>

UE5にImportしました。

まずはCautionの方から確認します。

Compression SettingはGrayscaleになってなかったので直しました。

更にsRGBもOffになってなかったのでOffにしました。

Diamond RetroreflectiveのTextureは同じでした。

ここからMaterialの作成に入ります。

InvLerpノードをCautionの文字が薄くなっているのを直すために繋げました。

結果です。

Aも文字が読めなくなっています。

InvLerpノードの値を調整します。

一寸明るすぎますが文字が読めてかつBlurが無いです。

使用した値です。

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

Aは何とか読めますね。

色を追加しました。

StepノードをOpacity Mask接続してRoad Signの端を消します。

結果です。

端の線が汚いですね。

まあ今回はこれは無視して続きをやります。

<Fresnel>

今度はFresnelを追加します。

MultiplyノードのBの値はまだ作成していないので1.0にしておきます。

この時点での結果です。

<Diamond Pattern>

FresnelのMultiplyノードのBの値を計算します。

結果です。

滅茶苦茶良いんじゃないでしょうか!

こっちの実装はこれでOKとします。

5.Gaeaの勉強

5.1 Tutorialの作成

今回はMountainノードの後につなげるNode群について解説します。

前回、以下に示した様にMountainノードを追加する事で山を作成しました。

これだけでもかなりRealですが、実際の地形の表面はもっと複雑です。

日本ではほとんどの山は木が生い茂っているだめ山の表面を見る機会はあまりありません。

ので山の表面がどうなっているのかなんで知りません。

そこで代表的な地形であるFolding、Shear(Fault)、Stack、(Shatter)そしてTerraceをここに紹介します。

Foldingです。

層になった地形がグニャっと曲がっています。

ここでは2023-02-26のBlogでした以下の説明をします。

次はShearです。

Shearは理屈を理解した方が現物を見るより分かり易いです。 

Shear Zones[4] に以下の解説がありました。

これが一番分かり易いです。

地面が引き裂かれるんです。

で真っ二つに引き裂かれた場合はFault、多少繋がっている場合はShearになります。

以下にWikipediaのShear zone[5]の例を示します。

By Mikenorton - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=25156710

でこれを見るとShearじゃなくてFaultじゃね。

と思います。

このFaultとShearの区別は文献によってまちまちでよく分かりません。

因みにWikipediaのFault [6]のPageにあるFaultのImageです。

By NASA Earth Observatory images by Robert Simmon and Jesse Allen, using Landsat data from the USGS Earth Explorer. Caption by Adam Voiland. - Faults in Xinjiang (Nasa Earth Observatory), Public Domain, https://commons.wikimedia.org/w/index.php?curid=30723575

こっちはスパッと切れていますね。

Stackです。

WikipediaのStack (geology)[7]の画像です。

By Jan from Singapore, Singapore - Two moreUploaded by Snowmanradio, CC BY 2.0, https://commons.wikimedia.org/w/index.php?curid=10677360

Computer ScienceのStackと同じじゃないですか。

うーん。

解説を読むと海のそばでしかこの地形は形成されないそうです。

ただGaeaのStackを見ると

凄い綺麗に出ています。

Shatterです。

WikipediaのShatter cone[8]によると

By Zatoichi26 at English Wikipedia, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=31287511

と紹介されています。

がこの地形が現れるのは隕石が落ちた後か核爆発があったかのどちらかだそうです。

Gaeaでは以下のように綺麗な地形を作成しています。

最後はTerraceです。

WikiのRiver terraces (tectonic–climatic interaction)[9]には

By Sushant savla - Own work, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=72683594

がありました。

これはTerraceの地形が分かり易いです。

写真もありました。

By Andreas F. Borchert, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=4568455

木が生えたりErosionが起きるとTerraceはあまりはっきりしませんね。

今度はGaeaの結果を示します。

Foldです。

あんまりFoldしていませんね。

Shearです。

この辺にShearっぽい地形が形成されていますね。

次いでにFaultノードの場合も検証します。

ただしFaultノードはLook Dev Groupに属するNodeでは無いです。

確かにFaultですが、地形が一辺してしまっています。

今回の主旨とは一寸違ってしまっています。

Stackです。

見事にStack状になっています。

Shatterです。

非常に綺麗な表面を作成しますが、Geology的には隕石や核爆発が起きた後しか形成されない地形だそうで、こんな感じで使用するのがありなのか一考が必要なNodeかもしれません。

最後にTerraceです。

このNodeもLook Devには属さないNodeでProfile Groupに属しています。

今回のTutorialで教える内容はこれぐらいが限界ですね。

因みに今回の結果の元になったMountainノードのSeedの値は

です。

5.2 Power Pointのまとめ

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

Mountainノードの次に配置すべきNodeはどのように選ぶべきなのか?

を軸にLookdev GroupのNodeを紹介しています。

今回はGeology的に重要なNodeをPickupして解説する事にしました。

Foldの解説です。

今回はどうしてこのような地形が形成されるのかについての解説は一切省きました。

こんな地表が存在している事を知ってもらうのが最も重要だからです。

Shearに関しては実際の地形を見る前に理論を理解した方が分かり易いと考え、理論から解説しています。

その後で写真も紹介しています。

Faultの例も紹介しています。

Stackはあまり重要な地表ではないですが、

Lookdev GroupにNodeが有る事と、次のTerraceと形状が似ている事からここで紹介する事に決めました。

このTerraceは何故かLookdev Groupに属していません。

最後にShatterです。

これもそんなに重要な地表とは思えませんが、Lookdev GroupにShatterが存在しているのでこれも追加しました。

この後にSurfaceノードも解説しようと思っています。

これらのNodeをいつ使用すれば良いのかがよく分からない場合、Surfaceノードで代用するとそれなりに対応出来ます。

6.Houdiniの勉強

6.1 先週の復習

先週のBlogを読み直すと Houdini 19 - Wall Tool 02 [10]の実装は終わったみたいです。

ただ最後の部分が何をしているのかよく分からないと書かれていました。

これはResample_BrickSpacingノードのLengthの値をこのLengthにPassしているだけです。

つまり0.712です。

これ見ると長さは一定には見えないですね。

うーん。

Rulerがあったら長さを図る事が出来ますね。

調べます。

公式SiteのRuler [11]を見るとSideFX LabsにRulerが有るそうです。

以下のように長さを図っていました。

私のProjectを見たらそもそもSide FX Lab自体が無いです。

うーん。

分らん。

Geometry SpreadsheetにそれぞれのPointの位置やPoint間の距離が表示されていました。

#0から#9のPointです。

SpreadsheetのそれぞれのPointの位置からPoint間の距離を計算しました。

Ptdistの値と比較すると9の値が違いますね。

それ以外は同じ数字になりました。

一つ前のAttributewrangle1の

Pointの並びです。

うん。

Pointが8までしかないですね。

Resampleノードを追加する事でPoint数が一個増えています。

公式サイトのResample geometry node [12]を見ます。

ResampleノードのRemarkの説明で均等な長さに分割するためにResampleします。

と書かれていました。

つまりResampleノードの機能そのものが距離を均等に分割するものだったんです。

そして以下のParameterです。

これについても解説していました。

これ読むとPoint間の距離がここで指定した値以下になるようにする設定です。

つまりResample_BrickSpacingノードのLengthの値である

以下になるように新しくPointを振った訳です。

確かにSpreadsheetを見直すとPtdistの値は全部0.712以下になっています。

うん。

こんだけ理解出来たら今回は十分です。

次に行きます。

6.2 Houdini 19 - Wall Tool 03 [13]を勉強する

以下のPointの位置が間違っているので直すそうです。

Attribwrangleノードを追加します。

名前はAttribwrangle_fixHalfBrickとします。

中の実装です。

とりあえずここまでの実装の説明をします。

位置を移動したいPointは全部@primnumが偶数です。

のでIf節で偶数だけ選別します。

次にIntのArrayを作成します。

関数、Primpoints()を使用しています。

この関数について調べます。

公式Siteのprimpoint VEX function [14]です。

Geometryは自身のGeometryを指すので0になるはずです。

次にPrimnumを指定しています。これが@primnumになるのか。

最後のParameterでprim Number内のVertexの番号を指定します。

今回はArrayなので全てのPointの番号を得るので、このParameterは指定していません。

次の実装です。

Tutorialによると位置を直す必要のあるPointは

以下の赤丸で囲ったPointなので

-2で指定するとこのPointになるそうです。

普通に8を代入した場合はどうなんでしょう?

これは実装する時試します。

次の実装です。

ここで位置を変更するPointの隣のPointを習得します。

Point関数について調べます。

公式Siteのpoint expression function [15]です。

それぞれのParameterについても見てみます。

最初のParameterです。

Surfaceノードだそうです。

今回は自身のノードなので0を指定しています。

次のParameterです。

これがPである訳が無いですので、ここは指定してないんでしょうか?

それとも最初の0がこれを指定しているんでしょうか?

よく分かりません。

次のParameterです。

ここでPを指定していますね。

PはPositionの事だそうです。

次のParameterです。

ここでPointの位置を指定しています。

例も載っていました。

これは納得です。

でもTutorialのPoint()関数の値どうなんでしょうか?

なんか全然合ってない気がします。

Tutorialみたら以下の解説が写っていました。

全然違うじゃん。

最初のParameterはGeometryです。

だから0を指定していたのか。

次のParameterがAttribute_Nameです。

ここはPointの位置を返してほしいのでPになるはずです。

最後のParameterはPoint Numberでした。

以下に示した様にprimPts[-1]で

位置を直したいPointの隣のPointを指定しています。

うーん。

何でPoint()関数のParameterが違っているんでしょうか?

謎です。

次は以下の距離の値を取得します。

以下の実装で取得しました。

これはすぐに意味が分かりました。

二番目のParameterで欲しい値がptdistと指定してます。つまりPoint間の距離を返せと言っています。

三番目のParameterでどのPointかを指定しています。

はい。

今度はこれらの値を使ってPointの位置を直すそうですが、どうやって直すんでしょうか?

次の関数です。

SetPointattrib()関数です。

今度はParameterで躓かないように最初からTutorialで表示されている画面をScreenshotしておきます。

途中で切れてしまっていますが、大体は読めます。

これを確認した上で公式Siteのsetpointattrib VEX function [16]を読みます。

先程のTutorialに表示された解説と同じですね。今度は大丈夫そうです。

先にTutorialがどんなArgumentを使用するか確認します。

Tutorialではこの関数の実装をする時にそれぞれのParameterの意味についても簡単に説明していました。

それを以下にまとめます。

最初のParameterです。

これはInput Indexで0を指定します。と言っていました。

公式Siteのsetpointattrib VEX function [16]のこのParameterの説明は後でまとめて読みます。

次のParameterです。

どんなAttributeの値をSetしたいのかをここで指定するそうです。Pointの位置を直したいので当然Pになります。

次のParameterです。

直したいPointをここで指定します。FixMeをここに指定しました。当然ですね。

次のParameterです。

ここには新しくSetしたい値を指定するそうです。

TutorialではtgtPの位置から@N方向にtgtLenの値を足した値を指定しています。

最後のParameterです。

ここはどんな操作をしたいのかを指定します。

TutorialではSetを指定しています。

ここは値をセットするからでしょうね。

公式Siteのsetpointattrib VEX function [16]の説明も確認します。

最初のParameterです。

うーん。

これは意味が分からん。

いや一応は意味は分かりますが、Tutorialの分かり易い説明を聞いた後だと、この説明を読むのはほとんど無駄に思えます。

最後のParameterのSetの意味だけ確認する事にします。

まさしくSetですね。

関数の上にCursorを合わせた状態でF1を押すと先程の公式SiteのFunctionのPageを開いてくれるそうです。

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

Resample_BrickSpacingノードの

Lengthの値を変更してTestしています。

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

Pointの数は減っていますが、Pointの位置が壁のBrickの位置を示すようになっています。

ここでこのTutorialは終わっていました。

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

6.3 Side FX Labの表示方法

Rulerを使用するためにSide FX Labを表示する必要が有りますがこのやり方が分かりません。

Side FX Labで検索すると

公式SiteのSIDEFX LABS INSTALLATION [17]が出て来ます。

ここにInstall方法を説明しているVideoがあります。

このVideoのやり方に沿ってやってみたところ、

以下のSide FX LabのTool BarとUpdate ToolsetのIconの表示のところまでは出来ました。

ここからUpdate ToolsetをClickすると

Tutorialでは以下のBoxが表示されていますが、

私のはHoudini Launcherが見つかりません。と言うMessageが書かれたBoxが出て来るだけです。

(ここにそのBoxのScreenshotを貼れたらよかったんですが、私の今のHoudiniは既にSide FX LabのInstallが終わってしまっています。のでこんな感じだったと文章で書くしか出来ません。)

そしてそのBoxにLauncherのある場所のPassを指定するとLauncherが開きます。

でその先はどうしていいのか分からないで終わります。

ここでHoudiniの勉強をしている時のSide FX LabのInstallは中止になりました。

次の日になってYouTubeを見てたら、お勧めに以下のVideoが表示されました。

Install Sidefx - Labs Tools - Easy and straight to point video [17]

これを見たら、Houdini LauncherからSide FX LabをInstallする方法が説明されていました。

やり方は超簡単で

Labs/Packagesを選択してInstallをClickします。

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

ここまでは昨日も試したんですが、この動画を見たらこの後が有りました。

この画面で5秒位、待っていると以下のような画面が自動で表示されます。

ぬおお!

これは気が付かなかった。

昨日はこの前の画面が表示された時、右下のInstall Buttonを押したりしても何の変化も起きなかったのでそこで諦めました。

なんとただ待っているのが正しかったとは。

もうここまでくれば後は使用したいVersionを選択するだけです。

この動画では以下のVersionを選択していました。

ここでInstall ButtonをClickします。

すると選択したSide FX LabがInstallされます。

以下に私のHoudiniの開いた画面を示します。

Side FX Labがあります。選択するとUpdate ToolsetだけでなくRulerを含めた色々なIconが表示されています。

7.UEFNの勉強

今週もPi Equals Three氏のTutorialをやっていきます。

7.1 Make Anything Face Your Player! UEFN/Creative 2.0 Verse Tutorial [9]を実装します。

先週勉強したMake Anything Face Your Player! UEFN/Creative 2.0 Verse Tutorial [9]を実装します。

<Intro>

特に何もする必要がないのでSkipします。

<Properly Rotating Your Creative Prop>

以下のPropが見つかりませんね。

名前はPNGとなっています。

無いです。

Fabの方にあるかもしれません。

Fabで探してみます。

無いです。

探しても無いんで、以下の狛犬が常にCameraの方を向くようにセットする事にします。

現在、狛犬は以下に示した様な軸に沿って配置されています。

Tutorialでは軸の向きに揃えてStatic Meshの向きを変更しています。

この向きの変更がよく分からないんです。

どっち向きが正しいんでしょうか?

後、狛犬の説明BoxのところにRead Onlyと書かれています。

向きの変更は出来ない気もしています。

今回は向きは直しません。

このまま使用する事にします。

<Creating Verse Device>

新しいVerseのDeviceを作成します。

PNGという名前のPropは使用していないので名前にPNGが入っているのは変ですが、後からこのVerseを探すときにTutorialと違う名前にすると見つけるのが面倒になる可能性もあるので名前はそのままにしました。

Buttonが増えています。

Createを押します。

Png_face_player_device.verseが追加されました。

<Basic Logic Behind Rotating Our Prop>

ここは実装には関係ないです。

<Getting Reference to Player and Prop>

ここからVerseのProgrammingに入ります。

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

前と比較して得に変化したような感じは無いですね。

Creative_prop型の変数、PNGを作成します。

次に以下の関数を作成しました。

更に以下の変数を作成しました。

Arrayですね。

更に以下の場所でPlayers変数の値をSetしました。

これも何回か使用していますね。

<Creating DoFacePlayer Function>

今度はDoFacePlayer()に以下のCodeを追加します。

勿論、以下のFortnite.com/CharactersはIncludeしています。

<Getting Prop and Player Positions><Getting Prop Forward Vector

Playerの位置を以下の方法で獲得します。

Propの位置も同様の方法で獲得します。

次に以下の実装でPropの向きをPlayer側に移動します。

GetLocalForward()関数の簡単な解説がDefinitionのところにありました。

このPropの正面がどこに向いているのかを取得する関数のようです。

これを見るとPropは元々X方面に正面が向いていると仮定しているようです。

以下のImageを見ると分かりますが

狛犬はX方向を元々向いていません。

このままだと常に左横向きになりそうです。

後、以下に示したUnrealEnigne.com/Temporary/SpatialMathもIncludeしました。

更にPNGFrontにPNGPositionの値を追加します。

これはLocal Positionに変換しているだけだと思います。

先週のBlogでは

と述べていますね。

<Creating Vectors to Delete Z Axis>

Z方向が0のVectorを作成します。

PlayerのZ方向が0の場合です。

PropのZ方向が0の場合です。

PNGFront2DのZ方向が0の場合です。

<Creating Shortest Rotation Between Vectors>

これらの値を使用して回転するのにもっとも短い距離を判定します。

<Rotating Prop>

回転させるために以下の実装を追加しました。

これでVerse側の実装は終わりです。

<Configuring Creative Device>

UEFN側の設定をします。

Buildをします。

Deviceを配置します。

DeviceのParameterにPropをセットします。

狛犬をセットしようとしたら

と表示されてセット出来ません。

あれ?

調べたらPropはBP Classでした。

以下のBPをProp用に作成しました。

Static MeshをComponentsに追加しました。

ついでに狛犬の正面をX方面に揃えました。

このBPの狛犬をLevel上に配置します。

先程のDeviceのPNGにこの狛犬Propをセットします。

今度はしっかりセット出来ました。

<Final Result>

テストします。

あれ?

全く移動しません。

あ、理由が分かりました。

OnBegin()関数内にDoFacePlayer()関数を追加するのを忘れていました。

動く事は動いたんですが

狛犬はずっと横を向いています。

直します。

正面を向くようになりました。

後、以下のPrintを消すのを忘れていました。

左端にHelloが大量に表示されました。

これを消してもう一回テストします。

今度こそ完成しました。

左端にHelloの文字も表示されていません。

8.DirectX12の勉強

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

8.1.1 先週の復習

先週何をやったのか全く覚えていません。先週のBlogを読み直して思い出します。

分かりました。

一応、ProjectのFolderの位置はSample Codeのそれとほぼ同じになりました。

そして最初のTutorialである Project Setup & ComPointer | D3D12 Beginners Tutorial [D3D12Ez] [18]を最後まで勉強しました。

前回勉強した内容はCom Pointerについて何ですが、やっている事はこのTutorialの作者が作成したCom Pointerを使いやすくするためのClassをCopyしてProjectに追加しているだけです。

8.1.2 Project Setup & ComPointer | D3D12 Beginners Tutorial [D3D12Ez] [18]の続きを実装する

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

こんな事もやっていました。

これは試さないといけませんね。

これはSample CodeにCodeが無いので自分で打ち込みました。

テストします。

ぐ。

Errorになってるやん。

まずCursorのSpellが間違っていました。

これを直して、WinInclude.hにあるIncludeしているHeader Fileを全部Main.cppにCopyします。

これで一端テストします。

普通に動いています。

WinInclude.hが読めないのが問題なだけです。

WinInclude.hからHeaderの情報を得る実装に戻してもう一回テストします。

あれ?

出来ています。

一回Rebuildしているので出来てると思います。

今度はCom Pointerの話です。

まずHeaderを作成してそのHeaderを使用出来るかどうかをテストしましょう。

その後でゆっくりとCom Pointerの話を聞く事にします。

Ohjurot/ComPointer.hpp [19]にSource Codeがありました。

これをまるCopyして貼り付けます。

なんかErrorになっています。

Sample Codeの方を見るとIUnknownはStructであると表示されています。

私のProjectだと

IUnknownはUndefinedだと書かれています。

検索したらCudaの実装をしている人達の間で似たような現象が起きている人もいるみたいです。

そこで行われていた解決策はここでは役に立ちそうにありません。

これはTutorialをもう一回勉強しないと解決しなそうです。

一端、ComPointerの実装を全部消してTutorial通りに進める事にします。

8.1.3 Project Setup & ComPointer | D3D12 Beginners Tutorial [D3D12Ez] [18]のComPointerをもう一回勉強する

速攻でIunknownについて説明していました。

ComPointerを使用するためのCom APIの事をIunknownとも呼ぶそうです。

このCom APIの目的は以下の2つだそうです。

  • C++やC#で書いたCodeを色々な言語で書かれたCodeと一緒に使用出来るようにする。
  • 複数の色々なCompilerやVersionの違Complierをまたがって使用出来るようにする。

この後もCom APIについて説明していますが、一寸専門的過ぎるのと、どこまでこのTutorialの説明を鵜呑みにして良いのか疑問な点もあるので、この後の説明はSkipします。

この後、普通にIUnknownを使用しています。

うーん。

試してみます。

あれ、普通に使えそう。

Tutorialではこの後、Release()関数を呼び出しています。

普通に呼び出せました。

うーん。

という事は普通にIUnknownは使用出来るって事?

TutorialではRelease()関数の機能について簡単に説明していました。

大体以下のような説明でした。

Com ObjectはRef CounterというReferenceされている数を記録する箇所があるらしく、ReleaseされるたびにそのCount数が減るそうです。

もしRef Counterの値が0になったらそのCom Objectは破壊されるそうです。

うーん。

単なるSmart Pointerですね。

今度はAddRef()関数について説明しています。

うん?

説明を聞いているとRef Countを増やすみたいに言っている気がします。

一寸これは調べて確認します。

公式SiteのIUnknown::AddRef method (unknwn.h)[20]の説明です。

やっぱりRef Countを増やしていました。

それよりもInterface PointerをCopyする度に自分でこの関数を使用してRef Countを増やす必要があるそうです。

こっちの方が大変です。

今度はQueryInterface()関数について説明しています。

この関数はError表示になっていますがArgumentをPassしていないからです。

この関数の機能はIUnknown Objectを別なObjectにCastする事だそうです。

TutorialではID3D12Device*のObjectであるdeviceを

ArgumentにPassしていました。

うーん。

これってPをID3D12DeviceにCastした訳ではないですよね。

だってID3D12Device*のObjectであるdeviceをPassしている訳ですから。

となるとQueryInterface()関数って単なるCastではないという事になります。

QueryInterface()関数の機能も公式のSiteで確認します。

IUnknown::QueryInterface(REFIID,void**) method (unknwn.h) [21]の説明です。

うーん。

よく分からないけど、Com ObjectにこのInterfaceへのPointerがあるかどうかを質問してるって事でしょうか?

このInterfaceが何を指してるのかよく分からないです。

Com ObjectがIUnknownと同じ意味だと仮定します。

Tutorialの説明だとIUnknownには沢山の子Classがあるそうで、ここで使用されているID3D12Deviceもその一つだそうです。

それらの子Classならぬ子Interfaceみたいなのがあってそれを指しているんでしょうか?

つまりID3D12DeviceはCom Objectの子クラスかどうかを聞いているって事なのかなと思いました。

うーん。

もう少し情報が無いと判断出来ないですね。

でもこの仮説が正しいと次の文章の意味がすっきり理解出来ます。

もしInterfaceがCom Objectから派生していた場合は、そのInterfaceから作成されたObjectのPointerを返します。と解釈できます。

だからこのTutorialの例はDeviceというID3D12Device*のObjectをPassしているとなります。

うーん。

これはそんな簡単に理解出来る内容ではなさそうです。

今週のLötwig Fusel氏のD3D12 Beginners Tutorialの勉強はここまでとし、この問題は来週考える事にします。

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

8.2.1 Render Targetの機能について

これを一言で解答出来るようになっておかないと、一体DirectX12の何を勉強してたのと言われかねません。

DirectX 12の魔導書」でRender Targetの定義を調べたらすぐに見つかりました。

描画先

って書かれていました。

GPU内のResourceだそうです。

はい。

よく考えたら英語もそういっていました。

いやDouble Bufferingで描画先って2つあったはず。

どっちがRender Targetなのかと調べたら「DirectX 12の魔導書」にしっかり両方Render Targetだ。って書かれていました。

教科書のその箇所を読み直したら、前の時より3倍くらい理解しました。

うーん。

成程。

8.2.2 先週の復習

「4.2 VertexのInformationの作成」の「4.2.1 Coordination Information」を読んでまとめています。

まとめると言っても別に実装する内容は無いので適当に内容をまとめただけです。

一個だけ疑問があるんですが、教科書に書かれているXMFLOAT3で指定されたVerticesの値は実装する必要があるんでしょうか?

これだけ確認します。

Sample Codeを開いて確認したらChapter 4で使用されているXMFLOAT3を使用したVerticesは以下のものだけでした。

値もVertexの数も「4.2.1 Coordination Information」のVerticesとは違います。

「4.2.1 Coordination Information」のVerticesは実装する必要は無さそうです。

8.2.3 「4.3 Vertex Buffer」を読む

今週はこの節を軽く読む事にします。

CPU側で作成したVertex情報をGPU側に渡します。

そのためにまずGPU側でそのVertex情報を受け取る事が出来るようにGPU内のMemory領域を確保します。

つまりBufferを作成します。

<「4.3.1 ID3D12Resource Object」>

GPU側のMemoryを確保するためにDirectX12では、ID3D12Resource Objectを使用するそうです。教科書ではこのObjectの機能をCPU側でいう所のNewと同じと解説していました。

ID3D12Resource ObjectはID3D12Device:CreateComittedResource()関数を使用して作成するそうです。

ここではCreateComittedResource()関数のParameterについて簡単に説明していましたが、実際の実装方法や実際のCodeなどは書いてなかったです。

<「4.3.2 Vertex heapの設定」>

ここは何の説明をしているのかと思ったら先程のCreateComittedResource()関数の最初のParameterであるD3D12_HEAP_PROPERTIESについて説明していました。

細かい設定については実装する時に勉強します。

<「4.3.3 Resource 設定構造体」>

CreateComittedResource()関数の三番目のParameterであるD3D12_RESOURCE_DESC構造体の設定について解説しています。

それぞれの要素の値の決定方法についてそれなりに詳しい解説がありました。

<「4.3.4 Vertex Bufferの生成」>

やっとここでVertex Bufferを生成します。

CreateComittedResource()関数を実装しています。

この実装は来週やる事にします。

今週の「DirectX 12の魔導書」の勉強はここまでとします。

9.まとめと感想

なし

10.参照(Reference)

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

[2] CGHOW. (2023, November 4). 822 UE5 VFX tutorials in 0.71$ IS THIS EXPENSIVE ?? [Video]. YouTube. https://www.youtube.com/watch?v=-adQRxv3Vps

[3] Ben Cloward. (2023, March 9). Sharp Text Shader - Advanced Materials - Episode 18 [Video]. YouTube. https://www.youtube.com/watch?v=Euvy_R03rlg

[4] Waldron, J. (n.d.). M. Shear zones. Pressbooks. https://openeducationalberta.ca/introductorystructuralgeology/chapter/m-shear-zones/

[5] Wikipedia contributors. (2022, March 14). Shear zone. Wikipedia. https://en.wikipedia.org/wiki/Shear_zone

[6] Wikipedia contributors. (2023, November 16). Fault (geology). Wikipedia. https://en.wikipedia.org/wiki/Fault_(geology)

[7] Wikipedia contributors. (2023, April 21). Stack (geology). Wikipedia. https://en.wikipedia.org/wiki/Stack_(geology)

[8] Wikipedia contributors. (2022, September 8). Shatter cone. Wikipedia. https://en.wikipedia.org/wiki/Shatter_cone

[9] Wikipedia contributors. (2020, September 2). River terraces (tectonic–climatic interaction). Wikipedia. https://en.wikipedia.org/wiki/River_terraces_(tectonic%E2%80%93climatic_interaction)

[10] Rick Banks. (2022, June 20). Houdini 19 - Wall Tool 02 [Video]. YouTube. https://www.youtube.com/watch?v=J2Tf_OIy9CA

[11] Buckley, M. (n.d.). Ruler | SideFX. https://www.sidefx.com/tutorials/ruler/

[12] Resample. (n.d.). https://www.sidefx.com/docs/houdini/nodes/sop/resample.html

[13] Rick Banks. (2022, June 20). Houdini 19 - Wall Tool 03 [Video]. YouTube. https://www.youtube.com/watch?v=SxZEj504muU

[14] primpoint. (n.d.). https://www.sidefx.com/docs/houdini/vex/functions/primpoint.html

[15] point. (n.d.). https://www.sidefx.com/docs/houdini/expressions/point.html

[16] setpointattrib. (n.d.). https://www.sidefx.com/docs/houdini/vex/functions/setpointattrib.html

[17] MOVFX. (2023, April 5). Install Sidefx - Labs Tools  - Easy and straight to point video [Video]. YouTube. https://www.youtube.com/watch?v=GYWWD-McB7s

[18] Lötwig Fusel. (2023, May 1). Project Setup & ComPointer | D3D12 Beginners Tutorial [D3D12EZ] [Video]. YouTube. https://www.youtube.com/watch?v=rF30qoUFDq8

[19] Simple templated COM Pointer class (Because I don’t like the WRL ComPointer). (n.d.). Gist. https://gist.github.com/Ohjurot/e17a5f04e9719a44866b4f38a4f2f680

[20] Stevewhims. (2021, June 29). IUnknown::AddRef - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-addref

[21] Stevewhims. (2021, June 29). IUnknown::AddRef - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-addref