UE4の勉強記録

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

UE5の勉強 -LandscapeのみのGameを作成する-

1. 今週の予定

以下の内容を勉強する予定です。

<LandscapeのみのGameを作成する>

GaeaのDataに川と湖を追加します。それをMaskとしてExportしUE5で川と湖を示します。

Niagaraの勉強>

先週勉強した Unreal Engine 5 Tutorial - Shading Niagara Fluids – Honey [1]を実装します。

<Materialの勉強>

GIMPを使用してRGB alphaのそれぞれのChannelにImageを張り付ける方法を勉強します。

<戦闘システムの続きを作成する>

MonsterのAnimationを追加します。

<Gaeaの勉強>

Andrea Cantelli氏のGaea Tutorial for Beginners #1 | Intro to the series & Analyzing the Interface [2]のToolboxの最後の三本線のIconとSettingを勉強します。

<Houdiniの勉強>

公式のTutorialであるFOUNDATIONS | OVERVIEW [3]のView Toolsの続きを勉強します。

<Volumetric Cloudの勉強内容をまとめる>

2枚のTextureのImageを変える事で雲の形状をある程度変更出来る事についてもっと深堀する。

DirectXの勉強>

OlympusMonsTutorials氏のC++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [4]のPrecompiled Headerを勉強します。

2.LandscapeのみのGameを作成する

2.1 GaeaのDataに川を追加する

先週、Gaeaで作成したTerrainの実装を見たら以下に示した様に既にRiversノードを使用していました。

RiverノードのImageを見ると

これで十分です。

これをBuildしてExportします。

Fxノードを繋げます。名前をRiverにしました。

以下にRiverノードのImageを示します。

このImageをRiverのMaskとしてExportします。

2.2 湖を追加する

Lakeノードを追加したんですが、Seaノードとほぼ同じ箇所を湖にして山の麓に湖を作成することが出来ません。

Maskを使用したら出来るのかと思ったんですが、湖が生成出来るのかその箇所が周りより低くなってないとダメみたいです。

取り敢えずこれは中止します。

結構、想像していたのと全く違う結果になります。

ここにNodeを入れたらこうなるはずだ。と思ってやったら全然違う結果になってしまいます。

これは先に川を追加した結果だけBuildしてUE5で確認した方が良いかもしれません。

後、Beachを砂場と岩場に分けたかったんですが、それも止めて取りあえず川だけ追加したHeight MapとMaskをBuildしてそれをUE5で確認する事にします。

2.3 取りあえず川だけ追加したTerrainをBuildしてUE5で確認する

Buildの設定は前回のがそのまま残っていたのでそれを使用します。

新しいHeight MapとMaskが出来ました。

まず新しいMaterialを作成しました。

単にRiverのLayerを追加しただけです。

一寸先週やったやり方を復習します。

で新しいLandscapeを作成しました。

空を追加します。

そしてSky LightのReal Time CaptureにCheckを入れます。

以下の条件でImportしました。

Height MapとMaterialが変わっている以外は先週と全く同じ条件です。

PaintのPaintを選択して

それぞれのLayerInfoを作成しました。

Cliffを選択してFill Layerを選択します。

先週はこれが抜けていたからうまく出来なかった。見たく書いていましたが、これをやらなくてもLandscapeは既にCliffの色一色になっています。あんまり重要じゃないのかもしれません。

次はManageのImportに移動して

対応するMaskを指定します。

あ、最後のLayerをSeaではなくLakeにしてありました。

これは間違いですね。

後で直します。

それぞれのLayerを一個ずつ選択して順番にImportしました。

最後のLakeだRiverのCheckを外すのを忘れてしまいました。

近づいて確認しましたが、大丈夫そうですね。

海の上に川が流れている事は無いですね。

Play画面です。

小川になっていますね。

川の上限まで登ってみました。

あんまりよく分かりません。

こっちにもっと太い川がありました。

Play画面です。

これでも小川サイズですね。

川を上ったらLandscapeの凸凹が教養出来ない範囲でひどいです。

もっと大きな川を見つけました。

これも登ってみます。

川が道標になっていろんな所を探索出来ます。

山脈の中腹にある草原にたどり着く事が出来ました。

2.4 Water Systemを勉強する

以下に示した様に一月中にWater Systemを勉強してこの島に追加する予定です。

それでWater Systemは色々問題があってうまく使用出来ないとかの噂があります。

のでこれを早く勉強して試す事にしました。

Klaus氏のUnreal Engine 5: Water System in UE5 Tutorial [5]を勉強します。

<Over View>

もう、最初からWater SimulationはまだExperimentalだから製品には使用しないように。と言っています。

でもその限界と回避の方法もここで解説する。と言っていました。

うーん。

これは勉強し甲斐があります。

<Getting the Water Ready>

当然、Water SystemはPluginなので以下に示した様にPluginのWaterを追加する必要があります。

敢えて実装と勉強を分ける必要もないでしょう。

一緒にやっていきます。

先程作成したLandscapeで試してみます。

まずWaterのPluginを追加しました。

以下に示した様にWater ExtrasというPluginも表示されています。

Water Extrasが必要なのかは不明ですが、Tutorialを見るとこっちもCheckされているので一緒にCheckしました。

UE5 EditorをRestartさせます。

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

検索したらUE ForumのHelp Please Error Packaging Project [6]でほとんど同じ質問がされていました。

しかも以下の解答で解決したとあります。

成程。

理解しました。

まずはこのError表示にあるAdd entry to DefaultEngine.iniをClickします。

うんともすんとも言いません。

DefaultEngine.iniを開いて確認します。

うーん。新しいPCにはNotepad++もVisual Codeもまだ入れてなかった。

Notepadで開きます。

普通に[/Script/Engine.CollisionProfile]がありました。

多分、Add entry to DefaultEngine.iniを押したことでこれらのLinesが追加されたんでしょう。

以下の箇所からWaterのPluginが追加された事が確認できます。

確認出来ました。

この後、TutorialはEmptyのMapから空を作成する手順を示しています。

この部分は要らないのでSkipします。

<Preparing Landscape>

ここも既に知っている内容なのでSkipします。

と思ったら結構、重要な事をそこかしこで述べていました。

ので大切だと思った事は以下に記録します。

最初のLayerInfoを作成すると自動的にLandscape全体にこのMaterialが適応されます。

されない場合は、このLayerを右ClickしてFill Layerを選択するそうです。

はい。

さっきの疑問が解消されました。

LandscapeのLayerを使用するために、LandscapeのParameterにあるEnable Edit LayersのCheckを入れる必要があります。

これはDefaultで入っていました。

LandscapeのPaintのPaintにある

Edit Layersについてです。

Layer1とLayer2を追加しています。

このLayerはお絵かきソフトのLayerと全く同じ機能をLandscapeで実装したものです。

それぞれのLayerでLandscapeを追加出来ます。

もしそのLayerでLandscapeの造形をやり直したい時は以下の様にLayerを右Clickして

Clearを選択しSculptを選択します。Allを選択するとPaintとかも無くなるそうです。

ここでTutorialはWaterを追加した場合、元のLayerの形状に影響を及ぼすので別なLayerにWaterを追加しろみたいな事を言っているみたいなんですが、一寸理解出来ないです。

ここは続きを見てから何を言いたかったのか判断する事にします。

<Save the Ocean>

Water Body Occeanを追加しました。

すると以下に示した様に画面からLandscapeが消え4つの点のある四角い線が表示されるようになりました。

更に以下に示した様に3つのものが追加されました。

やってみます。

Tutorialと同じようにやったら以下に示した様に3つのものが追加されました。

画面はかなり違います。

一面海になってしまいました。

広がってみたらこんな感じです。

先程のEdit Layersに移動したらWaterが追加されていました。

さっきの説明はこれが言いたかったんでしょうか?

次にLandscapeのLocationを0,0,0にセットし直しています。

これやっぱし0,0,0が正しいんでしょうか。

ここでWater Systemの2つの問題点について語っています。

  • 小さなLandscapeにしか適用出来ない
  • 原点から離れれば離れるほどおかしくなる。

だそうです。

どうやらKlaus氏はWater Systemの問題も熟知していて更にその解決方法も既に把握しているみたいです。

これは安心しました。

LandscapeとWater Body OcceanのLocationを0,0,0にセットし直しました。

以下の様になりました。

いやTutorialの続きを見たら以下の様にしてLandscapeの中央が原点に来るようにしていました。

直しました。

TutorialによるとZの値も原点より少しだけ高い方がうまく働くそうです。

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

調べたらLandscapeの中心を原点に合わせるには以下の様に-を付ける必要がありました。

Tutorialを見直したらNegativeになっていました。

今度はWaterBodyOcceanの高さを調整します。

Tutorialでは何を基準に高さを決めているのか不明なのでLandscapeの高さと揃う感じにしてみました。

次にWaterBodyOcceanのMaterialについて説明しています。

今回はこの部分は変更しないので何もしません。

因みに私のProjectの方では以下に示した様に5つのMaterialが使用出来るようになっていました。

この後、WaterBodyOcceanのSpline Pointの説明がずっと続きます。

どこで勉強したのか覚えていませんがこれの使用方法は知っています。

一応、大切そうな所だけ以下にまとめます。

Spline Pointを選択してXY方向に移動させるとOcceanの形状が変化します。

ただしZ軸には動きません。

もしSpline Pointを追加したい場合は、追加したい所を右Clickして以下のBoxを表示させ

Add Spline Point Hereを選択します。

Spline PointをDuplicateする時は、DuplicateしたいSpline Pointを選択して以下のBoxを表示して

Duplicate Spline Pointを選択します。

Altを押しながらDragしても同じ事が出来ます。

次はSpline Pointのtypeですが、以下の様になっているそうです。

これは分かりやすい。

Constantがこうなっているのは知りませんでした。

ただしTutorialによると最後に全部を選択してCurveに変更すべきで、途中で一個だけLinearからCurveに変更すると全体の調整が難しくなって失敗してしまうそうです。

はい。

それではSpline Pointの調整をやってみます。

取りあえず以下の様にしました。

微調整は後からします。

Play画面から見た映像です。

海の中です。

海底が浅いので顔から上が海から出ています。

取りあえずはこれでOKにします。

海のMaterialの色は濃い茶色の方がいいかもしれませんね。これは後で検討します。

<Meet me at the Lake>

Water Body Lakeを追加して今度はLakeの使用方法を勉強します。

こんなの大したことないから聞くだけでいいか。と思って聞いていたらWater SystemのParameterの使用方法について解説していて、大変重要な内容でした。

仕方ないので以下に示した様にWater Body Lakeを配置して、このParameterについて勉強する事にします。

まず以下に示したWater Body Lake全体を示す矢印ですが、これはZ軸を動かす事が出来ます。

Z軸上に動かす事が出来ないのは一個一個のSpline Pointだそうです。

<<Selected Points>>

Select Spline Pointsです。

Tutorialでは一個一個の使用方法について解説していますが、以下に示した様にCursorを載せるとそれぞれの機能について簡単な説明が表示されます。

これを見ると全部理解出来るのでここにはまとめません。

以下に示した様にそれぞれのSpline Pointには2つのPointが繋がっています。

この2つのPointを調節するのが以下のArrive TangentとLeave Tangentです。

<Island, Hole and Terrain Settings>

TutorialではここからSectionが変わっています。ので同じにします。ただし内容は変わっていません。

<<Water>>

Velocityです。

これは川の時に使用するそうです。

Water Body IslandsとWater Body Exclusion Volumesです。

ここは自動で追加されるので弄る必要はないみたいです。

以下にTutorialの例を示します。

こんな感じです。

<<Terrain>>

Curve Settingです。

Channel Edge Offsetです。

0の時です。

-1000です。

湖のサイズが小さくなりました。

Channel Depthです。

湖底の深さを示しているみたいです。

500の時です。

1000の時です。

湖底が深くなりました。

Curve Ramp Widthです。

これは一番深い場所に行くまでの距離を示しています。

この条件だと20m必要です。

<Wave Theory>

Tutorialでは、ここからWave Theoryになります。

<<Wave>>

岸から波が小さくなる距離を示します。

0の時は波は全く小さくなりません。

Wave Sourceについてです。

この辺の設定はEngineにあるAssetが担当しているので弄るのは止めておきます。

と思ったらTutorialで一から作成する方法が載っていました。

せっかくなので試してみます。

中身です。

まず以下の部分は他の選択肢がないのでそのままだそうです。

Num Wavesです。

この数が多いほどRealisticな波が出来るそうです。

ただしその分計算に負担もかかります。

TutorialによるとSmartphone用のGameでは2にした方が無難と言っていました。

Wavelengthです。

当然ですが波の長さです。

Amplitudeです。

波の高さです。

Directionです。

風が吹く方向です。

Steepnessです。

波の高さの急さを示しています。

自分で作成したWater WavesをLakeに使用してみました。

波を穏やかにしてみました。

<River flows in you>

今度はRiverの話です。

取りあえずWater Body Riverを追加しました。

Splineが見えません。

G押したら出て来ました。

Spline Pointを弄って川をまっすぐにしました。

川が太すぎます。

まあ最初はTutorialの解説を見る事にします。

Tutorialによると川の流れている向きから確認するそうです。

あっています。

以下のParameterでRiverの特徴を調整出来るそうです。

取りあえずは以下の様にしました。

Riverは後で調整します。

<Blending, Translucency and LODs>

ここまで来てあれなんですが、前にWater Systemについて勉強していました。

何か、知っている事や、概念を説明される前から理解していたりとかして?だったんですが、思い出しました。

前に勉強した事ありました。

このWireframeの絵で完全に思い出しました。

この海の部分がTranslucentであるように見えますが

実際のRenderingではOpaqueだそうです。

Landscapeと海のSurfaceをBlendして表示しているので見かけ上Translucentに見えるだけだそうです。

これを証明するのにCubeにTranslucentなMaterialを張り付けて半分だけ海に沈めています。

海が本当に透明なら沈んだ部分のCubeも海から見えるはずですが、ここでは完全に消えています。

うーん。

納得。

MeshのサイズもCameraからの距離によって変わるそうです。

Naniteと同じです。

<Lonely Island?>

完成品をみせているだけです。

<Good Stuff>

Tutorialの終わりで特に何かを語っている訳ではないです。

以上でした。

2.5 RiverをもっとRealにする

これをやります。

GaeaのRiver通りに作成したら逆に変になってしました。

GaeaのTerrainは1009x1009で出力すべきサイズではないですね。これ三倍、下手したら10倍の大きさで出力すべきでした。

いきなり大問題です。

川のMeshが切れています。

これで作り直します。

川を作成していたら完全に酔ってしまいました。

3D酔いです。UEを弄っていて初めてなりました。

吐きそうです。

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

3.Niagaraの勉強

今週は先週勉強したUnreal Engine 5 Tutorial - Shading Niagara Fluids – Honey [7]を実装します。

3.1 Unreal Engine 5 Tutorial - Shading Niagara Fluids – Honey [7]を実装する

Grid 3D FLIP Hoseを使用してNiagara Systemを作成します。

NS_Honeyと名付けました。

FoamやSprayを形成するEmitterは要らないので消します。

次に水の高さを調整するためにSystem StackのUser Parameter SectionにあるWater Heightの値を20にします。

しました。

User Parameterがどこにあるのか分からなくて探すのが大変でした。

System StackのUser Parameter Sectionを選択して

Selectionを見ても何も表示されません。

Default画面で左下に表示されているParametersのTabの隣にUser Parametersがあります。

ここにありました。

Pressure Iterationsの値も変更します。

先週のBlogに

と書かれていました。

一寸調べてみます。

Grid3D_FLIP_FluidControl_Emitterで[USER] Pressure Iterationsが使用されている箇所を調べます。

10か所で使用されているみたいです。

Sim Sectionで使用されていました。

Parameter Writes SectionにもPressure Iterationsがありました。

ただしこっちは[EMITTER][OVERRIDE]です。

Simulation Sectionにもありました。

これを見ると[USER] Pressure Iterationsが使用されているのはSim Sectionだけです。

ここで調査が詰まってしまいました。

以下にEmitter StackのSectionを示しますが、

Simはありません。

SimはEmitter SummaryにあるSectionの一つですが、実際のEmitterにはないSectionでした。

ありました。

Emitter Spawn SectionにあるGrid 3D FLIP FLUID CONTROLS Moduleの

Simにありました。

Grid 3D FLIP FLUID CONTROLS Moduleの実装を見ると以下に示した様に、

[USER] Pressure Iterationsの値を[INPUT] Pressure Iterationsにパスして、更にその値を[EMITTER] [OVERRIDE] Pressure Iterationsにパスしています。

成程ね。

今度は[EMITTER] [OVERRIDE] Pressure Iterationsを追えば良いわけです。

次のModuleであるGrid 3D FLIP SCALABILITY SPAWNでも

Particle Per Cellに[EMITTER][OVERRIDE] Pressure Iterationsが使用されていました。

このModuleの実装も見てみましょう。

ApplyOverrideがTrueだったら[INPUT] Pressure Iterationsを使用してFalaseだったら[EMITTER][OVERRIDE] Pressure Iterationsを使用しろと言っていますが、

[INPUT] Pressure IterationsにセットされているParameterは[EMITTER][OVERRIDE] Pressure Iterationsなので結局、[EMITTER][OVERRIDE] Pressure Iterationsの値になります。

Particles Per Cellの方も全く同じ実装でした。

こっちはApplyOverrideがTrueの時は[EMITTER][OVERRIDE] Pressure Iterationsの値が[EMITTER][OVERRIDE]Particle Per Cellにセットされます。

Falseの時は、元々[EMITTER][OVERRIDE]Particle Per Cellにあった値が[EMITTER][OVERRIDE]Particles Per Cellにセットされます。

これは[USER] Pressure Iterationsの値が[EMITTER][OVERRIDE]Particle Per Cellに使用されたと仮定しても問題ないでしょう。

Particle Per CellがEmitterのどこにセットされているのか確認します。

Particle Spawn Sectionにありました。

Parameter Write Sectionにもありました。

Simulationにあるやつは前から見ていたやつでした。

Parameter Read and Writeにあって

Grid 3D FLIP Tank Spawn SectionのParticle Per Cell

にもありました。

これまで追っていったら終わらなくなってしまうので止めますが、[USER] Pressure Iterationsの値が[EMITTER][OVERRIDE]Particle Per Cellになるという事は、[USER] Pressure Iterationsの値で一個のCell内のParticleの数を指定しているという事になります。

[USER] Pressure Iterationsの機能の一つが分かりました。

この後、Module内に[EMITTER] [OVERRIDE] Pressure Iterationsが出て来る事はありませんでした。

以下のSolve Pressure SectionにあるGeneric Simulation Stage Settingsには

Num IterationsというParameterがありますが、

その値は50で[EMITTER] [OVERRIDE] Pressure Iterationsの値とは違います。

あれ?

その下にあるNum Iteration Bindingに[EMITTER] [OVERRIDE] Pressure Iterationsがセットされています。

Pressure Iterationsで検索していますが、0件と表示されています。

うーん。

検索に表示されない箇所もあるのね。

Num Iteration Bindingを追ってみます。

Solve Pressure SectionにあるModuleを開いて実装を見たら、UE5Editorが固まって動かなくなりました。

何回やってもダメでした。

これを追うのは諦めます。

まあ、ここまでの調査でも[USER] Pressure Iterationsが単純にPressureのIterationの回数を指定しているのではない事は分かりました。

以下に分かった事をまとめておきます。

  • Cell内のParticleの数を決定する
  • PressureのIterationの回数を決定するのではなくPressureのIterationのBindingの回数を決定している

これだけ調べていてもしょうがないので次に行きます。

水の出て来る口の大きさを変更します。

Particle Spawn SectionのSphere Location Moduleの

Sphere Radiusの値を25にしました。

更にOffsetのXの値を-125にしました。

結果です。

水の出る位置が後ろにさがりました。

蛇口の口径も小さくなっているはずですが、これは見ただけでは分からないです。

次はShadingの調整です。

Render SectionにあるMesh Renderer Moduleを選択します。

あれ、TutorialのMeshと違います。

と思ったらこっちでした。

うーん。

これはEngine内のContentsなのでDuplicateしてそれを加工します。

しました。

名前はM_WaterSDF_Inst_meとしました。

更にその親MaterialであるM_WaterSDFもDuplicateしました。

名前はM_WaterSDF_meとしました。

M_WaterSDF_Inst_meのParentにM_WaterSDF_meを指定しました。

NSであるNS_Honeyに戻ります。

Emitter StackのRender SectionにあるMesh Renderer Moduleの以下の箇所に

先程作成したMaterial Instanceをセットします。

これでMaterial Instanceとその親Materialを自由に加工出来るようになりました。

先週は以下の様に書いていましたが、

私が今までやっていたやり方は

  1. MaterialをDuplicate
  2. そのDuplicateしたMaterialからInstanceを作成。
  3. そのInstanceのParameterを一個ずつ、元のMaterialのInstanceからCopy。

とやっていました。

このやり方だと3をやるのにとんでもない時間がかかります。

RenderBucket氏のやり方だとほぼ一瞬で終わります。

いや勉強になりました。

ではM_WaterSDF_Inst_meのParameterを弄っていきます。

まずBase Colorをdisableにします。

Base Colorは間違えて黒にしてしまいました。

まあ大丈夫でしょう。

ScatteringもDisableにします。

そしてAbsorptionの値を0にします。

水が透明になりました。

ここまではTutorialと同じです。

Absorptionに以下の値を代入しました。

以下の様になりました。

私のは完全な緑というより青緑です。

この色を赤くするためにAbsorptionに水色を指定します。

結果です。

あれ、真っ黒になってしまいました。

Tutorialの値と比較したらTutorialではRの値が0になっていました。

Rの値を0にします。

結果です。

赤くなりました。

次はOpacityの値を1にします。

黒くなりました。

Base ColorにCheckを入れました。

Base Colorが黒だと変化が分からないので水色に戻しました。

Base Colorを白くし、Opacityを0.5に下げます。

半透明になり少しだけ赤味がついています。

太陽に向かってこのEffectを見た場合です。

ほとんど半透明です。

太陽や後ろにあるActorが透けて見えます。

今度は太陽を背に向けてこのEffectを見ています。

僅かに透けて見える部分もありますが、ほとんど不透明です。

今度はScatteringを追加します。

太陽を背にした場合です。

全く変化が見られません。

今度は太陽に向かってNSを見ています。

これも全く変化が見られないです。

色が赤いからかと思い青などでも試しましたが全く変化しません。

ScatteringのAlphaの値を1.0に変更すると

太陽に向かっていても不透明で黄色になりました。

太陽を背にした場合は以下の様になりました。

完全に不透明ですが、黄色味があります。

Tutorialの値を見直したらAlphaには1が入っていました。

Tutorialの説明を聞いたら理解しました。

Scatteringがない状態です。

半透明になっています。

以下の条件でScatteringをEnableします。

以下の様になりました。

これはScatterされた光が放出されたからです。

太陽を背にした場合です。

こっちは僅かに黄色ですが、先程ほどではないです。

これはScatterされた光の大部分が前方に進んでいるためです。

色々試したんですがイマイチ理解出来ません。

Phaseも-1と1を変えてみましたが光源の向きによって大きな変化が見られる事は無かったです。

Toleranceです。

これは分かりました。

値を大きくするほど粒の大きさが大きくなります。

Toleranceが1の時です。

Toleranceが0.001の時です。

Scatteringの見方が分かりました。

太陽に向かった場合です。

黄色いです。

今度は太陽を背にします。

青いです。

これはScatteringする光が前方に放出されるからです。

Phaseを-1にしました。

今度は逆になります。

太陽を背にしている今は黄色になりました。

太陽に向かっている時が青くなります。

今度はHoneyを作成します。

Tutorial通りの値を代入しました。

太陽を背にした場合、以下の様になります。

こっち側から見るとクレヨンみたいな色しています。

Specularを追加します。

値は0.5にしました。

こんな感じです。

今度はRefractionを追加します。

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

結果です。

Refractionしているみたいです。

最後にRoughnessの値も追加しました。

これで完成したと思ったら疑似的にViscosityを追加するのを忘れていました。

Particle Update SectionにCollision Moduleを追加しました。

Collision ModuleをGrid 3D FLIP Integrate Particle Velocity Moduleより上に移動します。

Errorは直さずにDismiss Issueを押します。

こんな結果になっています。

Collision ModuleのKill Occluded ParticlesのCheckを外しました。

結果です。

ドロドロです。

Restitutionの値を0にしました。

結果です。

凄いドロドロになりました。

Emitter Summary SectionにあるSDF Particle Size Multの値を1.5にしました。

結果です。

粒が大きくなっているのは分かります。ハチミツらしいかと言われるとうーん。ってなります。

これで実装は完成しました。

3.2 Unreal Engine 5 Tutorial - Shading Niagara Fluids – Honey [7]を実装した感想

思っていたより分からない事が多かったです。

ただNiagara Fluid Systemを勉強し始めてまだTutorialを4つか5つしかやっていないので、まあこの位理解していたら十分かもしれません。

以下によく分からなかった事について書き残しておきます。

<太陽の向きに対してOpacityが変わるのはどのParameterなのか?>

最初はScatteringが太陽の向きに対してのOpacityを決定していると思っていたんですが、ScatteringのOpacityを0にしても太陽光を背にするとNSは不透明になります。

これParameterを一個ずつ外して確認したらどのParameterが犯人か分かるんですが、そうするとせっかく完成したHoneyの設定を壊さなければならなくなります。

なので今はやりません。

後でやります。

<Tolerance とSDF Particle Size Multの関係>

両方とも「Particleのサイズを変更する。」と紹介されていますが、それぞれの機能はどう違うんでしょうか?

<疑似的に粘性を出す方法について>

これCGHOW氏もやっていました。

2つのやり方を比較してどう違うのか検証したいです。

ここでは、

  • Collision Moduleを追加し
  • Collision ModuleのKill Occluded ParticlesのCheckを外し
  • Restitutionの値を0にし
  • 最後にEmitter Summary SectionにあるSDF Particle Size Multの値を5にしました。

これらのそれぞれの機能については先週のBlogで簡単にまとめてありますが、実際に確認した訳ではないです。

4.Materialの勉強

今週は兎に角、GIMPでRGBA Channelの使用方法を勉強して、使えるようにします。

4.1 GIMPでRGBA Channelの使用方法を勉強する

まずGIMPですが、Installしました。

が全く使い方は知りません。

何個かTutorialをみて分かったことは以下に示したChannelsを選ぶとRGBAのそれぞれのImageが別々に表示される事です。

もう一つ分かったのがColorsのComponentsからDecomposeを選択して

からRGBAを選択して

以下の様にRGBAでLayerを分割します。

T_FreshWindsweptSnow_uhpjdeyn_4K_ORDpを開きました。

以下にT_FreshWindsweptSnow_uhpjdeyn_4K_ORDp をUE5からTexture Editorで開いたImageを示します。

Rです。

RはAmbient Occlusionです。

GIMPのRedのImageです。

どうなんでしょう。

一寸薄い感じがします。

UEから見たGのImageです。

Roughnessを示しているはずです。

しかし何もない感じです。

GIMPの方のGです。

正直差があるのか分からないです。

最後のBです。

UEで見たImageです。

BにはDisplacementが入っています。

GIMPで見たBのImageです。

全く同じかどうかは不明です。

ぱっと見は同じに見えます。

これだけしか知りません。

Googleで検索しても出て来ません。

こうなったらChat GPTでも試してみるか。と思ったんですが、Chat GPT全く弄った事が無いので、さすがに躊躇しました。Chat GPTは一寸遊んだりしてから試す事にします。

Googleでひたすら検索したらStack OverflowのGIMP packing image into alpha (pasting grey scale image into alpha) [8]が見つかりました。

これを試してみます。

まずAmbient OcclusionのGray ImageをNormal MapのBに入れ、RoughnessのGray ImageをNormal MapのAlphaに入れてみます。

色々試したら出来たみたいです。

以下にやり方をまとめます。

まずGIMPを開きます。

GIMPはこんな画面をしています。

当然ですが、Normal MapとORDpのImage をここに開きます。

やり方はFileからOpenで開くFileを選択するだけです。

こんなの当たり前だと思いますが、Openだけでもこんだけあります。

念のために記録しておきます。

ImageがGIMP上で開かれると以下の様にそのImageが表示されます。

まずNormal Mapを選択します。

そしてColorsからComponentsを選択してDecompose…を選択します。

以下のBoxが表示されるのでColor ModeにRGBかRGBAを選択してOKを押します。

すると以下に示した様に新しいImage Fileが作成されます。

そのImage Fileですが、以下に示した様にNormal MapのRed Green Blue AlphaがLayerとして別々に表示されています。

当然、それぞれのLayerはGray Scaleになっています。

同様の事をORDpのImage Fileにも行います。

ORDpのRGBAが別々のLayerになったImage Fileが作成されました。

このRed ChannelにAmbient OcclusionのImage、Green ChannelにRoughnessのImageが入っています。

これをCopyして先程作成したNormal MapのRGBAがバラバラのLayerになったImage Fileに新しいLayerとしてPasteします。(毎回バラバラになったNormal Mapと呼ぶのは大変なのでNormal Map Separatedと呼ぶ事にします。)

まずNormal Map SeparatedにあるBlueとAlphaのlayerは要らないので消します。

やり方は、Layerを右Clickして以下のBoxを表示、

Delete Layerを選択します。

消えました。

今度は別のImageからLayerをCopyして新しいLayerとしてこのImageに追加します。

ORDp SeparatedのRed Layerを選択して

EditからCopyを選択します。

これでこのLayerはCopyされました。

そしてNormal Map Separatedに戻り、Editを選択、Paste AsからNew Layerを選びます。

すると以下に示した様にCopyしたLayerがRed CopyとしてこのImageに追加されました。

ここでこのLayerの名前がRed Copyのままだと後で混乱してしまうので名前の変更をします。

やり方ですが、Layerを右Clickして以下のBoxを示します。

Edit Layer Attributeを選択し、以下のBoxを表示します。

Layer Nameの所に新しい名前を書きます。

Blue ChannelにAmbient Occlusionが入るのでBlueとしました。

同様の方法でRoughnessのImageをAlphaとして追加しました。

今度はこれらのLayerをRGBA Channelに配置して一つのImageにします。

ColorsからComponentsを選択しCompose…を選択します。

すると以下のBoxにRGBAに対応するLayerを聞いてくるBoxが開くのでそれぞれのLayerを指定します。

OKを押すと以下に示した様にこれらのLayerをRGBAにまとめた新しいImageが作成されます。

今度はこのImageをPngでSaveします。

FileからExport asを選択します。

これが結構なひっかけでいくらSave Asを選択してもPngでSaveは出来ないという。初心者泣かせなUIになっています。

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

どこでPngを選択するのかと言うと、一番下にあるSelect File Type(By Extension)をClickします。

すると以下のImageが表示されるのでPNG Imageを選択します。

Exportを押すと以下のImageが表示されます。

これの条件はよく分かりません。

Exportを押します。

これでPngとしてExportされました。

UE5からこのImageをImportします。

すると以下に示した様に、このImage、Normal MapとしてImportしたけど良いですか?と聞いてきます。

良いわけ無いです。

Revertを選択して元に戻させます。

Text Editorで開きます。

こんなImageでした。

RGBAすべてのChannelにImageが入っています。

BlueのImageです。

AlphaのImageです。

はい、出来ました。

<4kを1kに縮小する>

ImageからScale Imageを選択します。

以下のBoxが表示されるので1kのPixelを指定します。

それだけした。

<4kのImageの内一部を切り取り512 x 512の別のImage Fileとして保存>

よく考えたら全部GIMPでやる必要はなくてMedi Bangで出来る事は今まで通りMedi Bangでやればいいのでこれを調べるのは止めます。

これでBen Cloward先生のAdvanced MaterialのTutorialを勉強するために必要なTextureの作成が出来るはずです。

4.2 Rock Shader - Advanced Materials - Episode 3 [9]Sparkling Snow Shader - Advanced Materials - Episode 2 [10]のTextureを作り直す

これは来週やります。

今週は慣れないGIMPの勉強なんかしたせいで、もう疲れてしまいました。

GIMPは嘘の情報が多いですね。

Layerの名前の変更を調べていたら、最初に出てきたSiteの解答が、GIMPではそれは出来ない。でした。

僅か2分間の更なる調査で、GIMPのLayerの名前の変更方法は分かりました。

UEならこういう間違った情報が書いてあるサイトは、決してお勧めの最初には出て来ません。

こういうのが疲れを増加させるんです。

GIMPにはTextureをSeamlessで作成する方法があるみたいです。

これがどの程度のSeamlessなのか試してみたいです。時間がある時に勉強する事にします。

後、Chat GPTを使用してGIMPの勉強をしてみたいです。今度はそれをやります。

以上です。

4.3 Chat GPTで質問してみました

Chat GPTの使用方法が判明したので、試しにChat GPTで質問してみました。

凄い。

Googleの検索で2時間以上かけて調べた内容が一瞬で出て来ました。

確かに世界中で話題をさらっているだけあります。

これはGoogleの検索に対しての強力な競争相手になりそうです。

ただ個人の感想ですが、YouTubeのTutorialを駆逐出来るとは思いません。

例えば以下の解答ですが、

質問者がこの解答を正しく実行するためにはImageとDecomposeがTool BarやMenu Barのどこにあるのかを知っている必要があります。

これって結構初心者にはLevelの高い要求です。

ところが、YouTubeの動画ならそう言う名称を全く知らなくても映像を追う事で理解出来ます。

のでYouTubeの映像で理解出来るTutorialが完全に無くなる自体にはならないと思います。

5.戦闘システムの続きを作成する

今週から召喚したMonsterにAnimationを追加する作業を開始します。

5.1 SkeletonCrew(ゾンビタイプ)のMonsterのAnimationを追加する

これが一番簡単そうなのでこれからやります。

後、先週、Levelと雲を改良したProjectではなく、元からAnimationのPackが追加されているProjectであるCombat Prototypeでテストします。

今、Animationが追加されている以下のMageがどうやってAnimationが発動されているかを調べます。

なんとこれだけでした。

という事はMonsterを召喚する時に、それぞれのMonsterに合ったAnimをAnim to Playにセットすれば良いだけみたいです。

Monsterの召喚方法を確認します。

Level BPに以下の関数がありました。

中身を調べます。

以下のNodeでMonster BPを生成しています。

Monster BPを調べます。

Monster BPにはMeshがComponentとして追加されていますが、

どのMeshを追加するかを決定するための実装とかは無かったです。

もう一回、Level BPを見ます。

ありました。ここで配置するMonsterのMeshを指定しています。

つまりこの後で、MonsterのMeshに合ったAnimをAnim to Playに指定すれば良いわけです。

取りあえず以下のAnimationに変更出来るのか試してみます。

一番、最初に出て来る妖精タイプのMonsterのAnimationを追加します。

と思ったら妖精タイプのMonsterにArcherなんていなかったです。

以下のMonsterはHalberdierと書かれていました。

Halberdierって何?

と調べたら

Halberdと言う武器を持っている人と言う意味でした。

Halberdってどんな武器と調べたら以下に示したような槍に斧が合体したような武器でした。

ふーん。です。

でこいつのAnimationがありません。

装備が似ている以下のAnimationを使用する事にしました。

出来ました。

これでTestします。

MonsterのPoseが変わっています。

出来ています。

うーん。

こんなに簡単だったの。

もっと早くやっておけばよかった。

以下のような関数を作成してそれぞれのMonsterに合ったAnimationを追加します。

実装部です。

何と以下のMonsterには付属のAnimationがない事が分かりました。

これは後で変更します。

付属のAnimationがあるMonsterには全部Idleを使用しました。

テストして確認します。

亡霊族のMonsterにはAnimationが追加されていないので表示されていません。

ここで問題発覚です。

MonsterはPoseは変更されていますが、Animationは追加されていません。静止しています。

Monster BPの設定を以下の様に変えてみました。

すると以下に示した様にAnimationが発動しました。

このScreenshotではよく分かりませんが、Animationが発動しています。

Monster BPを作成する時にAnimationを指定する必要があるという事みたいです。

はい。

ではMonster BPの実装を変更します。

Monster BPにSkeletal MeshをPass出来るようにして

そのMeshをMonster BP内でセットしました。

まずはこれでMonster BPを呼び出した時にそれぞれのMonsterのSkeletal Meshで召喚されるのかを確認します。

当然、Level BPにあるMonster BPのSkeletal Meshを変更していた実装は外します。

テストします。

普通にそれぞれのMonsterが召喚されました。

ここで詰まりました。

ConstructorからAnim to Playの設定を変える方法がありません。

Event GraphからAnim to Playの設定をSet Animationノードを使用して変えると

Monsterは止まって動かなくなります。

Set AnimationじゃなくてPlay Animationにしたら直りました。

普通に動いていました。

うーん。

という事は別にMonster BPじゃなくても良かった?

全部Codeを元に戻しました。

そしてSet Anim For Monster関数の実装を

Set AnimationからPlay Animationに変更しました。

テストします。

普通に動いています。

ぬぐ。

Play AnimationノードとSet Animationノードを間違えただけでこんなに時間を浪費してしまいました。

ぬぐ。

一応、他のMonsterのAnimationも確認します。

ゾンビタイプのMonsterのAnimationも普通に動いていました。

ドラゴンも普通に動いていました。

うーん。

一応これでAnimationの追加は完成です。

5.2 亡霊族のMonsterの代わりを探す

亡霊族のMonsterに使用していたCityofBrass_EnemiesのSkeletal MeshにAnimationがない事が判明しました。

AnimationがないMeshはGameには使用出来ないのでAssetから別のMonsterを探します。

こんなのがありました。

Downloadして中身を見ました。

以下の3つは使えそうです。

この3つを代わりのMonsterにする事にします。

これ以上2つのProjectで別々な作業をしているとMergeする時に面倒になります。

新しいProjectにAssetを足して、新しいProjectで作成する事にします。

うーん。新しいProjectのAssetを足す事が出来ません。

となると先週作成したLevelと雲を古いProjectで作成し直す必要があります。

うーん。

作り直しますか。

5.3 先週やったLevelの改良をCombat Proto Typeで作成する

もう一回Levelの改造を行います。

Multi-Story Dungeonを追加します。

こんな感じにしました。

空も作り直します。

今ある空関連のActorは全部消します。

新しく以下のActorを追加しました。

こんな感じです。

取りあえずはこれでOKにします。

5.4 AnimationのないMonsterを交換する

はい。

これは

以下に示したSK_Lichと交換します。

亡霊剣士の代わりは

以下に示したSK_Skeletonにします。

最後の亡霊魔人の代わりは

SK_Ghoulにします。

なのでMonster Data Tableを書き換えます。

以下の様にMeshだけ取りあえず変更しました。

これらのMeshのAminationを追加します。

亡霊族のAnimationをLevel BPのPlay Animation Nodeにセットしました。

テストします。

向きがオカシイですし、Sizeも小さいです。

直します。

Combat Level BPのSpawn Monster()関数の以下に示した部分の値を変更しました。

結果です。

今度は前は向くようになりましたが、Sizeは小さいです。

以下の様に変更してSizeを1.5倍にしました。

結果です。

Size的にも丁度いいです。

5.5 攻撃時のAnimationを追加する

Level BPにあるMonster Attack()関数の

実装に新たに作成したAttack Animation()関数を追加しました。

Attack Animation()関数では妖精族の攻撃Animationだけ実装してTestします。

結果です。

普通に攻撃はしました。

しましたがその後のIdlingのAnimationは止まってしまいました。

直します。

以下の実装をLevel BP上に追加しました。

攻撃のAnimationの長さが2秒間位と仮定して2秒経ったらIdlingのAnimationを開始します。

結果です。

攻撃が終わった後もIdlingしています。

うーん。

出来ています。

しかし攻撃の時間を2秒間と指定してしまったのでこれが不安要素ではあります。

PCによってFrame Per Secondがどう変わるのかが不明だからです。もし設定で初めからFrame Rateを固定出来てしまえば、このやり方でも問題は無くなります。

これは後で考えます。

今週はAnimationを追加する所までやります。

Attack Animation()関数のすべてのMonsterの攻撃Animationをセットしました。

今度はLevel BPにあるすべてのMonster Attack()関数の後にDelayノードとSet Anim for Moster()関数を追加します。

出来ました。

テストします。

ドラゴン族の攻撃です。

なんか可愛い攻撃です。

Idleが効いていないMonsterがありました。

直します。

直りました。

ゾンビタイプの攻撃もきちんと動いていました。

ゾンビタイプの弓士は弓を持っていません。後で弓を追加するかMonsterを交換する必要があります。

5.6 攻撃を受けた時Animationを追加する

今度はMonsterが攻撃を受けた時のAnimationを追加します。

まずDamage Animation()関数を作成します。

全てのMonsterのDamageを受けた時のAnimationが設定されています。

攻撃のAnimationの実装と全く同じやり方で以下の様にしました。

出来ました。

テストします。

全部綺麗に動きました。

攻撃と攻撃を受けるAnimationのおかげでどのMonsterがどのMonsterと戦っているのか一目瞭然になりました。

亡霊族との対戦です。

亡霊族の攻撃を受けた時のAnimationは小さくてあんまり攻撃が効いてないように見えます。

Animationを変えるか、別なAssetを使用するか後で検討する事にします。

ゾンビ族との対戦です。

左端のゾンビの攻撃が凄すぎます。これだけ3倍位のDamageを与えても良い感じです。

ゾンビ族の攻撃を受けた時のAnimationははっきりしていて見ていて楽しいです。

ドラゴン族との対戦です。

ドラゴンはもっと大きくても良いかもしれません。

特にBugもなく全部綺麗に動きました。

5.7 魔術師のAnimationを追加する

今度は魔術師のAnimationを追加します。

出来ました。

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

魔術師がMonsterを召喚する時に魔法を使用する動きをします。

更に、Playerが操作する魔術師は、戦闘前に魔法を使用するたびにこの動作を行います。

Testします。

Playerが操作する魔術師がMonsterを召喚した時です。

Screenshotを取ったのが動作が終わった瞬間でした。

正常に動いているのは確認出来ました。

今度は対戦相手の魔術師がMonsterを召喚する時です。

指定した動作を行っていました。

さらに動作を終えた後はIdlingのAnimationに戻りました。

正常に作動しています。

Playerが操作する魔術師が戦闘前に魔法を使用した時です。

これもScreenshotは取れませんでしたが、正常に動いていました。

勿論、動作を終了した後なIdlingのAnimationが発動しました。

全部正常に動いています。

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

5.8 Animationを追加した感想など

久しぶりにUEのAnimationについて触ったのと、単なるMonsterのAnimationの作成なのでかなり行き当たりばったりで作成してしまいました。

せめてAnimation BPぐらいは使用すべきでした。

今年の目標は兎に角Gameを完成させる事なので、どうやってCodeを書くのかはあまり気にしない事にします。

これでもMonsterが動きます。

それが一番大切です。

5.9 これから直す事

最後にこのGameを自分でPlayしていて直すべき3つの点に気が付きました。

それをここに記録しておきます。

<順番がオカシイ>

まず

が表示され、

魔術師のAnimationが発動し、

最後に

UIが変化すべきです。

今の順番は、

  1. UIの値が変化
  2. Dialogueのセリフが表示
  3. Animationが発動

になっています。

<セリフが足りない>

以下のDialogueが表示された後、

「右翼のMonsterのHPが回復した。」

というDialogueがあるべきです。

<Monsterが死んだときのAnimationがない>

HPが0になったMonsterも普通に立っています。

死んだAnimationを追加して倒されたことが分かるようにすべきです。

これらは来週以降直す事にします。

6.Gaeaの勉強

先週の続きからやっていきます。

6.1 Gaea Tutorial for Beginners #1 | Intro to the series & Analyzing the Interface [2]と先週、自分でまとめたUIの使用方法を比較するの続きをやる

先週のBlogのGaeaの勉強の最後に以下の部分は来週勉強するとありました。

Import GraphはExportしたGraphをImportするだけのはずです。

Import SeedはImport する前にExportする必要がありその方法が分かりません。

Show Graph Toolbarは以下にしめしたIcon群の事です。

次のShow Nodes in Context MenuにCheckを入れると、Node Graph上で右Clickした時に表示されるBoxが

から

になります。

全てのNodeがここからも選べるようになるだけです。

Show Grideは以下に示した様にNode Graph内にGridを表示します。

残りのGridとItemはどんな機能なのか不明です。

今度はTutorialの説明を確認します。

これ見ると今のVersionと全く違いますね。

まず、最初のShow 2D Viewですが、これは今のVersionのこれですね。

次のShow/Hide Girdは先程見たShow Gridです。

Snap to GridとSnap to Itemは今のVersionのGridとItemと同じでしょう。

ただこれらの機能がよく分からないです。

Take Screenshot of the Viewportですが、今のVersionでは右下にあるIcon群のScreenshotを右Clickすると

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

ここでSave to Screenshotsを選択するとViewportのScreenshotが取れます。

Open Screenshots Folderを開くと撮影したViewportのScreenshotが保存されているFolderが開きます。

別なFolderに保存したい場合は、Browse for Filename...を選択します。

好きなFolderに保存できます。

Node GraphのScreenshotが取りたい場合は、Graph Screenshotを選択します。

これらの機能はScreenshotを取る事に関しては、Snipping Toolの劣化互換でScreenshotを取るならSnipp Toolを使用すべきです。

以上です。

<Settings>

それではTutorialのSettingsを見ていきます。

PropertiesとBuildの説明をするのかと思ったら、何故かViewportの右上のIconの説明をしています。

左端のIconをClickすると以下のBoxが表示されます。

これは今のVersionにおけるこれです。

なんとこの太陽みたいな絵のIcon、Viewport Settingsと言うそうです。

だからこの章の名前がSettingsだったのか。

謎が解けました。

TutorialではAdvanceの機能についても紹介しています。

今のVersionにあるAdvanceの機能です。

Sun IntensityとAmbient Intensityは同じですね。

Exposureが無くなった代わりに、色々新たなParameterがありますね。

TutorialにはWater と言う項目があってWater Levelを自由に指定できます。

こんな感じです。

これは便利な機能ですね。

今のVersionにはこの機能はないですね。

次はBuild buttonについて紹介しています。

ただし、機能については後で解説すると言って終わりでした。

その次のX Buttonです。

これはGaeaが何かの計算を開始してずっとそれをやっている時にCancelするためのものだそうです。

Tutorialでは新しいNodeを繋げた場合を例にして解説していました。

新しいNodeを繋げたらGaeaがずっと計算していて結果が表示されない。もうこのNodeを使用するのは止めたい。となった時にこのButtonを押すそうです。

今のVersionでは以下に示した右下にあるIcon群の内、赤丸で囲ったやつがこれと同じ機能だったはずです。

ただし多分そうだという位です。

この機能を必要とするほどGaeaが長く計算している事態に、まだ遭遇した事がないので、試した事がないです。

Tutorialで使用しているGaeaのViewportの右上のあるIconの一番右端にあるIconです。

これはEngineの機能をSuspendするそうで、これを押すと、ViewportのImageはこの後に追加したNodeに影響されません。

このIconは今のVersionにはありません。

以下に示したPinをNodeに追加すれば同様の事が再現出来るはずです。

Tutorialでは今度は左下にあるIconについて解説しています。

このGraphを右Clickすると

GaeaをGraphで使用するのかLayerで使用するのか選択できます。

今のVersionのGaeaにはそもそもLayerによる操作が出来ないのでこの機能はありません。

これで終わりでした。

うーん。想像していた内容とは全然違った。

6.2 Gaea Tutorial for Beginners #1 | Intro to the series & Analyzing the Interface [2]のUIの説明と今のUIの自分の解説を比較した感想

自分の知らない機能の紹介がかなりありました。

その半分は今のVersionにはない機能でしたが、残り半分は今のVersionにもあるが、どういう機能だったのか知らなかったものです。

まあ、でも今のVersionのGaeaの機能については大体は説明出来るようになりました。

後はそれぞれのNodeの機能についてと、そのNodeの組み合わせの方法、そして以下に示したNodeを選択すると必ず表示される以下のButton群の使用方法について詳しくなるだけです。

6.3 Gaea Tutorial for Beginners #2 | Node Graph Workflow [11]を勉強する

それでは次のTutorialを勉強する事にします。

このTutorialは前に一回勉強しているのでそれの確認からします。

2022-11-14のBlog

以下の様に書かれていました。

マジか!

じゃあ、今の私のやりたい事にピッタリじゃないですか。

以下の様に勉強する事にしました。

  1. このBlogを読んで前回の勉強内容を把握する。
  2. Tutorialを勉強してまとめる
  3. 実装を自分でする
  4. 今のVersionにあわせたTutorialを自分で作成する

2022-11-14のBlogではGaea Tutorial for Beginners #2 | Node Graph Workflow [11]の内容を簡単にまとめてあります。

以下に、その内容を更に簡単にまとめます。

<<INTRO>>

GaeaではNodeをつないでTerrainを作成する事を説明しています。

<<Toolbox>>

以下の内容が書かれていました。

  • Node GraphでTerrainを作成するための使用出来るすべてのNodeが、ここに載っている事、
  • Nodeは種類があってその種類毎にまとめられている事、
  • Node Graph内で右Clickする事でもこれらのNodeにAccess出来る事

<<Primitive>>

Nodeの種類の内の一つです。

最初のNodeは必ずPrimitiveから選ぶ事。TutorialのVersionのGaeaにはGeo Primitiveという種類がない事、MountainノードがGeo Primitiveに配置されている事などが述べられていました。

更に、Node Graph内の操作について以下の事がまとめられていました。

<<Parameters>>

NodeのParameterの解説をしています。

以下のIconの使用方法について解説しています。

次にNodeのInputとOutputについて解説しているみたいなんですが、なんか要領を得ません。

この部分は今回、Tutorialを見直す事で勉強し直します。

NodeのResetについて解説しています。

Presetとは以下に示した様に、Propertiesの脇にある三本線をClickした時に表示されるBoxにある

これの事です。

適切なParameterの値をセットしてくれます。

Presetなんてあるのすっかり忘れていました。

というか全く知らなかったです。

昔のBlogに、自分でも知らない事が書いてあるなんてどういう事何でしょう。

<<Connecting Nodes>>

NodeをGraph上に生成する方法について解説しているそうです。

ここで説明されている内容で、特に知らない事は無いです。

<<Randomizing Nodes>>

以下に示した様に、PrimitiveのNodeは2つ以上使用する事も可能だと説明されていました。

以上でした。

更にその後、このTutorialを勉強した感想がまとめられていました。

兎に角、勉強していてつまらなかったと書いています。

今、見直すとそんなにつまらなそうなTutorialには見えませんが、この時はそうだったみたいですね。

これだけ見ると今のVersionでもそんなに差がない機能ばかり勉強したみたいに見えます。

動画を見て確認しましょう。

Gaea Tutorial for Beginners #2 | Node Graph Workflow [11]をもう一回見る>

<<Intro>>

以下のNodeを例にしてNodeによるTerrainの作成がどのように行われているのかについて説明しています。

一つ一つのNodeがFunctionであると言っていますね。

NodeによるProgrammingをまったく行った事がない人にこの仕組みを説明するのはかなり難しいです。

私も考えてみました。

私なら以下の様に説明します。

GaeaのNodeによるTerrainの作成は以下の工程で行われます。

生成して改造する。

まず、Nodeには2種類あります。生成型と改造型です。

生成型は、何も無い空間に何かを作成します。

改造型はその生成された物を改造する事をします。自分で生成する事は出来ません。

この2つのタイプのNodeを組み合わせてTerrainを作成します。

まず生成型のNodeは以下の2つです。

改造するためには元の何かが必要ですので、最初のNodeは必ず生成型であるPrimitivesかGeo Primitivesから選ぶ必要があります。

Geo PrimitivesにあるMountainをNode Graphに配置してみました。

Viewportを見ると山のTerrainが生成されました。

他の生成型のNodeも試してみます。

Mountainノードを消してHillノードを配置してみました。

Terrainが以下の様に形成されました。

これらのNodeに今度は改造型のNodeを追加する事で、このTerrainの形状を改造します。

先程のMountainノードに改造型のノードであるSwirlを追加してみます。

結果です。

何と山がねじれてしまいました。

Swirlの意味は「ねじる。」ですので、山を文字通りねじった訳です。

どうでしょうか?

この説明分かりやすいと思います。

<<Toolbox>>

Toolboxの説明です。

ToolboxにあるNodeの種類について簡単に説明しています。

これらの種類の細かい説明は私も分かりません。

公式のSiteを見てみます。

Toolboxの使用方法やCustomize化についてしか説明が無かったです。

<<Primitives>>

MountainノードのParameterについても解説していますね。

後は、今までまとめた内容以上の事は言ってないです。

<<Parameters>>

この章はParametersとしてまとまっていますが、あんまりParameterについては語って無いです。

NodeのInputとOutputの数とか、Presetについての説明が主でした。

NodeのInputとOutputの数がここで解説される必要があるのかは不明です。

Presetは今のVersionでも同じ場所にありました。

<<Connecting Nodes>>

Tutorialを見直したら、それなりに大切な事を語っています。

前回のまとめはこの章の大切なPointを見逃しています。

この章はどうやって次のNodeを繋げるのか?と言う基礎的な内容について説明しています。

PrimitivesからNodeを一つ選んでNode Graphに配置した

次はどうしたら良いのか?

に対しての解答なんです。

以下に3つのNodeの繋げ方についてまとめます。

  • Tool Barから調達する。
  • Graph内で右Click
  • NodeのOutputを引っ張って離す。

後、以下のIconの機能について解説していました。

<<Randomizing Noise>>

全部見ましたが特に大切な事は教えてなかったです。

後、次のTutorialはLayerを使用したTerrainの作成だそうなので勉強する必要ないです。

6.4 Gaea Tutorial for Beginners #2 | Node Graph Workflow [11]を勉強した感想

Node Graphの使用方法やNodeのつなぎ方、Nodeを使ったTerrainの作成方法、Node Graph関連のIconの機能の説明はかなり勉強になりました。

後、Versionの違いによる機能の違いはほとんど無かったです。

Parameterの説明はほとんど無かったです。

Parameterの説明はほしいですね。

Parameterの理解を最もしやすいのはCombineノードだと思います。

私ならCombineノードを使用してParameterを理解します。

以下のようなNodeを組みます。

MountainノードだけならTerrainは以下の様になります。

Sandノードだけだと以下の様になります。

これをCombineノードで混合すると

となります。

でもこれ混合の方法によってはこうならない可能性もありますよね。

そうお絵かきソフトでBlendするとき、どんなBlendするかで絵の見た目が変わってくるじゃないですか。それと一緒です。

ではどうやってそのBlendする方法を変更するのでしょうか?

それを決定しているのが以下に示したCombine Propertiesです。

Methodを開くと

Blend以外にもいろいろな方法でCombineしてくれます。

試しにMaxを選択すると

値が高い方が選択されます。

こういう細かい条件を決定するのがParameterの役割になります。

こんな感じの説明でどうでしょうか?

7.Houdiniの勉強

Houdiniの勉強の続きをやっていきます。

今週もFOUNDATIONS | OVERVIEW [12]の続きを勉強していきます。

先週は3のView Toolsの途中まで勉強しました。その続きから勉強します。

7.1 View Toolsの続きから勉強する

<Space Bar + H>

以下に示したButtonを押して

Construction Gridを表示します。

この状態でSpace Bar + Hを押すとConstruction GridにFocusします。

うーん。以下の状態で試してみます。

先週やったように、以下に示した3つのObjectを配置します。

こんな感じです。

ここでSpace Bar + Gを使用してTommyにCameraをFocusします。

この状態でSpace Bar + Hを押します。

お、確かにCameraがConstruction GridにFocusしました。

今度はConstruction Gridを消します。

この状態で今度はSquabにFocusします。

Squabを選択してSpace Bar + Gを押します。

この状態でSpace Bar + Hを押します。

以下の様になりました。

Space Bar+ HはConstruction Gridが表示されていない状態だと、Space Bar + Aと同じ結果になるみたいです。

Construction Gridを表示しました。

この状態でもう一回、Space Bar + Hを押してみます。

今度はConstruction GridにFocusしました。

確認のためにもう一回同じことをしましたが、同じ結果になりました。

<その他のHot Key>

Viewport内で右Clickすると以下のBoxが表示されます。

ここでその他のHot Keyを知る事が出来るそうです。

TutorialではCamera ViewではこのBoxが表示される敢えてCamera Viewが選択されている事を強調されていますが、別のViewを選択した場合は違うBoxが表示されるんでしょうか?

試してみます。

Camera Viewを外して、その下のRendering Regionを選択して右Clickしました。

確かにBox内の表示が変わりました。

2を押すと

Top Viewになります。

3,4もそれぞれ違うViewを示します。1を押すと元に戻りました。

更に5を押すと、以下に示した様に

UVを示しました。

あ、0を試すのを忘れていました。

Load Previous Viewと表示され前のViewに戻りました。

6~9はLoad Quick Viewと表示されますが何を指しているのか不明です。

<Link Ortho View>

次にVを押して以下のUIを表示させ

Viewport Layoutを選択し、

以下のUIを表示させ、ここから望みのViewportを選択する方法も紹介されていました。

こういうやつです。

これは前に勉強しました。

2023-01-08のBlogで勉強していました。

というかHoudiniの勉強って始めてまだ3回目だったのか。

何かもう一年くらい勉強した気になっています。

Scene Viewの右上にあるViewportの枠と同じ形をしたIconをClickすると以下のBoxが表示されます。

TutorialではLink Ortho ViewsにCheckを入れてすべてのOrtho ViewのCameraの動きを統一しています。

自分で確認しましたが、確かに以下に示した3つのOrtho Viewの内の一つのCameraを弄ると他の2つも同じように動きます。

Perspective Viewは全く動きませんね。

<Space Bar + B>

以下に示したようにLayoutが複数に分かれているViewを

元のViewに戻します。

今まで以下のUIのSingle Viewを選択して戻していました。

2023-01-08のBlogでそれぞれのBoxの名称を以下の様に学びましたが

Scene Viewに関しては以下に示した様に

このBoxにある一つのTabの名称だけでした。

つまりこのBox全体の名称は無いって事です。

これからは、ここに表示されているすべてのTabを含めたこのBox全体を呼ぶ時はViewportと呼ぶ事にします。

<Tumble Tool>

まず先週の復習ですが、TumbleとはCameraが撮影する対象の周りを上下左右に回転して撮影する機能の事です。

このサイト[12]に分かりやすく解説されています。

この場合大切なのはどの対象物の周りをCameraが回るのかです。

TutorialによるとTumbleをするために左Clickをした瞬間に選択したObjectが対象物になるそうです。

もしObjectのない単なる空間で左ClickしてTumbleを開始した場合は前回、選択したObjectが対象物になるそうです。

うーん。

成程。

テストして確認します。

以下の状態でSquabを左ClickしてTumbleします。

もし選択してあるObjectを中心にTumbleするならTommyを中心にTumbleするはずです。

もし原点を中心にTumbleするならばCragの周りでTumbleするはずです。

そしてもしTutorialの説明通りなら、Squabの周りでTumbleするはずです。

Squabの周りでTumbleしました。

Tutorialの説明通りの結果になりました。

今度は何もない空間で左ClickしてTumbleしてみました。

この場合はその空間の場所を中心としてTumbleするのではなく前にTumbleの対象物として選択したObjectを中心としてTumbleしました。

これもTutorialの説明通りでした。

TutorialではこのTumbleする時の対象物をPivot Pointと呼んでいるので、これからはそう呼ぶようにします。

更に以下に示したIconを選択する事で今、選択されているPivot Pointを固定したままにする事も出来るそうです。

実際に試してみましたが、その通りでした。

ただCameraの位置をTumble以外の方法で動かすと、Keep Pivot on Tumble/Rotateにセットしておいても、よく分からない動きをする時もあります。

あんまり追及するとまた3D酔いするかもしれないので、この辺で止めておきますが。

<3D Camera>

今度は3D Cameraについてです。

以下のIconをClickしてCameraを追加します。

以下に示した様にCameraの配置された場所に青い円と赤い矢印が表示されます。

更にNetwork Pane内でもCameraのNodeが表示されます。

このCameraはObjectなのでこのCameraをPivot PointとしてTumbleする事も可能だそうです。

試してみます。

うーん。出来ない。

もう一回Tutorialを見直します。

分かりました。

Space Barを押して左ClickしてTumbleしています。

後、これCameraをPivot Pointにしているのかは不明です。

まず3D Cameraを配置したら、Scene ViewのViewの設定が以下に示したCameraのIconから

以下のIconに変わります。

このIconが選ばれている限り、Objectを掴んでTumbleする事は出来ません。

所がSpace Barを押すと、押している間だけ先程のCameraのIconが選択されます。

そしてその間はTumbleする事が可能になります。

ここのTutorialの説明はよく分からないです。

CameraがCameraにCameraしてみたいな説明でどのCameraがどのCameraを指しているのか全く分かりません。

しかしTutorialがやっているようにCameraを撮影するCameraをScene Viewに表示する事は出来ました。

いや、まだよく分かってないので断言は出来ません。

この今表示されているCameraは、先程追加したCameraを写している別のCameraだと思っていますが、違うかもしれません。

兎に角、Tutorialの画面と同じ画面になりました。

先程追加したCameraのNodeを選択すると

以下のCameraが選択されます。

となるとこのCameraは先程追加した3D Cameraになるみたいです。

うーん。複雑。

やっとTutorialの言っている意味が分かりました。

この3D Cameraを追加した時、Scene Viewの画像がその3D Cameraから見たViewに変わったんです。

それが、Tumbleをした事で、そのCameraから見たViewから外れてしまったんです。

だから追加した3D Camera自体を見る事が出来るようになったんです。

そしてこの事が理解出来ると、その次にTutorialが説明している事も理解できるようになります。

No Camを選択して以下に示したBoxを表示させ

Cam1を選択すると、Cam1から見たViewに戻るんです。

これがTutorialが説明している事だったんです。

これであっているはずです。

自分で試して確認します。

はい、その通りの結果になりました。

うーん。Houdiniの勉強が難しい理由が分かりました。

これ、一寸でも間違えて理解していたり、いい加減に澄ませていたりすると次で詰みます。

逆に私みたいに、納得できない箇所があるとチクチクと納得いくまで検証するタイプにはドンピシャのSoftかもしれません。

Tutorialでは、このViewの操作方法について解説しています。

以下に示した様に赤い矢印を移動させる事で撮影しているCamera(つまり先程追加した3D Cameraの事)の向きをControlできます。

この場合はCameraの位置は固定されたままです。

以下に示したLockのIconを押す事で

Cameraの見ている位置を固定してそのまわりをCameraが移動する事も出来ます。

試してみます。

うーん。

また出来ない。

いや以下に示した様に出来たんですが、

これCameraの位置関係ないです。

あ、そうでもなかった。

以下に示した様に実際にCameraが移動していました。

分かりました。

以下に示したLockのIconを使用した場合は、

TumbleするとCameraも移動します。

このLockを外した場合は、Cameraはその位置から動かないでViewだけ変化します。

成程ね。

理解しました。

今週のHoudiniの勉強はここまでにしておきます。

もう少し勉強出来る余禄はありますが、まああんまり無理しなくても良いでしょう。

量より質を高める勉強にしたいので余裕があるうちに終了します。

8.Volumetric Cloudの勉強内容をまとめる

今週やる事は2つです。

  • Volumetric Cloud関連で使用したParameterをまとめる
  • m_SimpleVolumetricCloudで使用されている2つのTextureを変更する事で雲の形状を自由に変更する事が出来る事を紹介する

先週やった内容をもう少し詳しく正確にまとめ直します。

8.1 Volumetric Cloud関連で使用したParameterをまとめる

先週、大体はまとめたんですが、戦闘システムとVolumetric Cloudで別々にまとめてしまったのでそれをここに一括してまとめ直します。

<Volumetric Cloud>

まずVolumetric CloudそのもののParameterです。

当たり前ですがこのActorのParameterは全てがVolumetric Cloudに関係しています。

しかし最初から全部を覚えようとすると、一個も覚えられないと言うParadoxに人は陥るので、このParameterの中で最も重要と考えられている以下の4つについてのみ紹介します。

Layerにある以下の2つのParameterについてと

Cloud MaterialにあるMaterial、

そしてCloud TracingにあるUser Per Sample Atmospheric Light Transmittance

です。

<<Layer Bottom Attitude >>

原点からの雲の底の高さを指定します。

原点からの距離を㎞で表しています。つまりDefaultでは原点から5㎞の箇所に雲の底があるという事です。

標準では0~20 kmの間の値を指定出来るようになっています。

0㎞を指定しています。

20kmを指定してみました。

直接、値を打ち込めばNegativeな値や20km以上の高さを入れる事も可能ですが、

-5kmの場合、

30kmの場合、

一般的な雲の位置からは大きく外れる事になります。

以下にTenki.jpの【十種雲形】雲は全部で10種類 見分け方を形や高さから解説!~下層雲編~ [13]で紹介されていた図を示しますが、

実際の雲の位置は地上から2km位で、最も高い位置にある雲でも10kmの位置です。

雲の種類と地面の高さにもよりますが、Layer Bottom Attitudeの値は2,5,そして10位が正しい値と覚えておくと良いです。

また雲の高さは日本だけ世界と違っているという事は無いです。

以下にBritanicaのCloud types [14]に載っていた雲の図を示しますが、

同じ形状の雲は大体同じ高さに位置しています。

<<Layer Height>>

雲の厚さを指定します。

Defaultでは10㎞になっています。

このVolumetric CloudはCumlonimbus、つまり積乱雲を再現しているので、この厚さが指定されています。

試しにこの値を変えてみましょう。

雲の厚さの変化が見やすいようにLayer Bottom Altitudeの値を0にします。

こんな感じです。

Layer Heightの値を1にします。

結果です。

雲がペッちゃんこになりました。

5kmです。

雲の厚みがかなり戻っています。

10kmより雲を厚くした場合、地上から見ても変化がよく分かりません。ので雲を真横から眺めたViewを示します。

Layer Heightが10kmの場合です。

20㎞にしました。

雲の厚みが倍になっているのが確認出来ると思います。

<<Material>>

ここは雲の形状や色などを指定するMaterialを指定しています。

指定されているMaterialを開くと

実際はMaterial Instanceが使用されています。

このMaterial InstanceのParameterを弄る事で、更にVolumetric Cloudに変化をつける事が出来ますが、それについては範囲外になるので今回は述べません。

一個だけ述べると以下の示した親Materialを開くと

以下に示したような実装になっています。

この辺についても今回は範囲外ですので解説はしません。

ただ、

  • Volumetric CloudにはMaterialが使用されている事。
  • それが雲の形状や色などを指定している事

だけ理解出来れば十分です。

<<Use per Sample Atmospheric Light Transmittance>>

これに関しては私もあんまり理解していません。

簡単に私が理解した範囲で説明すると以下の様になります。

Litの計算をする時に、ある値を使用します。通常はその値はすべてのSampleで同じ値を使用します。

ところでSampleによってその値を変更したら、LitがもっとRealになると思いませんか?

それを可能にしたのがこれです。

このParameterをEnableする事で、Litの計算をするのに、Sample毎に違う値を使用します。

Litに影響するParameterなので雲の後ろから光があたる状態で観察すると違いが分かります。

というか普通の状態では差はよく分かりません。

英語圏のTutorialで紹介されているParameterなのでここでも一応紹介しました。

以下に示したような夕焼けのSceneなどではかなりの違いが生じます。

Use per Sample Atmospheric Light Transmittanceを使用しない場合です。

Use per Sample Atmospheric Light Transmittanceを使用した場合です。

Use per Sample Atmospheric Light Transmittanceを使用した場合の方が雲の影が細かくなっており、よりはっきりと雲の形状を認識する事が出来ます。

ただ雲によっては白くなりすぎている気もします。

<Directional Light>

Volumetric Cloudに影響を与えるのは雲そのものだけではありません。その雲を照らすLightの設定もVolumetric Cloudに影響を与えます。

Directional LightではLight ShaftとAtmosphere and Cloudの項にあるParameterがVolumetric Cloudに関係しています。

<<Light Shaft>>

Light ShaftはGod Rayの事です。

God Rayって何?と言う人もいるかもしれないので以下に示します。

こういうやつです。

<<<Light Shaft Occlusion>>>

これはOcclusionを追加するんですが、変化が出る時と出ない時があってそれがどんな条件の時なのかよくわかっていません。

先週試した以下の例では

凄くはっきりと違うが確認出来たんですが、今週のLevelでは、

Light Shaft Occlusionなし

Light Shaft Occlusionあり

全く違いが出ませんでした。

<<<Light Shaft Bloom>>>

God RayにBloom効果を追加します。

これが

こうなりました。

この機能はGod RayにBloomを追加する事だと思うんですが、場所によってはGod Rayそのものも追加します。

これが

こうなります。

この2つのParameterはGod Rayが欲しい時に試しに入れてみる。ぐらいの使用法が良いのかもしれません。

<<Atmosphere and Cloud>>

当然ですが、ここのParameterは全部、雲に関係します。

今回はこの中でCast Cloud Shadowsだけ説明します。

<<<Cast Cloud Shadows>>>

雲の影を投影します。

これが

こうなります。

床に雲の影が投影されるようになったので夕焼けが見えづらくなってしまいました。

雲の影はAtmosphereにも投影されます。

これが

こうなります。

空が青くなっています。

暗くなっているのか明るくなっているのかがよく分からないんですが、兎に角Atmosphereにも雲の影が投影されるようになりました。

以下のParameterを変更する事で、雲が投影する影に更に細かい設定が出来るようになります。

これらのParameterは変化が有ったり無かったりです。

色々弄って確認して下さい。

<Skylight>

Skylightで使用するのはAtmosphere and Cloud にあるCloud Ambient Occlusionだけです。

<<Atmosphere and Cloud>>

<<<Cloud Ambient Occlusion>>>

雲にAmbient Occlusionを追加します。

無い時です。

ある時です。

空全体が微妙に青くなります。

何と言うか、水色だったところが濃い青になるという感じです。

このParameterは夕焼けとかの時は変化が全く分からないです。

無い時です。

ある時です。

全く違いが分かりません。

以上です。

8.2 ここ(8.1)で紹介したParameterを使用してVolumetric Cloudを改良する

以下の状態から8.1で紹介したParameterを使用して雲をもっとRealな感じにします。

がこんなになりました。

うーん。

あんまり変っていませんね。

8.3 m_SimpleVolumetricCloudの改良

先週のTextureはかなり現実離れした形状だったので今週は、実際の雲を真似て作成してみます。

こんな雲を作成してみました。

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

斜め横から見た図です。

使用したTextureです。

CouldのXYを指定するためのTextureです。

CloudのZを指定するためのTextureです。

この後、色々試したんですが、適当にやったんでは適切なTextureは作成出来ませんでした。

HoudiniのようにNodeベースでTextureが作成出来るSoftが必要です。

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

9.DirectXの勉強

今週もいつも通りに勉強していきます。

9.1 C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [15]を勉強する

今週はC++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [15]のPrecompiled Headerを勉強します。

まず軽く見て何をしているのかを理解します。

分かりました。

Compileにかかる時間をなるだけ少なくするために、Windows.hなどの絶対にCodeが変更される事のないFileを先にCompileしておきます。

それによってCompileする時間が短くなります。

Visual StudioC++にはそれを行う機能が予め備わっており、その名前がPrecompiled Headerでした。

Precompiled Headerを使用するためには、まずそれを作成する必要があります。

まずそのためのFolderを作成します。

以下に示したSwitch Viewを押して

Folder Viewを選択します。

そして以下に示した様にSource Folderにpch.hを追加します。

C++のCodeを見てるとたまに、pch.hと言う名前のHeaderがありますが、それってこれの事だったんですね。

納得。

更にpch.cppも追加します。

又Switch viewを押してSolution画面に戻ります。

Sourceに新しいFolderを追加してpchと名付けます。

そしてそのFolderに先程作成したpch.hとpch.cppを追加します。

まずpch.cppにpch.hのHeaderを追加します。

そしてpch.hには#Pragma onceを追加します。

この2つのFileをSolutionに追加します。

Projectを右Clickして以下のBoxを開き

Propertiesを開きます。

C/C++のPrecompile Headerを選択します。

設定を以下の様に変更します。

ConfigurationがAll Configurationである事を確認し、Applyを押します。

これで、pch.hにPrecompileしたいFileを書き込む事でそのFileをPrecompileする事が出来るそうです。

Window.hをIncludeしました。

うーん。

成程。

こうやってPrecompileするんですね。

勉強になります。

最後にWinMain.cppを開きWindow.hをIncludeから消して代わりにpch.hを追加します。

更にpch.h fileに置き換えるのはHeader Fileだけじゃなくて以下に示したMacroもです。

WinMain.cppから消して、

以下に示した様にpch.hにPasteします。

以下の示した様にこのような書き方に代えてもErrorは発生しません。

Compileしてテストしています。

最初のCompileは少し時間が掛かりますが、次からは早くCompile出来るようになるそうです。

以上でした。

9.2 C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [15]のPrecompile Headerを実装する

また一つ賢くなってしまった。

今週はPrecompile Headerについて勉強しました。

早速自分で実装してみます。

Visual StudioからOlympus Engineを開きました。

Switch Viewを押して画面を以下のものに切り替えます。

Folder Viewを選択します。

Source Folderにpch.hとpch.cppを追加します。

しました。

そしたら又Switch Viewを押して以下の画面に切り替えて

今度はOlympusEngine.slnに戻ります。

そしてSource Folderに新しいFolder、pchを追加します。

無、Filterとなっています。

今までずっとFolderと思っていたんですが、Filterだったのかな?

一応Tutorialで確認します。

TutorialでもFilterを選択していました。

Filterを追加しました。名前もpchに変更しました。

このFilterに先程作成したpch.hとpch.cppを追加します。

あれExisting ItemにWinMain.cppが無いです。

Tutorialを見るとこんな感じであります。

む。

何か忘れているのか?

Tutorialを見直します。

特に何もしてなかったです。

あ、分かりました。

Existing Itemで開かれたFolderが去年のOlympusEngine.slnのFolderでした。これをCopyして今年のFolderに移動させたんですが、VSの設定がそのままだったからなのか去年のOlympusEngine.slnのFolderを開いていました。

今のOlympusEngine.slnのFolderにAccessしたら以下に示した様にpch.hとpch.cppがありました。

追加出来ました。

pch.cppにpch.hのHeaderを追加します。

そしてpch.hには#Pragma onceを追加します。

これらのpch fileをSolutionに追加します。

SolutionのPropertiesを開いたら

全然違うBoxが出て来ました。

ProjectのPropertyでした。

以下の様に設定を変更します。

Pch.hにWindow.hをIncludeしました。

Window.hじゃなくてwindows.hでした。

今度はWinMain.cppを開きWindow.hをIncludeから消して代わりにpch.hを追加しました。

更にWinMain.cppにあるMacroをpch.hに移します。

WinMain.cppに表示されたErrorも消えました。

これで完成みたいです。

テストします。

Errorになりました。

うーん。

色々調べて、公式のサイトとかも読んだりしたんですが、原因がよく分かりません。

Precompile Headerのやり方はあっているはずです。

しかもこのErrorはCompiler Error C2857 []によるとPrecompileに指定したHeaderをIncludeしていない時に発せられるErrorとあります。

全部のSource FileでInclude しています。

あ。

File名を間違えていました。

直しました。

今度は出来ました。

はい。

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

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

先週は、「3.2.1ウィンドウの生成」の最後まで勉強しました。

今週は「3.2.2 Direct3Dの初期化」を勉強します。

まず軽く全部読みます。

おお、遂にDirectX 3Dを使用しています。

DirectX 12を使用するために必要なHeaderやLibraryの追加と、DirectX 12を使用するために最初に初期化する必要があるID3D12Deviceの初期化の方法について解説していました。

以下に具体的な内容を簡単にまとめます。

Includeする必要があるHeaderは以下の2つだそうです。

  • D3d12.h
  • dxgi1_6.h

そしてこれらのHeaderがあるLibraryが以下の2つだそうです。

  • d3d12.lib
  • dxgi.lib

dxgiのlibraryにはVersionの番号は無いんですね。

次にID3D12Device型の変数を含む3つの変数を宣言しています。

その後でD3D12CreateDevice()関数を使用してID3D12Deviceの初期化を行っています。

大体こんな感じです。

それでは実際にやってみましょう。

まずHeaderとLibraryをIncludeしました。

使用するLibraryはPropertyからも指定出来たはずです。

まあ良いです。

今回はこれで行きます。

次にID3D12Device型の変数を宣言します。

しました。

何故かIDXGIFactory6型とIDXGISwapChain4型の変数も同時に宣言しています。

IDGISwapChain4は本ではIDGISwapchain4と記載されていました。本ではCが小文字になっていました。

ここからD3D12CreateDevice()関数の話になります。

D3D12CreateDevice()関数に使用されているParameterについて説明しています。

読んだんですがあんまり頭に入って来ません。初めて聞く概念はなかなか理解出来ないのと一緒です。

そこで公式のD3D12CreateDevice function (d3d12.h) [17]を読むことにします。

うーん。

これ読むとID3D12DeviceってDirectX 12を総括しているClassではなくて単にDisplay Adapterを再現しているClassって感じです。

Display Adapterって何だっけ?

はい。これ去年、買ったやつじゃないですか。

これをSoft上で再現するのがID3D12Deviceなのか?
それぞれのParameterについての解説です。

そもそもD3D12CreateDevice()関数のParameterは以下の様になっています。

最初のIUnknown *pAdapterですが、

と解説されていました。

うーん。

これが「DirectX 12の魔導書」だとVideo Cardを選択するためのParameterと解説されています。

うーん。

あ。

さっきのDisplay Adapterの定義に

ビデオカードなどの映像信号の出力装置ってのがありました。

こっちか。

成程。

このParameterが何をするためのParameterか理解出来ました。

2番目のParameterです。

そもそもD3D_FEATURE_LEVELが何を指定しているのかが不明です。

公式のDirect3D feature levels [18]を詠むことにします。

はい。

大体のImageが掴めました。簡単に言うとFeature Levelという基準があってそのVideo CardがどのFeature Levelまで動く事が出来るのかは決まっているって事です。

それをここで指定しているという事ですね。

DirectX 12の魔導書」だとD3D_FEATURE_LEVEL_12_1が最新と書かれていますが、

今は12_2があるみたいですね。

3番目のParameterです。

Device InterfaceつまりVideo Cardが持つ番号でその機体特有の番号が返ってくるのか、それともこっちでこのParameterにそのInterfaceだけが持つ番号を指定するのかのどっちなのかが分かりません。

更に「DirectX 12の魔導書」の説明だと、受け取りたいObjectの型を識別するためID。となっています。更に訳が分からなくなりました。

兎に角、IDが入っている事だけは分かりました。

最後のParameterです。

ここは分かります。さっき作成したID3D12Device型の変数をパスする所でしょう。

あれ?

全然違う事が書かれている。

DirectX 12の魔導書」を見直したら、ID3D12Device型の変数をPassしているのは三番目のParameterでした。このParameterは使ってなかったです。

しかもそれぞれのParameterの値を指定するのに、もうひと手間必要みたいです。

もうお腹いっぱいです。

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

9.4 HLSLシェーダーの魔導書を勉強する

ID3D12Device型の変数の宣言をどうやっているのか、とD3D12CreateDevice()関数の説明をどうしているのかを重点的に見てみます。

ぱっと見ましたが、これらの説明はなくいきなりShader言語の勉強に入っています。

これはこれで有りですが、他の本と同じPaceで進みたいのでこの本の勉強はもう少しだけPendingします。

9.5 Direct3D 12 ゲームグラフィック実践ガイドを勉強する

今週は何をするんだったけ?

と先週のBlogを読んだ思い出しました。

App Classを実装するんでした。

いきなり重いの来た。

全然やらない訳にもいかないし、出来るとこまでやりますか。

正直、今週はこっちを頑張るべきでした。そうすれば来週からDirectX 12の勉強に3つの本で同時に始められました。

まあ、仕方ない。

出来る所までやります。

まずApp.h fileとApp.cpp fileを作成します。

Sample Codeを見ると以下のFile内で作成されているので

同様にしました。

それではApp.hの実装から始めます。

まずは使用するHeaderをIncludeする所からです。

Windows.h。Sは忘れていません。まあVSでTypoする事はほとんど無いですけど。

次のcstdintはどんなHeader何でしょう。

うーん。覚えていません。調べます。

cppreference.comのcstdint [19]に以下の説明がありました。

成程。cのStandard Libraryなのね。

Constructor、Destructor、そして唯一のMember FunctionであるRun()関数を追加します。

この辺はC++のClassの作り方としては直球すぎてCommentする事は無いです。

Privateの方です。

Helper Method?

C++だとHelper member functionって言うべきなんでしょうか?

うーん。

数年ぶりにC++でCodeを書き込んでいますので、かなり忘れています。

最後のWndProc()関数は先週勉強したやつです。

一寸、本の説明をしっかり読みます。

説明が真っすぐで分かりやすい。

C++でCodeを書く人は変に捻って書く人とかもいますが、このCodeは直球で書いてくれるので分かりやすいです。説明も同じで簡潔で必要な事だけビシッと書いてあります。

ここではWindProc()関数の説明は無かったですね。

App.cppの実装です。

当然ですが、HeaderをIncludeします。

次にConstructorの実装です。

うーん。

この書き方で変数を初期化した方が何か得があったはずです。が忘れてしまいました。調べようにもこの書き方自体の名称を忘れてしまいました。

後で調べます。

---後述---

調べました。

この書き方はInitializer Listと言います。

Geeks for geeksのWhen do we use Initializer List in C++? [20]には以下のような解説がありました。

この書き方の長所は以下の変数も初期化出来る事でした。

  • non-static const data members
  • reference members
  • DefaultのConstructorを持たないmember objects
  • 親ClassのConstructor
  • constructorのparameter と同じ名前を変数の初期化も使用した場合(同じ変数とはみなされない)

そしてこの書き方の方が、早く動くそうです。

---

Destructorです。

はい。

Run()関数の実装です。

うーん。これはまだ何をやるのか分かりませんね。

それぞれのHelperの関数の実装を見ないと。

次はInitApp()関数の実装です。

InitApp()が何をしているのかは判明しました。

InitWnd()をしています。

しかしInitWnd()関数が何をしているのかまだ不明です。

軽く実装を見ました。ここでCreateWindowEx ()関数を使用しています。

ここでWindowを作成していますね。

まずGetModuleHandle()関数を使用してhInstを初期化しています。

うーん。

こんなのしたっけ。覚えていません。

他の本の実装で確認します。

DirectX 12の魔導書」では以下の様に使用していました。

直接、WNDCLASSEXのPropertyにAssignしていたから覚えていなかったみたいです。

OlympusMonsTutorialsではHInstance()関数になっていました。

HInstance()関数って何?

と思って調べたら

GetModuleHandle()関数の事でした。

これを敢えてMacroでやる意味があるんでしょうか?

覚えていません。

最後にHLSLシェーダーの魔導書です。

この本はWindowの作成方法とかについては全く語っていないので、Sample CodeにあったWindow作成の実装部分を切り取って持ってきました。

まあ、書き方は違いますがやっている事は同じです。

みんなGetModuleHandle()関数を使用していました。

しかし何でここまで書き方違うんですかね。

勉強する方はみんなが同じ事をやっているって気が付くだけでも大変です。

これはとても今週中に終わる感じではないので、App Classの作成は来週もやる事にします。

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

10.まとめと感想

今週は最初のWater Systemによる川の作成で3D酔いして気持ち悪くなってしまって、全体的になんか締まりがない勉強になってしまいまいした。

まあ、そういう週もあるでしょう。

Volumetric Cloudに関しては、後からもっと客観的な方法でPhotorealisticな雲を作成する方法を見つけました。これは来週まとめます。

以上です。

11.参照(Reference)

[1] renderBucket. (2022b, December 4). Unreal Engine 5 Tutorial - Shading Niagara Fluids - Honey [Video]. YouTube. https://www.youtube.com/watch?v=iHxNQE9n_Gw

[2] Andrea Cantelli. (2020a, May 21). Gaea Tutorial for Beginners #1 | Intro to the series & Analyzing the Interface [Video]. YouTube. https://www.youtube.com/watch?v=fX1PJNvl8c0

[3] Magee, R. (n.d.). Foundations | Overview | SideFX. https://www.sidefx.com/tutorials/foundations-overview/

[4] OlympusMonsTutorials. (2021, March 3). C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [Video]. YouTube. https://www.youtube.com/watch?v=rWylZKi8QbM

[5] Klaus. (2022a, May 14). Unreal Engine 5: Water System in UE5 Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=MpCQc4sDMjw

[6] Help Please Error Packaging Project. (2022, November 19). Epic Developer Community Forums. https://forums.unrealengine.com/t/help-please-error-packaging-project/693911/1

[7] renderBucket. (2022b, December 4). Unreal Engine 5 Tutorial - Shading Niagara Fluids - Honey [Video]. YouTube. https://www.youtube.com/watch?v=iHxNQE9n_Gw

[8] GIMP packing image into alpha (pasting grey scale image into alpha). (2018, July 29). Stack Overflow. https://stackoverflow.com/questions/51581384/gimp-packing-image-into-alpha-pasting-grey-scale-image-into-alpha

[9] Ben Cloward. (2022b, October 13). Rock Shader - Advanced Materials - Episode 3 [Video]. YouTube. https://www.youtube.com/watch?v=Q2XI8cuSBMk

[10] Ben Cloward. (2022, October 6). Sparkling Snow Shader - Advanced Materials - Episode 2 [Video]. YouTube. https://www.youtube.com/watch?v=TCz-fKJS3wI

[11] Andrea Cantelli. (2020b, May 24). Gaea Tutorial for Beginners #2 | Node Graph Workflow. YouTube. https://www.youtube.com/watch?v=lKxw45AoRbU

[12] Alias Help. (n.d.). http://desprod.dmu.ac.uk/alias_2010/index.html?url=WS73099cc142f48755360aa6ed11a9c1effaa-69e6.htm,topicNumber=d0e7382

[13] 【十種雲形】雲は全部で10種類 見分け方を形や高さから解説!~下層雲編~. (2021, August 1). tenki.jp. https://tenki.jp/suppl/tenkijp_labo/2021/08/01/30532.html

[14] Climate - Cloud types. (2022, December 30). Encyclopedia Britannica. https://www.britannica.com/science/climate-meteorology/Cloud-types

[15] OlympusMonsTutorials. (2021, March 3). C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [Video]. YouTube. https://www.youtube.com/watch?v=rWylZKi8QbM

[16] Compiler Error C2857. (2021, August 3). Microsoft Learn. https://learn.microsoft.com/en-us/cpp/error-messages/compiler-errors-2/compiler-error-c2857?view=msvc-170

[17] D3D12CreateDevice function (d3d12.h) - Win32 apps. (2022, July 28). Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-d3d12createdevice

[18] Direct3D feature levels - Win32 apps. (2022, August 5). Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro

[19] Standard library header  (C++11) - cppreference.com. (n.d.). https://en.cppreference.com/w/cpp/header/cstdint

[20] GeeksforGeeks. (2022, April 19). When do we use Initializer List in C++? https://www.geeksforgeeks.org/when-do-we-use-initializer-list-in-c/