UE4の勉強記録

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

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

1. 今週の予定

今週も予定を見直す時間がありませんでした。ぶっつけ本番でやっていきます。

以下の内容を勉強します。

  1. 映像作品としてのLevelの作成
  2. AIの勉強
  3. Nvidia Omniverseの勉強
  4. Gaeaの勉強
  5. Houdiniの勉強
  6. UEFNの勉強
  7. DirectX12の勉強

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

YouTubeのお勧めでTerrain Remix Brushes - Unreal Engine 5 Tutorial [1]と言う動画が出て来ました。

これはUEの付属のPluginを使用してPhoto-realisticなLandscapeを生成するためのTutorialだったんですが、生成される地形の質が凄いです。

Gaeaと比較しても全然上です。

ので今週は予定を変更してこれを勉強する事にします。

今週やる予定だった以下の作業は来週やる事にします。

これらの作業も忘れないように以下にまとめておきます。

  • Plateを別なSub Levelに移動してLevel SequenceからPlateを消す実装を追加
  • Plateに自作のMaterialを使用する
  • もっと綺麗な背景を表示するためにLuma AIのPluginのVersionを確認したり、XVERSE 3D-GS UE Pluginとの性能を比較したりする

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

2.1 Terrain Remix Brushes - Unreal Engine 5 Tutorial [1]を勉強する

兎に角、ぱっと見には凄いです。

<00:00 - 01:00 – Intro>

このPluginの紹介として以下のようなLandscapeを一瞬で作成していました。

と思ったら有料でした。

一応、UE5.4を開いて確認します。

あれ?

Pluginありますね?

どういう事?

<01:01 - 02:14 - Landscape Setup>

Landscape Patchを追加します。

UEを再起動して

Landscape Modeを開きます。

Enable Edit Layerが使用できるようになっているのを確認して

Materialに以下の箇所にあるDefaultから一つを選びSetします。

ここではDefault1を追加しています。

これがPluginについてくるAssetなのか、それとも先程紹介された有料のPluginだけについてくるAssetなのかが分かりません。

これは実際に試して確認するしかなさそうです。

Layerの設定は以下のようにしていました。

Createを押してLandscapeを生成しました。

次にPaintに移動します。

通常のLandscape作成ならばManageで地形を作成するんですが、

ここではいきなりPaintから始まっています。

Layer Infoを作成しています。

なんとここでNon Weight-Blended Layerを選択していました。

Non Weight-Blended Layerを選択した事は無いです。

Weight-Blended Layer(normal)との違いについては、あんまりよく知らないです。

言葉通りに理解したらBlendをするのにWeightを考慮しないってなります。

次のLayerのRockもLayer Infoを作成しました。

こっちもNon Weight-Blended Layerです。

ここからよく分からない作業をいきなり始めました。

Erosionを右Clickして以下のBoxを表示し

Clear Layerを選択しました。

Layerを消すなら何で最初にLayerを作成するんでしょうか?

次のRockでも同じ事をしています。

ここでSelection Modeに戻ります。

<02:15 - 04:45 - Using the Brushes>

BrushesのFolderに移動します。

PeaksはMountainです。

Slop Detailsです。

Tutorialでは山をCutしてDetailを追加したと言っていました。

Valleysです。

谷ですね。

Peak1をLevel上にDrag and Dropします。

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

これはAcceptを押せば良いそうです。

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

うーん。

凄い。

しかしこの状態ではOutlinerには何も追加されていません。

もう一回Peak1をLevel上にDrag and Dropします。

Level上には一個のPeakが存在しているだけに見えます。

2個目のPeak1はOutliner上にも表示されるようになりました。

要するに一回目のDragはMeshとして認識されないので、もう一回してって事ですね。

Peak6を追加しています。

Outlinerを見ると

前に追加したPeak1は消えているので、Peak1を消して

その後でPeak6を追加したようです。

ここで追加したPeak6は普通のMeshのような操作が出来る事を説明しています。

Scaleを大きくすると以下のようにLandscapeで生成出来る最大値を超えてMountainを生成しようとして

平な部分が生成されるようになってしまいます。

これを解決するのに

以下に示した様に

LandscapeのZ Scaleの値を100から500に変更していました。

うーん。

これはLandscapeのZのSizeを500倍にするって事でしょう。

これで解決するんでしょうか?

Peak6を少しだけ移動させると、以下のようになりました。

あ、分かった。

これはその高さまでLandscapeは生成されますが、その分Meshは荒くなります。

更にMeshを追加して以下のようなLandscapeを生成しました。

<04:45 - 06:43 - Editing the Material>

Landscape Materialの値を変更します。

先程のDefaultのMaterialから色々選択しています。

Default2の結果です。

以下の部分で値を微調整していました。

最初、これはどこにある機能なんだと焦りましたが、

よく見たら単なるMaterial Instanceでした。

このMaterial InstanceのそれぞれのParameterの機能については別なTutorialで解説しているそうです。

<06:44 - 09:28 - Scattering Rocks>

Scatteringについての説明です。

以下のPCG GraphをLevel上に追加しました。

結果です。

なんとRockを追加しています。

しかもPCGを使用しています。

凄い。

BoxのSizeを大きくすると以下のように沢山のRockを生成するようになりました。

このPCGを選択した状態で

PCGComponent(PCG Component)を選択します。

すると以下のParameterが出て来ますので

ここで色々な設定を変更する事が出来るそうです。

これらのParameterの機能については別のTutorialで説明しているそうです。

今回のTutorialでは以下のBounding BoxのCheckを外して

Landscape全体にPCGを効かせる事だけやっていました。

近づいて見ると今の設定では岩が雪の上にも生成されています。

これはオカシイです。

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

Upper Tree Lineの値を5000に変更しました。

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

LandscapeのScaleのZの値が100ですので、最大値が512m、そこから推測するにこの5000の単位はcmでしょう。50m以上の高さにはRockを生成しない設定にしたみたいですね。

次に以下のPCGを追加していました。

設定は前のPCGと同じでした。

<09:29 - 11:40 – Outro>

Vegetationです。

Tutorialが言うには、私は優れたDesignerでは無いんで、Photo-realisticな木の3D Modelは作れない。だからこんな木を代わりに入れた。と言っていました。

代わりにMarket Placeで手に入れたPine Treeを使用した場合です。

これは凄い。

以上でした。

2.2 Terrain Remix Brushes - Unreal Engine 5 Tutorial [1]を勉強した感想

これが無料のPluginで出来るのなら凄いの一言です。

来週実際に試して確認します。

後はMaterialを外した状態のLandscapeを見てみたいですね。

GaeaからLandscapeをImportした時に発生する

以下に示した様な凸凹感が無いかどうかを確認したいです。

これが無かったたらこのやり方がこれからの主流になるでしょうね。

2.3 Plateを別なSub Levelに移動してLevel SequenceからPlateを消す実装を追加

時間が余ったのでこれだけやる事にします。

まずSub Level用のMapをEmpty Templateから作成します。

これをDragonのLevelにSub Levelとして追加します。

PlaneとPlane2を選択します。

切り取ります。

Emptyを選択した状態でPasteします。

Planeが他のAssetからReferenceされているけど強制的にやるか?

と聞いてきました。

あれ?

どっかでReferenceなんかしたんでしょうか。

取りあえずNoを選択します。

Plane3が作成されました。

Plane2はPlaneと同じAssetですが、Empty Levelに配置されています。

PlaneはどこでReferenceされているんでしょうか?

Level Sequencesを見てみます。

ありました。

消します。

OutlinerのPlaneも消しました。

これでEmpty Levelを消せばPlaneも消えるようになります。

Level Sequenceを開き+ Track ButtonからLevel Visibility Trackを追加します。

更にHiddenを追加してそこにEmptyを追加しました。

2.5秒の後はDragonの影が地面に写る必要は無いです。

Planeがある状態です。

Planeが消えた状態です。

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

www.youtube.com

なんとplaneが最初から消えています。

何で?

UEから見る時は、途中まではPlaneが写っています。

仕方ないのでLevel VisibilityにVisibleも追加しました。

結果です。

www.youtube.com

今度は影が写っています。

しかも動画の後半ではPlaneが消えています。

一応望み通りの設定をする事が出来ました。

3. AIの勉強

今週もJeremy Howard氏のTutorialを勉強していきます。

3.1 Lesson 2: Practical Deep Learning for Coders 2022 [1]を勉強する

<How to find information & source code on Python/fastai functions>

以下のように??を書いてFunction名を書くと

その関数の全情報が表示されます。

ここのTypeにFunctionと書かれていますが、Function以外のTypeがあるんでしょうか?

?の場合は

以下のような簡単な解説が表示されます。

更に以下のようにDocを使用したら

以下のような解説が表示されます。

この場合はDocumentへのLinkが追加されています。

Documentationの内容です。

これしかないの?

後、DocumentとDocumentationの違いが気になったので調べました。

日本語だとDocumentationってDocumentを作成する行為の事ですが、ここではいわゆる日本語でDocumentと言うべき文脈でDocumentationと言っています。

つまり英語ではDocumentationはDocumentを作成する行為は指してないです。

Copilotに質問しました。

ホントかな。

Difference between "document" and "documentation" [3]に以下の解説がありました。

これ読むと少なくともComputer ScienceにおいてはDocumentationはDocumentのPluralと言う意味であってそうです。

<Cleaning the data that we gathered by training a model>

DataをCleanする前にTrainするって言っています。

それだけでした。

<Explaining various resizing methods>

Resizeするための色々なMethodを紹介していました。

元のDataをbatchしました。

両端が切れています。これはCroppingという手法で画像を編集したからだそうです。

Squishしました。

画像全体が表示されるようになりましたが、クマが細くなってしまっています。

Padしました。

上下に画像として使用しない部分を作成する事で画像全体を歪めないで表示しています。

Pad Modeを0に指定する事でBackの色が黒になっているそうです。

<RandomResizedCrop explanation>

RandomResizedCropを使用しています。

RandomにCroppingします。

やるたびに画像が少しだけ変わります。

<Data augmentation>

先程の例のように、やるたびにDataの内容が変化するものをData Augmentationと呼ぶそうです。

以下に例を示しておきます。

<Question: Does fastai's data augmentation copy the image multiple times?>

data augmentationの実装に対しての質問で、これらの画像は元の画像をCopyして作成しているのかというのに対する回答です。

Copyする時に条件を少しだけ変更する事で一寸だけ違うImageをCopyしている。と説明していました。

そもそもこの質問がどんな目的で聞いて来たのかが分かりません。

元の画像を編集する事によって計算Costが余計にかかる事を気にしてCopyしているのかを聞いてるのかもしれないし、元の画像を編集する事は著作権違反ではないのか?という意味で質問しているのかもしれません。

そしてそれに対しての回答も、単に実装内容を解説しているだけです。

よく分からん部分です。

<Training a model so you can clean your data>

ここで本当にTrainを初めてしまいました。

<Confusion matrix explanation>

そしてConfusion Matrixを見ます。

Black BearとGrizzly Bearを間違えた例が2つあります。

そしてPlot Top Losesの説明に入るところで終わっています

今週はもっとやりたかったんですが、途中で用事が発生して時間が無くなってしまいました。

今週のAIの勉強はここまでで終了です。

4. Nvidia Omniverseの勉強

先々週は、以下のようにOmniverse Createに車を配置しました。

今週はこれに、先週勉強したSetting Up A Project in NVIDIA Omniverse Create Part 2: Lighting & Rendering [4]の内容を追加していきます。

4.1 Setting Up A Project in NVIDIA Omniverse Create Part 2: Lighting & Rendering [4]を実装する

<Intro>

特になし。

<Lighting Setup>0:41

以下のDefault Lightを消します。

全部のLightが無くなったので真っ暗になるかと思ったんですが、

僅かに車が確認できます。

Dome Lightを追加します。

使用したいHDRI Fileを以下に示したTexture Fileの値にDropします。

まずHDRI Fileを探します。

検索したらPoly Havenに行きました。

ム、前にここからHDRIを一個Downloadしたはずです。

そっちを探します。

ありました。

FormatがGIMPですが、これで行けるんでしょうか?

試してみます。

いけました。

でもこのHDRIのImageは変です。

別なのを探します。

これなんかどうでしょう?

LicenseはCC0になっています。

CC0の意味は

とCommentで解説されています。

まあ、大丈夫でしょう。

結果です。

こっちも同じ位あってないです。

これは車の影に比べて背景が明るすぎます。

後、この角度以外から見ると車が宙を浮いています。

次です。

おお。

これは良い。

しかもどの角度から見ても車が浮いている様には見えません。

こっちは曇りのVersionです。

車が真っ黒なのでこっちの方があってますね。

これに決定します。

良いんですが、Gridを消したいです。

Copilotに質問しました。

やってみます。

Viewport Settingにはいけないです。

以下の目のIconにGridをOn Offする機能がありました。

うーん。

Copilotの今回の回答はHallucination起こしてる可能性がありますね。

でもGridは消えたので良しとします。

<Render Setting>1:30

今度はRender Settingについてです。

Ray Tracingにセットされています。

Viewの左上にあるButtonからPath Tracedを選択します。

結果です。

みんなPath Tracedの方がRealだと言いますが、この結果のどこがRealなんでしょうか。

黒い粒子のぶつぶつがそこら中に発生していて、一言で言えば汚いです。

3D Graphicsは、もう何年も、このような質の低い結果しか生成出来ないPath Tracingを究極のTechniqueであると崇めています。

いい加減に気づけよ。

と言いたいです。

次ですが、先週のBlogでは

と解説されています。

これの事でしょうか?

Defaultの時です。

Roughness Cache Cutoffを1.0にしました。

全く変化していません。

効いてない気がします。

今回はCreateの機能をざっと確認するのが目的ですので、この辺の細かい設定を実際にどうやって使用するかはまた後で検証します。

先に行きます。

Path Tracedに設定を変更します。

Doom LightのColor Temperatureです。

これですね。

値を上げてみます。

結果です。

うーん。

床の光り方が変わった?

Defaultの場合です。

うーん。

あんまり変らないか。

今気が付きましたが、

Ray Tracingだと以下のように地面に反射したタイヤが以下のように写っていますが、

RTX Real Timeだと以下のように

地面に反射して映っているタイヤはほとんど確認出来ません。

<Camera Settings>4:25

今度はCameraの設定をやっていきます。

Cameraを追加しました。

Focal Lengthです。

Focal Lengthについては2023-09-11のBlogで勉強しています。

要はLenseの厚みの事です。

Lenseの厚みが増すほど、被写体に近づきます。

しかしそれだけでは無くて、

Lenseが熱くなるほど、画像がOrthogonalな状態に近づきます。

どのSizeのLenseが最適化はその時々で変わる訳です。

Focal Lengthを35に変更しました。

結果です。

一寸だけ下がりました。

うーん。

こっちの方がなじみがある画角ですね。

70も試してみました。

ここまで行くと何か変な気がします。

この場合に限りますがFocal Lengthは30位が丁度良かったです。

今度はF-Stopです。

このF-Stopを大きくした場合、背景がBlurになる傾向を確認します。

まずFocus Distanceの値を128にします。

結果です。

うーん。

背景に関して言うとあんまりBlurになってないですね。

FStopの値を0.1にするのを忘れていました。

結果です。

おお、Blurが凄い掛かっています。

F-Stopの値が3.8位になると

車はボケなくなりました。

このHDRIでは背景のBlurがよく分からないので、別なHDRIに変更します。

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

F-Stop、1.5です。

車の後の方がBlurが掛かっていますが、前面ははっきりしてBlurは無いです。

背景の雲に関して言うと、全然Blurになっていません。

うーん。

F-StopとBlurの関係についてはまだ勉強しないと理解出来ない部分がありますね。

今回はこれくらいにしておきます。

今度は別なCameraを作成して以下のように配置しました。

2つのCameraが車を別な角度から撮影しています。

Doom Lightの角度を調整しました。

先週のBlogで

と書いていましたが、

Viewportの左端にあるTool BarでRotationを選択すれば表示されました。

車の塗料がつや消しの黒のため

綺麗に写りません。

つや消し黒の車は絶対に選択してはいけないです。

相当かっこ悪くなります。

Screenshotを取ります。

Render Resolutionの値をCamera Settingsから調整します。

3840x2160にしました。

後、ScreenshotをSaveする場所を変更しました。

やり方は先週のBlogに書いてあるのでここでは書きません。

ProjectのSaveに関してですが、

先週のBlogによると

以下のようなScreenshotをThumbnailとして使用したUSDが生成されるとありましたが、

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

別なProject名でSaveしてみましたが

変らないです。

うーん。

ここは全然分からん。

CaptureしたScreenshotです。

Path Tracingで発生した黒い靄は消えてないし、車の大部分は影になってしまって車の形状ははっきりしません。

やっぱりPath Tracingは駄目です。

<Hiding Screenshot>10:27

ここでCameraを隠すとばかり思ってたんですが、実際はDoom LightのIconを消していました。

仕方ないのでDoom Lightの位置を以下のように移動してCamera1から見えるようにしました。

ここからLightのIconを消していました。

ただしここに写っているCameraはここから操作したのでは消えませんでした。

Stageから操作すると消えました。

以上です。

4.2 Omniverse Createを使用した感想

今回使用した感想を述べると、UE5やBlenderの性能を100とすると8ぐらいしかない。って感じです。

更にVideo Cardも結構な音を鳴らしていました。

まだVideo Cardに余裕はありますが、UE5を弄っていてこんな轟音を聞いた事ないです。

更にPath Tracingを強要する癖に、黒い靄が発生した時の対処方法についての解説は無いし、画像的にも非常に汚いです。

今の時点の評価では、100点満点で8点ぐらいです。

とてもOmniverseは実現しそうにないです。

5. Gaeaの勉強

今週は先週読んだHomepageの内容をもう少し深く勉強します。

5.1 Homepageの勉強

<Simulations>

これ、分かりました。

私が言っている、Terrainの作成の3つの工程の最後の時間経過を追加する。をまとめています。

Erosion2です。

以下の解説がありました。

実際にやって検証してみます。

以下のNodeを組みました。

これが

こうなりました。

なんか普通のErosionって感じです。

Thermal2です。

以下の解説がありました。

そう言えばGeologyの勉強した時に、色々なErosionが有りました。

その中で熱によって地形が変形するものをThermal Erosionと呼んでいます。

これも実際に試してみます。

何の変化もしませんでした。

もしかすると他の2つのInputに何かを指定する必要があるのかもしれません。

Debrisです。

これは時間経過関係ないと思ったら

Mechanical ErosionをSimulateしていました。

これも実際に試してみます。

結果です。

大量の岩が追加されました。

Snowです。

これも時間経過なんか計算してないと思ったら、以下に示した解説によると

太陽の光によって雪が溶ける影響なんかを計算していました。

これも実際に試してみました。

結果です。

何これ?

全部に雪が被っています。

使い方は分からないです。

Dustingです。

これの解説は無かったです。

実際に使用してみます。

結果です。

これはMaskとして使用するんでしょうか。

さっきのSnowノードと合わせて使用してみます。

以下のように使用してみました。

結果です。

おお、多分これが正しい使用方法なんでしょう。

Water Systemです。

解説です。

ある物理的なRuleに基づいて川や湖を生成するといっています。さらにそれらの周りの環境の変化も追加するとあるので、まあこれも時間経過の一種です。

Riversノードだけ試してみました。

結果です。

端の方に川が形成されています。

Vegetationです。

解説です。

色々解説していますが、木を生やすためのNodeです。

試してみます。

結果です。

これは木なのか?

<Construction>

これは先週のBlogで既に以下のように分析されていました。

それぞれの項目を見ていきます。

Construction with Primitivesです。

これNodeを表示されているCoordinateをDragする事で動かしています。

こんな事出来るの?

少なくとLayerが2つ以上生成されていないとこれは出来ないです。

解説は単にPrimitive Groupについて解説していました。

以下の解説が、もしかしたらPrimitive Groupのノードを移動させる方法なのかもしれません。

以下のようにTransformノードを使用して

以下のIconを選択します。

その結果View画面の上にCoordinateのIconが現れます。

これをDragするとMountainノードが移動します。

動画と同じ事が出来ました。

Mergeノードはありませんでした。Combineノードで代用します。

以下のように実装して

こんな地形を作成しました。

正直、Transformノードは

以下のParameterから操作した方が簡単です。

Import Objectsです。

これは解説から読んでいきます。

3DのModelをImportするのは以下に示したObjectノードでしょう。

これを試してみます。

まだ完成してないNodeでした。

Paint Landscapesです。

Painterで描くと実際のTerrainにも山が形成されています。

Primitives GroupにあるDrawノードを使用すると似たような事が出来ます。

Surface GroupのNodeを追加してそれっぽくしてみました。

結構良い感じです。

以下の項目はPrimitivesのNodeです。

<Surfaces>

Transpose Surfacesです。

これは2つのSurfaceを足しているだけでしょう。

解説を読みます。

Transposeノードがあると言っています。

上記の様に実装した場合、MountainノードのVolumeを保存したまま、PlateノードのSurfaceをTransposeしてくれるのでしょうか。

結果です。

うん。そうなってそうです。

Volume Preservationです。

解説です。

Surface GroupのNodeを使用したら作成したTerrainのVolumeは変化しないって事でしょう。

試してみます。

以下のTerrainで試してみます。

Surface GroupからCraggyノードを使用しました。

結果です。

おお、確かにTerrainのVolumeは保存されていそうです。

Paint Surfacesです。

これは解説がありません。

色々試しましたがこれのやり方は分かりませんでした。

と思ったら以下の解説がありました。

やってみます。

以下のように実装しました。

DrawノードからPaintする事でMountainにCraggyなSurfaceを追加してみます。

出来ました。

こんな簡単に出来るのか。

さっきまで全くできなかったのは何だったんでしょう。

Modifiersです。

これは以下の機能についての解説です。

これらの機能はNodeとして追加する事も出来るので

初心者にはこっちの方が分かり易いです。

残りの3つはNodeの説明です。

これはSkipします。

最後のSmall Scaleです。

これは解説もないし、何を指しているのか不明です。

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

6. Houdiniの勉強

先週の最後で以下のように書いていました。

これからやっていきます。

6.1 Convertlineノードについて

いつものようにConvert Lineノードを選択してそのHelpからDocumentを開きます。

InputしたGeometryをLine Segmentに変換するとありました。

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

Boxノードの結果です。

それぞれの面がPrimitiveとして表示されています。

Convertlineノードの結果です。

InputされたPoint同士をつなげているLineがPrimitive化しました。

うーん。

どういう原理でLineを抽出しているのか不明です。

取りあえず、Documentを読んでみますか。

そもそもこの最初のGeometryやPrimitive Attributeがこの文脈においては何を指しているのかが不明です。

Copilotに質問してみます。

まずGeometryの定義について質問しました。

最初の説明ですが、別にHoudiniに限らず全部の3D Graphicsに通じるGeometryの説明です。

SOPがここにも出て来ました。

SOPについての定義も後で調べる事にします。

今度はUnconverted Geometryについても調べる事にします。

これもCopilot先生に質問しました。

Unconverted Geometry はHoudiniにおいてはGeometry Dataの状態を示す言葉だそうです。

うーん。

成程。

以下の状態にあるGeometry DataはUnconvertedだそうです。

またここでもSOPが出て来ます。

Converted Geometryに相当するGeometry Dataの種類の解説もありました。

この情報だけではどのGeometry DataがConvertかどうかの判断を下す事は出来ません。

ただGeometry Dataの状態によってはUnconverted Geometryに分類される事がある事は判明しました。

次はPrimitive Attributeについて質問します。

ここではPrimitiveをPolygonと仮定してこの解説を理解します。

このPolygonを構成する色々な要素(例えばPointの位置)を保持しています。それらをPrimitive Attributeと呼ぶみたいです。

SOPについても質問しました。

この定義から推測すると、今やっているGeometryノード内に入って実装しているのは全部SOPって事になります。

これって正しい解釈なんでしょうか?

解説について来た動画を見る限りそのようです。

何となく理解出来たので、ConvertlineノードのDocumentの続きを読んでいきます。

何とここでどうやってLineを生成するのかを説明していました。

Primitiveを2つのPointで構成されるLineに変換する。と言っています。

PrimitiveでLineで繋がっている2つのPointは全部、Primitiveとして変換するみたいです。

先程のBoxの例でいえば、Pointの0と7は、元々のPrimitiveで繋がっていないので

Convertlineノードで変換しても

繋がってないと推測出来ます。

うん。

大体、どんなLineのPrimitiveを生成するか理解出来ました。

Parameterの説明です。

Groupです。

ここでEdgesを指定すれば指定したEdgesだけPrimitiveに変換します。

このGroupの指定方法、どっかで習ったんですが覚えていません。

Copilot先生に質問してみます。

Groupノードというのがあるのか。

更に具体的なやり方も示してくれました。

以下のTutorialも紹介してくれました。

Creating Groups with Vex | Houdini 19 [5]です。

軽く見たら、この動画ではGroupノードではなく、

Attribwrangleノードを使用してGroupを作成していました。

こんな感じのCodeを書いていました。

VEXを用いてGroupを作成する方法はCopilotでも紹介されていました。

じゃあ、Convertlineノードの勉強は一端おいて、Groupの作成方法について勉強します。

6.2 Groupの作成方法について

<Groupノード>

まずはCopilotの説明通りにGroupノードを使用してGroupを作成します。

以下のようにGroupノードを追加しました。

これは難なく見つかりました。

以下のようにSetしました。

これも問題なく出来ました。

これが出来ません。

ViewportからEdgeをClickしたりしたんですが、選択出来ません。

Base Groupを使用しろとありますが、どうやって使用するのか不明です。

分かりました。

適当にいじっていたら判明しました。

まずBase Groupの以下のIconをClickします。

すると

以下のように選択したEdgeの色が変化します。

Screenshotでは写っていませんが、Cursorが2-7のEdgeの上にHoveringしています。

その状態でClickすると以下のように

選択したEdgeの色がOrangeに変化します。

この状態でEnterを押すと

Base Groupに選択したEdgeが追加されます。

Edgeが一個では寂しいので以下のように4つのEdgeを選択し

Base Groupに追加しました。

なんでp2-7-5というEdgeが指定されているんでしょうか?

ここはp2-7、p7-5の2つで指定されるべきだと思うんですが。

この辺はまだよく分かりません。

Group NameはTest1としました。

これで完成です。

とあります。

Convertlineノードに繋いで使用してみましょう。

Convertlineノードから先程作成したGroup、Test1を選択する事が出来ました。

結果です。

Group化したEdgeだけがPrimitiveとして生成されました。

<Attribwrangleノードを使用>

もうこれは説明の通りに

と打ってやってみます。

何とBoxノードをつないだらErrorになってしまいました。

色々やったんですがErrorの原因が分かりません。

Copilot先生に聞いてみます。

pは大文字じゃない?

って言っています。

Pを大文字にしたらErrorが消えました。

はあ。

これが問題だったのか。

正直疲れました。

ConvertlineノードのGroupを1に指定しました。

結果です。

うーん。

これ正しい解答なんでしょうか?

あってないです。

そうかConvertLineノードにパス出来るGroupはPointではなくEdgeでした。

仕方ない。

Tutorialのやり方でやってみます。

まずGridノードを配置します。

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

Attribwrangleノードを追加します。

Mountainノードを追加します。

MountainノードのGroupにGroupNameを選択します。

え?

さっきのAttribwrangleノードに書いたCode、

1がGroup名になるんじゃないの?

うーん。

分かりません。

試しにGroupNameをTestに変更してみました。

MountainノードのGroupを見るとTestがありました。

ではこの1は何を示しているんでしょうね。

結果です。

これ見るとー0.5の値を持つPointも含まれている感じがします。

Geometry Spreadsheetで確認します。

Point4のXの値は-0.5555で0より小さいです。

以下のCodeによれば

1にはならないです。

なってます。

更にViewportで確認してもMountainノードの影響を受けているのが分かります。

細かい点はまだ訳分からないですが、

これで一応Groupの作成方法は理解出来た事にします。

もう疲れたのでHoudiniの勉強はここまでとします。

来週はConvertlineノードの勉強の続きからやる事にします。

7. UEFNの勉強

7.1 先週の復習

先週何を勉強したのか覚えていません。

先週のBlogを読み直して復習します。

まず Create Custom NPC Behavior [6]の実装をやっていました。

これは実際には2024-07-14のBlogでやった内容を別なNPC_Behaviorでやり直しただけです。

その後で、UEFNのNPC_Behaviorの勉強の総復習をやっています。

その結果、以下の事をやっていた事が判明しました。

  1. 最初で最大の目的はVerse_Deviceの代わりにNPC Behaviorを使用してVerseのCodeが書けるようにする。
  2. そのために公式SiteにあったCreate Custom NPC Behavior[6]の勉強を始めた。
  3. Create Custom NPC Behavior[6]の勉強を始めたら、最初の2項目のCodeはDefaultで書かれていた。更にDefaultで書かれているCodeはそれ以外にも沢山ありDefaultで書かれているCodeの意味を理解するのが先だ。となった。
  4. DefaultのCodeを理解しようとしたら、なんとClassの作成方法などのもっとも基本的な内容すら覚えてない事に気が付き急いで復習した。

そして先週は基本的な復習が終わったので、DefaultのCodeの続きを勉強する事にしました。

Focusまで勉強しました。

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

この続きからやる事にします。

7.2 npc_behaviorのDefaultのCodeの続きを勉強する

まず以下のIf、Thenの意味が分かりません。

これから調べます。

まずCopilot先生に質問しました。

うーん。

でもIf節にConditionが無いんです。

まあCharacterを得ることが出来たら、Then節の内容を実行する。と解釈するならまあこの説明の通りです。

一応これで納得しておきます。

検索したら

公式SiteのVerse Language Quick Reference [7]の以下のIfの項目で説明されていました。

以下のように使用するそうです。

そして以下のように実行されるそうです。

うーん。

これだと以下のIf節内のCodeで、望んだObjectを得ることが出来なかった場合に何らかのFalseを発する必要があります。

例えばGetAgentはAgentを得る事が出来なかったら、Falseを返すんでしょうか?

公式SiteのGetAgent function [7]を読みます。

うーん。

どんなAgentを得ることが出来なかった時に、どんなReturn Valueがあるのかは説明されていませんでした。

しかし以下のヒントがありました。

このDecidesというSpecifierを使用している関数は失敗する可能性があります。そしてそういう関数を総じてFailable Expressionと言うそうです。

このFailable Expressionを調べると

と書かれていました。

つまり失敗した時は何の値も返さない訳です。

Agentになんの値も帰ってこなかった場合は、if節のConditionが満たされなかったとして、Then節には行かないという事になりそうです。

Then節をSkipした場合、どうなるかを調べました。

なんと、Else節がありました。

Agentを得る事に失敗した場合、としっかり書かれていました。

うーん。

納得しました。

ではThen節の内部で何をやっているのかを解読していきます。

まずTODOのCommentがありました。

Agentとそれに伴うAI Interface(NavigatableやFocusの事ですね。)が使用出来るようになったので、これらを使って望みのBehaviorを追加して下さいと言っています。

Debug関連のCodeは今は無視して先に進みます。

後でまとめて勉強します。

NPCがSpawnした場所を保持するためのConstantを作成しています。

このNPCSpawnPointのTypeは何なんでしょう?

TranslationのTypeがVector3なのでVector3でしょうね。

ここからLoopが始まります。

まずNPCが移動するPointを決定しています。

Debug用のCodeです。

これらは後でまとめて勉強します。今は無視して先に進みます。

NavigationTargetを生成します。

MakeNavigationTarget function [8]の公式Siteです。

Navigation_Targetを生成するとあります。

その前にこのSiteなんですが、腐っても公式Siteなんですから

Googleの検索結果には表示されるべきだと思うんですけど、

Copilotでは一発で表示されました。

もう検索EngineとしてのGoogleの天下も終わりですね。

またDebugです。

ここのでNavigataTo()関数が出て来ました。

調べます。

この関数は珍しくCodeからDefinitionを見る事が出来ました。

最初のParameterにNavigation_Targetがありました。

残りのParameterは?と=があるのでOptionで指定してもしなくても良いParameterになります。

次のCodeです。

<>の意味が分かりません。

つまり2つの値が違っていたらTrueを返すOperatorでした。

今度はWait()関数について調べます。

こんな例が出ていました。

公式Siteですが、先にnavigatable interface [9]を調べます。

このInterfaceにあるFunctionです。

さっき見たDefinitionにある説明と同じですね。

こんだけ調べれば十分です。

Wait()関数はParameterで指定した時間、待つFunctionと分かりました。

Copilotの例では単位は秒になっていましたが、ここまでAIを信用して良いのかは不明です。

またDebugです。

Commentの意味が分かりません。

強引に訳してみました。

NPCが目的地に着くまで待っているのを利用してConcurrencyを活用します。

Spawnした場所を見直すためのCallとDebugのための矢のDrawingが決して完了しない間、ずっと続きます。

NavigateToだけがこの競争に勝てるようにして下さい。

うーん。

Continuingが何に掛かっているのか不明です。

Deep Lにも訳してもらいました。

NPCが目的地に到着するまで待つために並行性を活用し、

その一方で、その原点を振り返り、デバッグ矢印を描くための呼び出しは完了することなく、継続することで、

NavigateToだけがレースに勝つことができます。

ああ。

成程。

こっちの方が正しい訳ですわ。

永遠に終了しないCallとDebugとNavigateToを競争させる事でNavigateToが必ず勝つ事が出来ると言ってるんですわ。

うーん。

Deep L凄い!

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

来週はRaceについて調査する事から始めます。

8. DirectX12の勉強

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

先週のBlogの最後に以下のように書いてあったので

今週はResizing the SwapChain | D3D12 Beginners Tutorial [D3D12Ez] [10]の勉強をします。

8.1.1 Resizing the SwapChain | D3D12 Beginners Tutorial [D3D12Ez] [10]を勉強する

何とこのTutorial、節が無いです。

まあ再生回数も700回しかないですし

作者のやる気も無くなるか。

前回までに作成したSwap ChainはSizeが固定されていてWindowのSizeが変更される事に対応していないそうです。

このTutorialではWindowのSizeが変更された場合、Swap ChainのSizeも変更されるような実装を追加します。

ここでSwap ChainのSizeは指定されています。

確かに固定されています。

WindowのSizeが変更された場合、

以下に示したようにScalingの設定が

DXGI_SCALING_STRETCHとなっているので

Stretchされます。

じゃWindowのSizeは変更されているじゃん。と思ったんですが、

SwdのWidthとHeightの値は同じなので1920pxと1080pxは変化しないそうです。

うーん。

成程。WindowのSizeが1920pxと1080pxより小さい場合は1920pxと1080pxでSwap Chainする必要ないですし、WindowのSizeが1920pxと1080pxより大きい場合は1920pxと1080pxでSwap Chainしたら何かが足りなくなる訳か。

Swap ChainをResizeするには、Codeを変更するだけでは足りなくて、NvidiaGPUの設定も変更する必要があるそうです。

ここでNvidia Nsight Graphicsを開いています。

うーん。

これはどうやって開くんだよ。

このNvidia Nsight Graphicsについては後で調べる事にします。

以下に示したNew ProjectをClickして

以下のWindowを開きます。

Application ExecutableにこのProjectの

ReleaseでBuildされたExe Fileをセットします。

Launch Frame Debuggerを押して実行します。

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

KeepをClickするそうです。

Terminateが開いて以下のような内容が表示されるそうです。

このTerminateのSizeを以下のように小さくします。

表示されている文字まで小さくなって字が読めなくなってしまいました。

成程。

これを見せたかったのか。

このTextはNvidiaによってSwap Chainそのものに書かれているのでこんな結果になってしまうそうです。

別にSwap ChainをResizeするにNvidiaGPUの設定も変更する必要は無かったのね。

で解決策なんですが、以下のFunctionを呼べば良いそうです。

しかしこのFunctionは単に呼び出すだけでは使用出来ないそうです。

まずWindowのSizeが変更された時に適宜、呼び出す必要があります。

具体的には以下に示した様にWindow Cpp fileのOnWindowMessage()関数内に実装します。

成程。

こうやってWindowのMessageに対してどんな反応をするのかを決めるのか。

勉強になります。

と思ったら、TutorialがMessage Block内でこういう作業を直接実装する事はやらない。と言い始めました。

うーん。

そうなの?

代わりにWindow.h fileに以下のBooleanを作成し

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

うんうん。

段々このTutorialの言っている事の意味が分かって来ました。

で、このBooleanがTrueになった時に起動する関数を作成するんですね。

まず以下に示した様にShouldResize()関数を作成しました。

そしてResize()関数を作成します。

以下に示した様にまず宣言しました。

そして実装します。

まずGetClientRect()関数を使用して現在のWindowのSizeを取得します。

以下に示した方法によりWindowのWidthとHeightを計算します。

Window.hの以下の場所に変数を追加しました。

そしてResize()関数の実装の以下の部分を変更しました。

そしてここでResizeBuffers()関数を追加します。

ResizeBuffers()関数のParameterを指定に従ってセットしていきます。

個々のParameterについては実装する時に調査します。

最後のParameterは以下の場所で指定したのと同じのを指定する必要があるそうです。

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

そして最後にm_shouldResizeにFlaseをセットします。

これでResize()関数が完成しました。

霧が良いので今週のLötwig Fusel氏のD3D12 Beginners Tutorial [D3D12Ez]の勉強はここまでとします。

8.2 「DirectX 12の魔導書」を勉強する

8.2.1 「5.4 Texture Dataの作成」を勉強する

最初はFileからDataを読み込むものではなく、ProgrammingでTexture Dataを生成してそれを使用するそうです。

以下のような実装からTexture用のDataを作成します。

まずUnsigned Char型の変数、RGBAを持つStruct、TexRGBAを作成します。

このStructを256x256持つVector、texturedataを作成し完成です。

ここに以下の実装を使用してRandomなDataを入れます。

以上です。

今週の「DirectX 12の魔導書」の勉強は短いですが、たまにはこれも良いでしょう。

9. まとめと感想

なし

10. 参照(Reference)

[1] Jakob Menz. (2024, July 22). Terrain Remix Brushes - Unreal Engine 5 tutorial [Video]. YouTube. https://www.youtube.com/watch?v=9hyiyRZpId0

[2] Jeremy Howard. (2022, July 21). Lesson 2: Practical Deep Learning for Coders 2022 [Video]. YouTube. https://www.youtube.com/watch?v=F4tvM4Vb3A0

[3] Difference between “document” and “documentation.” (n.d.). English Language Learners Stack Exchange. https://ell.stackexchange.com/questions/16580/difference-between-document-and-documentation

[4] NVIDIA Studio. (2022, January 8). Setting up a project in NVIDIA Omniverse Create Part 2: Lighting & Rendering [Video]. YouTube. https://www.youtube.com/watch?v=OVCY84-QHN4

[5] Inside The Mind. (2022, February 8). Creating Groups with Vex | Houdini 19 [Video]. YouTube. https://www.youtube.com/watch?v=8g9wbHwdp1k

[6] NPC Character Definitions. (n.d.). Epic Dev. https://dev.epicgames.com/documentation/en-us/uefn/npc-character-definitions-in-unreal-editor-for-fortnite

[7] GetAgent function. (n.d.). Epic Dev. https://dev.epicgames.com/documentation/en-us/uefn/verse-api/fortnitedotcom/characters/fort_character/getagent

[8] MakeNavigationTarget function. (n.d.). Epic Dev. https://dev.epicgames.com/documentation/en-us/uefn/verse-api/fortnitedotcom/ai/makenavigationtarget

[9] navigatable interface. (n.d.). Epic Dev. https://dev.epicgames.com/documentation/en-us/uefn/verse-api/fortnitedotcom/ai/navigatable

[10] Lötwig Fusel. (2023, June 21). Resizing the SwapChain | D3D12 Beginners Tutorial [D3D12EZ] [Video]. YouTube. https://www.youtube.com/watch?v=QOT_OzPJl6c