UE4の勉強記録

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

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

1.今週の予定

今年から以下の内容を勉強します。

  • LandscapeのみのGameを作成する
  • Niagaraの勉強
  • Materialの勉強
  • 戦闘システムの続きを作成する
  • Gaeaの勉強
  • Houdiniの勉強
  • Volumetric Cloudの勉強内容をまとめる
  • DirectXの勉強

先週は、これをやってみましたが量は多すぎました。

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

先週作成したHeight MapとMaskをUEにImportしてLandscapeを作成します。

2.1 Landscapeを作成する

Landscape用の仮のMaterialを事前に作成しておきます。

これ別にやらなくても後からLandscapeのMaterialのLayerとMaskを対応させる事は出来るんですが、先に作っておくと色々楽なので前もって4つのLayerを持つLandscape用のMaterialを作成しておきます。

まずProjectの作成から行います。

Versionは5.1にします。Project名はLandscape Gameとします。

新しいLevelを作成します。

一応、World Partitionが使用出来るOpen Worldを選択しました。

Env.LightMixerを開いて空の作成に必要なActorを追加します。

以下のActorが追加されました。

Landscape用のMaterialを作成しました。

取りあえずLayerが4つあれば良いので以下の実装を作成しました。

勿論後で、しっかりしたMaterialの実装を作成しますが、とりあえずはこれで十分です。

Klaus氏のTutorialを見ながらLandscapeを作成しても良いんですが、多分自分ひとりでも出来るでしょう。

何も見ないでLandscapeを作成してみます。

以下の条件でHeight MapをImportします。

ImportするHeight Mapは先週作成したやつです。

結果です。

高すぎな気がします。ZのSizeを半分の30に変更します。

うーん。

これくらいなら良い感じです。

LandscapeのPaintを選択して

なんかやり方を間違えたらしくUE editorがCrashしてしまいました。

もう一回新しいLevelを作成してHeight Mapの読み込みからやり直そうとしたら、前の設定がそのまま表示されて以下に示した様になりました。

MaterialのDirtとGrassが逆ですね。

直します。

Roughnessを上げてテカリを止めます。

この時点でかなり良い感じです。

話は戻ってLayerとMaskの指定方法なんですが、私が理解しているのは、

Paintの以下の部分にLyerInfoを作成して

ManageのImportの

Layerの部分でMaskを指定する

やり方です。

なんかこのやり方間違っているのでしょうか。

今、Layerを開いたらLandscapeってLayerが出来ているし、それぞれのLayerに指定したはずのMaskが消えています。

うーん。

分からん。

ちょっともう一回やり直します。

このProjectは消して、新しいProject、LandscapeGame2を作成してそこでもう一回最初から試してみます。

やり直しました。

これでLandscapeを確認すると

前のProjectと同じになっていました。

何でセットしたMask達が表示されないんでしょうか?

うーん。

分からん。

これはKlaus氏のやり方を復習する必要がありますね。

2.2 How To BUILD AN ISLAND In 20 mins | Unreal Engine 5 Tutorial[1]のUEへのImportのやり方を勉強する

このTutorialのCreating the Island in UnrealでGaeaで作成したHeight MapとMaskを使用してUE5でLandscapeを作成する方法を説明しています。

この部分を以下にまとめます。

以下にKlaus氏が使用するHeight MapとMaskを示します。

これ見るとMaskが5個ありますね。私のMaskはFlowが無いです。

Flowは川を追加するためのMaskですね。

まず新しいLevelの作成を行っています。

Empty Open WorldをTemplateに使用していました。

Env. Light Mixerを使用して空を作成しています。

Env. Light Mixer内にCreate Atmosphere 1があるところを見るとこのUnrealのVersionは5.0のようです。

Sky Lightを選択してReal Time CaptureにCheckを入れます。

むむ。

これってDefaultでCheckが入っていると思っていたんですが。

確認します。

無かった。

Check入れました。

このReal Time Captureの機能の確認もしておきます。

これを簡単にまとめるとSky AtmosphereやVolumetric CloudそしてSky Domeの影響を考慮して

  • Dynamic Diffuse
  • Specular Environment Lighting

の質が良くなるって書いています。

これにCheckを入れると時間によって夜になったり朝になったりするんじゃなかったけ。

うーん。なんか記憶と違う。

公式のDocumentにあるSkylight [2]にReal time Captureの詳しい解説がありました。

これ読むと、環境光が動的でSpecularになると書かれています。

うーん。

さっきの解説と一寸違う事言っていない。

あ、分かった。

最初の文はDiffuse LightとSpecular Lightが動的になるって言っているんだ。

ところが、これ光の種類にDiffuse光とSpecular光がある事を知らないと先程の私の様に、動的なDiffuseとSpecular な環境光を作成すると勘違いして読んでしまうんです。

それで2番目の文になります。

ここは環境光が動的でSpecularになるって言っています。

いや、これはもっとオカシイ。

光の種類にはDiffuse、Specularそして環境光であるAmbient の3つがあります。ここでいっているEnvironment lightingはAmbient lightingの事でしょう。

これはどこまで行っても変わらない原則です。

Specularな環境光という表現自体に、一寸、あれっと感じます。

うーん。

分かりました。ここでEnvironmentといっているのがPointなんです。

元々Skylightの機能を考えると分かりますが、

以下の様になっている影が

Skylightを使用する事で以下の様になります。

これはSkylightが、空から降り注ぐ反射光、つまり青い光が地面に当たって反射している事を考慮しているんです。

この計算を動的につまりDynamicに行うのがReal Time Captureなんです。

そこまでは分かったんですが、それ以上が分かりません。

いろんな条件で影の濃さの変化をReal Time Capture有りと無しで比較したんですが、差が出なかったです。

このReal Time CaptureでDiffuseとかSpecularとか言っているのは話半分位に聞いておいた方が良い気がします。のでこれ以上は深入りしません。

Klaus氏もこのReal Time CaptureをOnにする理由は、Real timeに動的な影を得るためです。としか言っていません。

(CaptionではSchedulesとなっていますが、ここはShadowと言っています。)

脱線しすぎました。

元に戻ります。

Landscape Modeに入ります。

ManageのNewでImport from Fileを選択します。

ここでEnable Edit LayersにCheckが入っていませんが、Klaus氏、後で忘れていたと言っているのでCheckを入れるのが正しいです。

Materialは前に作成したMaterialが指定されています。

そしてLayersにはMaterial内で作成したLayerが表示されています。

私のProjectにはLANDSCAPE VISBILITY...という訳分からんLayerが追加して現れているんですが、Klaus氏のTutorialの例ではそれはないですね。

あ、原因が分かりました。

LandscapeのManageのNewを見ると私のProjectでもLANDSCAPE VISBILITY...というLayerは表示されません。

ところが、Importを開くと以下に示した様にLANDSCAPE VISBILITY...というLayerが現れます。

Import From FileをClickしてHeightmap Fileの欄を表示させ、そこにHeightmapを指定します。

あれ、既にImport from Fileを指定していると思っていました。

まあ、この辺はどうでも良いです。

ここでScalingの設定について解説しています。

この部分は既に何回も勉強していますので、今回はSkipします。

Klaus氏は厳密な計算をして以下の数値を導き出しました。

私は、Landscapeの精度を考えるとScaleは100倍が限界と思っています。今回Klaus氏は5000mのLandscapeを1009 Pixelに落として使用していますが、これをやるなら1009 Pixel のHeightmapを何枚も作成した方が良い気がします。

Klaus氏はここでZの値、つまり高さの厳密な計算方法も解説していて、そのやり方は私は知らなかったのでその部分だけは以下にしっかり記録しておきます。

まずGaeaのBuildの設定でRowにした場合です。

これですね。

2600 meterをここに入れるそうです。

この2600 mがこのLandscapeだけに当てはまる値なのか、それとも全部のLandscapeに当てはまる値なのかは分かりません。

Buildの下の方にあるTerran DefinitionのHeightを見るとDefaultで2600がセットされています。

ので多分ですが、全部の例で2600mをセットするのが正しいんでしょう。

しかし今回のHeightmapはNormalizedでセットされています。

Normalizeの場合は、500mがMaxになるそうです。そしてUnrealではDefault値である100倍が512mになるようにセットされているそうです。

のでNormalizeでExportした場合はZの値は100倍にすれば大体合っているそうです。

ふーん。です。

因みに私は高さのScaleは気分で決めています。今回は30倍に設定しました。

以下のButtonを押してImportしました。

ManageのNewを開くと以下のようなLayerが形成されています。

ManageのNewです。

今度はPaintのPaintを開きます。

それぞれのLayerにLayerInfoを作成します。

Tutorialでは既にLayerInfoを作成しているのでそれをセットだけしています。

LayerInfoにはWeight-Blended Layer(normal)とNon Weight-Blend Layerがありますが、

私はいつもWeight-Blend Layer(normal)を選択しています。

これの違いをKlaus氏のどれかのTutorialで述べていたのを覚えていますが、その違いが何だったのかまでは覚えていません。

以下に私のProjectのPaintのPaintを示しますが、Target Editor以外の欄がありますね。

それ以外はほとんど同じですね。

ここからMaskをImportしますが、ここからのやり方が違った。

まずCliffを選択します。

右Clickし、以下のBoxを表示します。

Fill Layerを選択します。

Landscape全体がCliff Layerになります。

次にGroundAを選択して

又、右Clickして以下のBoxを表示します。

そして今度はImport From/Export To Fileを選択します。

するとManageのImportに飛びます。

ここで表示されている緑の線のMapが下に表示されているLandscapeと同じ大きさである事を確認します。

今回は同じ大きさですが、もし違っていたら以下に示した様にHeightmap FileにCheckを入れて

前にLoadしたHeightmapをもう一回選択する必要があります。

ここでLayerを開きますが、

私のProjectにあるLANDSCAPE VISIBILITYはないです。

これはあれだ。

私は以下の部分をやらなかったからだ。

なんでCliff LayerをFill Layerに選択したのか分かりませんが、それは後で調べます。

以下の様に5つのMaskを指定しました。

うーん。Cliffは何も指定してないですね。

何も指定しない箇所のLayerがCliffになっているのか。

成程。

分かったわ。

これで理解したわ。

と思ったらもうひと手間必要でした。

GroundA以外のCheckを外して

Importしました。

つまりCroundAのMaskだけImportしています。

結果です。

結果です。Grass LayerがCliffのLayerの上に被さっています。

あ。成程ね。

こうやってLayerのMaskを指定する事でGaeaで作成したTerrainと全く同じLandscapeのLayerを作成するのね。

次はFlow BottomのMaskをImportしています。

どのLayerにどのMaskを使用したのかを確認しておきます。

  • GroundA=Slope
  • FlowBottom=Flow
  • FlowTop = Erosion
  • Sand = Beach
  • Lake = Sea

でした。

残りのLayerも同じように一個ずつImportしていきます。

これで終わりでした。

<Mask作成の順番を確認する>

UnrealでLayerにMaskを指定した順番とGaeaのMaskを作成した順番は同じなはずです。

念のためこれを確認します。

最初のMaskはSlopeでした。

次のMaskはShatterですが、その元はFlowです。

その次のMaskはErosionかと思ったんですがBeachを取っています。

最後にSeaを取っています。

あれ、Erosionが無い。

ずっとFlowが先週無かったMaskだと思っていたんですが、どうやらErosionが先週無かったMaskだったみたいです。

2.3 Landscapeをもう一回作成する

これはもう一回、Landscapeを作り直す必要がありますね。

新しいLevelを作成しました。

当然、Empty Open Worldを使用しています。

ここにEnv. Light Mixerを使用して

Directional Light、Exponential Light、Sky Atmosphere、Sky LightそしてVolumetric Cloudを追加します。

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

Landscape用のMaterialを作成します。

今度はLayerを5個作成しました。

Flowには一応青色を付けました。これは結果を見てから考え直すかもしれません。

Landscapeを開いてManageのNewを選択しました。

設定は以下の様にしました。

当然、Enable Edit LayerにCheckを入れました。

Heightmapには先週作成したHeightmapを入れました。

Materialには先程作成したMaterialをセットしました。

Scaleの設定は先週と同じにしました。

Importしました。

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

Landscape ModeのPaintのPaintを開き

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

この時点で、LandscapeはCliffの色一色になりました。

今度はCliffを選択して

Fill Layerを選択します。

Tutorialと違い、私のLandscapeは既にCliffの色一色になっているので何も変化しません。

今度はGrassを選択してImport From/Export To Fileを選択しました。

するとLandscapeのManageのImportに飛びました。

LayerにLANDSCAPE VISIBILITYがあります。

うーん。

このやり方でも出て来るという事は、このLayerは出来るのが正しいんでしょうね。

多分、5.1から標準になったんでしょう。

表示されている緑の線のMapが下に表示されているLandscapeと同じ大きさである事を確認します。

同じでした。

対応するMaskがあるLayerにMaskを指定します。

今度はGrassだけCheckを残して残りのLayerのCheckを外します。

この状態でImportします。

結果です。

山頂に草が生えている変なLandscapeになりました。

ただ全部がオカシイんじゃなくて一番高い山の周りはいい感じに草が生えています。

次はFlowにのみCheckを入れてImportしました。

結果です。

うわ。全部水色になってしまいました。

まあ良いです。

次に行きます。

次はBeachだけ選択してImportしました。

結果です。

成程ね。このやり方だと後から追加するLayerが100%上書きするんですね。

最後にSeaのLayerを追加します。

結果です。

Landscape ModeからSection Modeに変更しました。

ん、Layerの色を調整しました。

2.4 作成したLandscapeを検証する

以下にKlaus氏のやり方に忠実に従って作成したLandscapeを示します。

まず川が欲しいです。GaeaのProjectに川のNodeを追加して川を作成しましょう。

Beachは大きすぎる気がします。

実際に歩いてみます。

砂浜の端に着きました。

うーん。本物の砂浜もこの位の大きさはある気がしますね。

やっぱり1km^2というのが小さいのかもしれませんね。

この辺の凸凹は後で手直しする必要がありますね。

山を登ってみました。

流石に登り切れませんでした。

歩いた感想を以下にまとめます。

まず悪くないです。

Beachがあって荒地があって緑があって山があります。

後、欲しいのは川と湖、岩場ですね。Beachの半分ぐらいは岩場にしたいです。

以下の赤線の部分に湖と川を追加して、Beachの半分は岩場にしたらかなり良い感じになると思います。

来週はGaeaでTerrainの修正を行います。

2.5 予定の確認

2023-01-01のBlogを見ると一月のLandscapeだけのGame作成の予定表は以下の様になっていました。

ああ、Water Systemを勉強する必要があるのか。

まあ、しょうがない。来週はGaeaでTerrainの修正を行います。

3. Niagaraの勉強

3.1 Colliderに変わる設定を探す

先週、Unreal Engine 5 Tutorial - Niagara Fluids - Flamethrower [2/2] [3]を勉強しましたが、Static MeshとCollisionする設定が分かりません。

TutorialではUE5.0 でやっていてその場合は、Emitter SummaryにあるTagにColliderと指定されています。

これを対象のStatic MeshのTagにセットする事でそのStatic MeshはNiagara Fluid Simulationと衝突する事になります。

このTag自体が5.1にはありません。

これの問題を解明します。

まずはUE5.1のContent ExamplesにあるNiagara Fluid のSampleである以下のSampleを検証します。

これSmokeがStatic MeshにCollideしています。

ざっと探しましたが全く分かりません。

今度は5.0のContent Examplesの同じSampleを調べてみます。

このEmitter SummaryのCollision Data InterfacesにあるStatic Mesh Collisionsが以下の設定を行っています。

Pre Sim Velocity SectionにあるGrid 3D Compute Boundary Module内に

Use Static Mesh Collisionがあります。

うーん。

これから見ていきますか。

5.1の同じSampleのPre Sim Velocity Sectionです。

Grid 3D Compute Boundary Moduleがあります。

そしてその中にはUse Mesh Collisionsがあります。Use Static Mesh Collisionsは無いです。

うーん。これだけだと全く分かりませんね。

これは以下のSectionで何をやっているのかが判明しないと理解出来ない感じです。

うーん。決めました。Render Bucket氏のNiagara Fluid Simulationに関するTutorialはUE5.0で勉強します。

そしてその後で、どうするかまた考えます。

3.2 Unreal Engine 5 Tutorial - Shading Niagara Fluids – Honey [4]を勉強する

なんと、Render Bucket氏のNiagara Fluid SimulationのTutorialはこれが最後でした。これ以外のNiagara Fluid SimulationのTutorialはありませんでした。

うーん。

これは予想外です。

来週からどうやってNiagara Fluid Simulationの勉強をしよう。

兎に角、今週はこれを勉強します。

まず、全部見ました。

ハチミツのSimulationを作成しています。

Niagara Fluid SimulationにおけるViscosityの調整の仕方を勉強するのかと思ったら違いました。

そのほとんどが物質がどうやって光を透過したり屈曲したりしていてそのためのParameterがどうなっているのかについての勉強でした。

これはこれで非常に面白かったです。

このTutorialの最後に一寸だけ、Niagara Fluid SimulationにおけるViscosityの調整の仕方も教えていました。

以下にこのTutorialの内容をまとめます。

まずこのTutorial、5.1で作成されていました。

これは予想外です。

Grid 3D FLIP Hoseから作成します。

名前はFXS_Honeyとしました。

まずSprayやFoamを作成するEmitterは入らないので消します。

まずは水の高さを変更します。

System StackのUser Parameter SectionにあるWater Heightの値を20にします。

Pressure Iterationsの値も変更します。

これは何をするParameterなのか分からないです。

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

Grid 3D FLIP Fluid Control Emitter Stackの

Particle Spawn SectionにあるSphere Location Section Moduleの

Sphere Radiusの値を25にします。

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

次はShadingの調整を行います。

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

Override MaterialsのIndex[0]にセットされているM_WaterSDF_InstのあるFolderを開きます。

TutorialではDefaultで付いているMaterialやそのInstanceは絶対に変更するな。もし間違ってしたらUEをもう一回Installする羽目になる。と長々と言っています。

余程の初心者じゃない限りそんな事はしません。

M_WaterSDF_InstをDuplicateしてM_WaterSDF_Honeyと名付けます。

このMaterial InstanceのParameterを改造します。

しかしその前にM_WaterSDF_Honeyを開きそのParent Materialを確認します。

M_WaterSDFでした。

今度はこのMaterialがあるFolderを開きDuplicateします。

今度はM_WaterSDF_Customと名付けます。

最後にこのDuplicateしたMaterialとMaterial InstanceをHoney Folderに移します。

うーん。

こんなの逐一記録する箇所じゃなかった。

単に使用しているMaterial InstanceとそのParentであるMaterialをDuplicateしてHoneyのFolderに移動します。と一言で説明すればよかった。

後で読み直してもこんな解説が必要になる訳もないです。

もう書いてしまったので、あえて消すのも勿体ないのでそのまま残しておきます。

M_WaterSDF_Honeyを開きそのParent MaterialにM_WaterSDF_Customをセットします。

Niagara Fluid SimulationであるFXS_Honeyに戻ります。

Grid 3D FLIP Fluid Control Emitter StackのRender SectionにあるMesh Renderer ModuleのOverride MaterialのExplicit Matに

M_WaterSDF_Honeyをセットします。

はい。

これでOriginalのMaterialとMaterial Instanceを変更しないで、Honey用のMaterialとMaterial Instanceを作成する準備が出来ました。

はい。

そんだけです。

このTutorialの勉強で大切なのはこれからです。

まずM_WaterSDF_Honeyの値をResetするそうです。

まずBase ColorをDisableしました。

次にScatteringをDisableしました。

Scattering! Scatteringがあるのか。

Absorptionの値を0にします。

Absorptionもあるんですんか。

これはかなり厳密な光の計算をしているみたいですね。

水が透明になっています。

これでDefaultの値になったそうです。

ここからHoneyっぽい色を追加するそうです。

がその前にAbsorptionのParameterが何を管理しているのかを解説しています。

Absorptionに赤をセットします。

すると水の色が緑になりました。

これはどのSpectrumがAbsorbされるのかを指定しているからです。

この液体は赤をAbsorbし、残った緑色が表示されています。

なのでHoneyの色を出すためにAbsorptionに水色を指定し

液体の色を赤くします。

今度はOpacityについてです。

Opacityの値を1にすると

先程の赤い液体は黒くなります。

うーん。これ式を示してほしいです。液体の光の吸収を表す、このSimulationを作成するに当たって使用している元の式を知りたいです。

それ見ればどの値を弄ったらどんな結果になるのか一目瞭然です。その後で実際の計算結果の可視化としてこの液体の色を見たら理解が100倍深まります。

なんとこの液体が黒くなるのはBase Colorが黒くセットされているからだそうです。

Opacityの値が高くなればなるほど、このBase Colorの色に近づくそうです。

なのでBase ColorのCheckを入れると

液体の色は以下に示した様に

Base Color色に変化しました。

今度はBase Colorを白にします。

当然、液体は白くなります。

ここでOpacityの値を1から下げます。

すると以下の様にAbsorptionとBase Colorの色が混じった感じになります。

うーん。分かりやすい。

更にScatteringを追加します。

Scatteringの色になります。

Light(Directional Light)がこの液体を通過しない角度で見ている時、

ほとんどOpacityの色になります。

Absorption、Opacity (base Color)そしてScatteringの3つの値を調節してHoneyの色を再現するそうです。

これらの値をどうしたらHoneyにそっくりになるのか全く想像できません。とにかくTutorialのやり方を見てみます。

その前にPhaseについてです。

この値はScatteringがどう関わってくるのかを指定するそうです。

値が大きい時は、Forward Scatteringと言ってScatteringは光源から離れるそうです。

逆に値がNegativeな時は、Back Scatteringと言ってLightはもっと反射するようになるそうです。

うーん。

何言っているのか分からない。

調べました。

以下の図が一番分かりやすかったです。

https://www.researchgate.net/figure/A-schematic-of-light-transport-a-forward-scattering-b-forward-scattering-and-back_fig2_4169663 [5]

から引用しました。

この図の元はガチの論文で、その論文を引用元に記しておきました。

要するにLightが粒子にぶつかった時にScatteringが起きるんですが、その方向がLightと同じ方向だったらForward ScatteringでLightの向きと逆だったらBack Scatteringになる訳です。

私、化学とCSのDouble Majorだったので化学の研究室にいた時期があったんですが、その研究室ではLaserで色付きの液体を励起してScatteringを起こしてその光を分子に充てて、分子が振動する波長を調べていました。

まあ分光学の一種ですが、バリバリの量子化学の研究室ですので、光の錯乱などの計算は、大抵のCSの研究者より出来ます。

いやこれは出来ました。と言うのが正解で今はその計算方法の大半は忘れてしまっています。が勉強すればすぐに思い出せます。

うーん。この辺の勉強は一寸やりたいですね。

次はToleranceです。

TutorialだとBlobbyと言っていますが、Blobby自体初めて聞く単語です。

調べたらBubbleっぽくなる事の様です。

1の時です。

0.1の時です。

Tutorialでは数字が大きいほどBlobbyと言っていますが、このBlobbyの意味が泡泡している事なら数字の小さいほうがしている気がします。

どうなんでしょうか?

これでM_WaterSDF_HoneyのParameterについての解説はお終いだそうです。

ここからはHoneyの色合いを出すためのこれらのParameterの設定を行うそうです。

まず今まで弄ったParameterの値を0に戻します。

Absorptionの値です。

結果です。

うーん。この時点で既にハチミツっぽいです。

Absorptionの値って実際のハチミツから測定して得た値何でしょうか?

何かそういう所に興味を惹かれます。

Base Colorです。

結果です。

あんまし違いが出てないですね。

Opacityの値をいじったら変わるんでしょうか?

Opacityの値は逆に0.1に下げてしまいました。

まあ、ハチミツって透明ですからね。

結果です。

当然ですが、あんまり変化ないですね。

次はScatteringです。

Alphaの値が0.15なのでほとんどScatteringはしないという事でしょう。

一寸、緑がかって来ました。

今度はPhaseの値を変更しました。

もっとBack Scatteringを起こします。

と思ったらTutorialはいろんな値を入れて試していました。

Specularの値を追加します。

大分、ハチミツらしくなりました。

今度はRefraction(屈折)を追加します。

これはMaterialの実装にRefraction用のCodeを追加する事で実現します。

M_WaterSDF_Customの

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

これでRefractionが発生するのは理解できますが、この計算が正しいRefractionを発生出来るんでしょうか?

その辺の解説が欲しかったです。

Material InstanceであるM_WaterSDF_Honey

以下の値を調節して

屈曲を表現しています。

屈曲そのものは観測出来ますね。

この屈曲が正しいのかどうかは別ですが。

Roughnessの値もセットしました。

結果です。

Specularが増しました。

更に値を微調整して以下の様になりました。

これで一応完成ですが、

Simulationを見ていると、ハチミツ色をした水が流れている感じがします。

つまりViscosityが無いんです。

このParameterはNiagara Fluid Simulationには無いので疑似的に追加するしかありません。

このTutorialでは、ParticleのCollideとInteractの値を調節する事でハチミツの高Viscosityを再現するそうです。

Niagara Fluid SimulationであるFXS_Honeyを開いて

Grid 3D FLIP Fluid Control Emitterを選択します。

そしてParticle SectionにCollision Moduleを追加します。

このCollision ModuleはGrid 3D FLIP Integrate Particle Velocity Moduleより上に配置する必要があります。

そしてCollision Moduleに表示されているErrorを消すためにDismiss Issueを選択します。

これ超重要な箇所で決してFix Issueを押してはいけません。

そしてCollision ModuleのAttributeの値を調整します。

まずKill Occluded ParticlesのCheckを外します。

Restitutionの値を0にしました。

これはParticleがCollideした時にEnergyを全部失うという意味だそうです。

結果です。

最後にEmitter Summary Sectionにある

Render SectionにあるSDF Particle Size Multの値を1~1.5に上げました。

これはParticleから生成されるMeshのSizeを大きくするそうです。

その結果、以下の様にClumpy(大きな塊)になりました。

これで終わりでした。

3.3 Unreal Engine 5 Tutorial - Shading Niagara Fluids – Honey [4]を勉強して

かなり勉強になりました。

単にParameterを弄っているだけでもAbsorptionとかScatteringとかの復習になって昔、分光学で勉強した内容を一寸だけ思い出しました。

分光学で光の性質について勉強した時は、式とその式を使用した計算結果しかなくて実際のモノがどういう風に変化するのかは全くわかりませんでした。こうやって可視化するとそれぞれのParameterと実際の物質の色の関係が一目瞭然になるので、実際感動しました。

Niagara Fluid Simulationでは粘性が再現出来ないのが一寸悲しいですね。

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

これは来週やります。

本当はこれもやりたかったんですが、これやったら先週と同じで終わらなくなります。NiagaraとMaterialの勉強は去年の半分ぐらいの量にします。

Niagaraで勉強してMaterialは実装する週と、Niagaraで実装してMaterialで勉強する週を交互に繰り返す感じにします。

そうしないと永遠にGameが完成しなくなるからです。

4. Materialの勉強

今週はBen Cloward先生のRock Shader - Advanced Materials - Episode 3 [6]を勉強します。

今週は全部やって来週から勉強する日と実装する日を分けるのか、今週から勉強だけにするのかは、やってみて決めます。時間とやる気が余っていたら最後までやりますし、どちらかが足りなくなったらその時点で終了します。

4.1 Rock Shader - Advanced Materials - Episode 3 [6]を勉強する

まず全部軽く見ます。

見ました。

先週と同じでNormalのBにRoughnessの値を入れたり、Macro Size用のNormalやMicro Size用のNormalを作成したりしています。

うーん。

これのやり方を解明する必要があるのか。

RockのShaderは以下の様になっています。

UEで提供されているRockのMaterialを見ると以下の様になっています。

Materialはかなり精密でぱっと見本物と変わりません。

しかし以下に示した様にRockを実際に使用する場合は2つ以上のサイズの違うRockと重ねて使用します。

するとMaterialに使用しているTextureのサイズが全く違うので直ぐに2つ以上のRockを混ぜて作成したと分かってしまいます。

更にSizeを大きくしたRockの方のMaterialは全体的にぼやっと見え、Resolutionが低い物体がポツンと存在しているように見えます。

以下に今回のMaterialを使用した場合の30倍に拡大したRockの結果を示します。

全くMaterialに使用しているTextureがぼやけていません。

更にMacroとMicroのNormalも追加しているので、以下の様にRockに極端に近づいても

その細部の細かさがぼやける事はありません。

うーん。

凄い。

凄いけど、一枚のTextureにNormalのDataとそれ以外のRoughnessやAmbient OcclusionのDataを持たせる方法がまだ分からないんです。

これを解明しない事には、この技術を学んでも絵に描いた餅でしか無いです。

うーん。どうしよう。

調べたらPhotoshopでやっている事はGIMPでも出来そうです。

これは後で調べる事にします。

以下にこのTutorialの手順をまとめます。

まずUEに付属で備わっているRock用のMaterialの実装を解説する所から始まっています。

これが本当にUEにあるMaterialなのか、単なるRockのMaterialの例として、このTutorialが作成したものなのかが分かりません。

一寸確認します。

調べたらUEにはM_Rockと言う名前のMaterialが確かにありました。

実装を見たら全く同じでした。

更にSM_Rockと言うTutorialで使用している岩と全く同じStatic Meshもありました。

まずTextureの話です。

以下に示した部分がM_Rockに元からあるTextureだそうです。

確認します。

まずBase Colorに使用されているT_Rock_Basalt_Dです。

開くと以下のようなImageを示しました。

Alphaを切ります。

以下のImageが現れました。

これはTutorialで紹介された左端のImageと同じです。

因みにAlphaには以下のImageが入っていました。

うーん。これはRoughnessとかでしょうか?

次は、Ambient Occlusion Maskで使用されている

T_RockMesh_Mを調べます。

以下のようなTextureでした。

Ambient Occlusionに使用されているRの値を見ると

あ、これTutorialの右から二番目のImageです。

因みにGには以下のImageが入っていました。BとAlphaには何も入ってなかったです。

Normalに使用されているT_RockMesh_NのImageです。

これはTutorialの左から2番目のImageです。

最後のDetail NormalのTextureですが、

T_Detail_Rocky_Nが使用されていました。

これは多分、Tutorialの一番右端のTextureと同じでしょう。

はい。

確かにTutorialが言っている通りでした。

そして以下に示したのが、このTutorialで改良したTextureたちです。

まずDiffuse 用のTextureですが、

  • RBR向けにLevelの調整をして少しだけ明るくした。
  • Alpha ChannelにRoughnessを追加
  • 名前をRock_CRに変更(Color, Roughness)

をしたそうです。

うーん。Roughnessは元からTextureのAlpha Channelに入っているので、RoughnessをAlpha Channelに追加したというのは多分勘違いでしょう。

となるとLevelを調整して一寸だけ明るくするだけなので、このTextureの調整は出来そうです。

次はNormal Mapですが、Normal MapのBlue ChannelにAmbient OcclusionのTextureを追加したそうです。

これもう少し具体的に言い直すと、T_RockMesh_NのBlue ChannelにT_RockMesh_MのRed ChannelのImageを追加した。という事です。

うーん。

これを正確にやるにはPhotoshopが必要ですね。GINPにも同様の機能があるみたいなんで、それを勉強してみます。

次にMacro Detail MapとMicro Detail Mapを紹介しています。

これらのNormal Mapとどこから手に入れたのかについての説明は全く無かったです。

うーん。どうしよう。

似たNormal Mapを探して使用します。

そしてTutorialではUEにImportしたこれらのTextureの簡単な解説をしています。

重要だと思ったところだけ書き出しました。

TutorialのDiffuse用のTextureに入っていたRoughnessは以下のものでした。

T_Rock_Basalt_DのAlpha Channelに元から入っているImageは以下のものです。

これは別のImageをRoughnessとして使用する必要があるかもしれませんね。

正直、UEのTextureの設定ってまだよく分かってない部分が多くてどこが大切なのか分からない所があります。

例えばTutorialでNormal MapのFormatがBC7である必要について解説していますが、

Normal MapのBlue Channelに別なImageを保存したからBC7にしないといけないという事以外は全く理解していません。

こういうものの勉強は本当に億劫です。

ここからMaterialの作成です。

4つのTextureをImportしました。

まずTextureのScaleがObjectの大きさに関係なく一定にするための実装です。

Object Scaleを掛けています。

このMaterialをRockに使用してRockのサイズをおおきくすると

TextureのサイズはそのままでTextureを繰り返してRockの表面を覆うようになります。

うーん。

成程。

こういう発想が大切なのか。

このTexCoord[0]の結果をTexture Sampleに繋ぎます。

Base ColorとRoughnessに繋ぎます。

NormalとAmbient Occlusionに繋ぎます。

Normal Mapに戻すための計算は先週もやったのでここに記録はしません。

何故かTutorialは、このTexture SampleのUVに先程のTexCoord[0]の計算結果を繋ぎません。多分後で繋ぐと思うんですが。

MacroなDetailを持つNormal Mapを追加しています。

赤線で囲った計算を敢えてする事で通常のNormalにAddする事が出来ると説明されています。

このやり方はよく分からないです。Derived Normal Zノードの前にこの値をAddするのが正しい気がします。

ここでこのMacroとMicroのNormal MapのBlue ChannelにRoughnessの値が入っている事、AlphaにはColorと混合出来るImageが入っている事が判明しました。

えー。

ですがまあ仕方ないです。続きを見ます。

BのRoughnessですが、以下に示した様にOne MinusしてRoughnessの値に足しています。

Alphaに入っていたImageの方ですが、以下に示した様にBlend Overlayノードを使用して混合しています。

Micro DetailのTextureに関してはこれと全く同じ事をしています。

当然ですが、UVに繋ぐ値だけは違います。

これで完成だそうです。

近づいた画像です。

細部まではっきりしています。

Rockを30倍にした時の画像です。

Macro Detailのおかげで30倍にしても凸凹感がぼやけていません。

しかもサイズが違う2つのRockを重ねても

境界によってTextureのサイズが全く違うという事が無いため、2つのRockを重ねたという事は分かりません。

これで終わりでした。

以下のTexture SampleのUVsには結局最後まで何も繋がなかったです。

このTexture Sampleに入っているNormal Mapを見たらその理由は明白でした。

もう時間が無くなってしまったので今週のMaterialの勉強はここまでにします。

来週がGIMPを勉強してRGBAに望みのImageを追加する方法を解明します。

そして再来週にこのMaterialを実装します。

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

今週は、Mapを別なProjectにMigrateする事で必要なものだけで構成されているProjectが作成出来るのか、そしてそのProjectからPackagingをした場合本当にPackagingした後のサイズは小さくなるのか試してみます。

5.1 Packagingについての復習

調べたら2022-10-23のBlogでMapを別なProjectにMigrateする事でSizeを小さくする方法について述べていました。

Unreal Engine 5 tutorial _How to Reduce your project size [7]にこのやり方が紹介されている。とだけ書かれています。

このTutorialを見たら本当にMapをMigrateする事しかやっていません。

更にAsset Cleaner – Project Cleaning ToolというAssetを使用すると使用していないAssetが消せる事も書かれていました。

後、Projectのサイズを小さくするための方法が紹介されたサイトや動画が何個か紹介されていました。

5.2 MapをMigrateしてPackagingをする

MapをMigrateするためのProjectを作成します。

当然5.1で作成します。

TemplateはBlankを選択し

Project名はMigrate Map Testにしました。

今度はProject、Combat Prototypeを開き以下の2つのMapをMigrate Map Test にMigrateします。

まずはCombatLevelをMigrateします。

以下のAssetが一緒にMigrateすると出てきました。

のAssetを同時にMigrateしました。

この一覧にMapであるAfter Combatは含まれていないのでAfter CombatもMigrateします。

以下のAssetが同時にMigrateされます。

出来ました。

今度はMigrateMapTestでGameをPlayしてみます。

まずCombat Levelを開きました。

普通にGameをPlay出来そうです。

やってみます。

なんとGameが始まりません。

Widgetが読み込まれていないみたいです。

WidgetそのものはMigrateされているみたいですね。

あ、Game Instanceを変えるのを忘れていました。

直しました。

もう一回試してみます。

今度は普通にGameが始まりました。

何か平均以上に後攻が出ます。

Stage 2を勝つのにいつもの2倍近い時間が掛かりました。

なんと、Stage10まで勝ち上がって、とうとうStage10のMonsterも倒す事が出来ました。

うーん。

一寸感動しました。

GameのPlayそのものに関しては何の問題も無かったです。

これを、先週やった方法でPackagingしてみましょう。

まずBuild Light Onlyを行います。

次にBuild All Levelも行いました。

また配置したActorがどっかにいってしまいました。

一回このLevelを閉じて開き直したら元に戻りました。

何なんでしょう?

この現象は?

Project Settingの設定をしていきます。

先週、やったのと全く同じ設定です。

これで全部の設定は完了したはずです。

Saveして以下の箇所からPackagingを行います。

大体10分ぐらいでPackagingが終わりました。

Windows Folderのサイズですが、

でした。

前回のWindows Folderのサイズが

という事を考えると、そんなにサイズの縮小に成功したとは言えませんね。

次にExe.fileからGameをPlayしてみます。

なんとStage 2で負けてしまいました。

特にGameをPlayしていて問題は無かったです。

Mapを別なProjectにMigrateしてPackagingするのは、出来ましたが、思ったよりサイズが小さくならなかったです。

5.3 次の予定をやる

Mapを別なProjectにMigrateしてPackagingする作業は予想に反して、簡単に終わってしまいました。

簡単に終わったのは良いですが、残念な事にPackagingした後のSizeも大して小さくならなかったです。

「戦闘システムの続きを作成する」の今週の予定していた作業はすべて遂行出来ました。しかし大した量はやっていないのでもう少しだけ何かします。

以下に先週決めた予定を示します。

この三週目の作業であるLevelを作り直すためのAssetの調査をする事にします。

まずLow PolyやStylizedしたEnvironment関連で以下のAssetを持っていました。

この中で特に使えそうなのが以下に示したStylized Egyptです。

ただ使用しているCharacterがStylizedされたLow PolyであったとしてもEnvironmentまでLow Polyにする必要もないので、Photo-realisticなEnvironmentも見ておきます。

これかな。ダントツで私が想像している魔法の修行場のImageに合致しています。

Multistory DungeonsをInstallする事にしました。

このMultistoryですが、どんな意味なのか知りません。

調べたらMultistorey Buildingで、一つの階に4つ以上の部屋があって、それが何階も連なっている建物。と説明されていました。

のでMultistoryじゃなくて、Multistoreyじゃないの?と調べ直したら、Multistoryと言う言い方もあってどっちが正しいのか分かりません。ただこのContextでは、沢山の部屋がある何層にも連なったDungeonと言う意味である事は間違いないでしょう。

そんだけ分かれば十分です。

せっかくなんで今日作成したMigrateMapTestの方に追加します。

こっちのLevelをPolishしていきます。

以下の様になりました。

空が明るすぎます。

Volumetric CloudとAtmosphere FogがLevel上に無かったです。追加します。

以下の様になりました。

これぐらいにしておきます。

5.4 空の調整をする

SkylightのReal Time CaptureにCheckが出来ません。

色々試したんですが直し方が分かりません。

仕方ないので一端、Sky関連のActorを全部消しました。

もう一回以下の様にSky関連のActorを追加しました。

今度はCheck出来るようになりました。

新しく作成した空を見ても特に問題は無いです。

これでOKにします。

Exponential Height FogのZの位置を調整します。

1000の時です。

霧は全く掛かって無いです。

10000です。

非常にうっすらとですが霧が掛かっています。

1000の時と比較して初めて気が付くぐらいの霧です。

20000です。

はっきりわかる位の霧が掛かっています。

30000です。

凄い霧です。

しかしまだ対戦相手の魔導士の姿は見えます。

40000です。

対戦相手の光っている部分以外はほとんど見えない位濃い霧になりました。

50000です。

完全に何も見えなくなりました。

1000に戻しました。

Exponential Height Fogがこのように使用するために作成されたのかどうかは分かりませんが、こんな事も出来るという事を示しました。

丁度いいので先週、復習したVolumetric Cloud関連の設定をここで試してみます。

まずはVolumetric Cloudに使用されているMaterialを変えてみました。

M_VolumetricCloud_02_Profiles_PaintCloudsを使用しました。

こんな空になりました。

MI_VolumetricCloud_02_Profiles_PaintClouds_Morningも試してみました。

あれ、雲が出来ませんね。

Materialの実装を確認したら以下のTextureは使用されていませんでした。

うーん。という事はこのMaterialをそのまま使用しても何も表示されないはずです。

先週は何で、このMaterialで雲が出来たんでしょうか?

雲のMaterialはDefaultに戻しました。

今度は、Volumetric CloudのLayer Bottom Attitude とLayer Heightを試してみます。

Layer Botton Altitudeの値を0にします。

雲の底が下に落ちてきました。

Layer Heightの値を10から1にしました。

雲の厚さが10km~1kmになりました。まっ平です。

Directional LightのParameterであるLight Shaftの値を調整してみます。

この2つはGod Rayに関係するParameterなので以下の様にDirectional Lightの角度を変更しました。

Light Shaft OcclusionにCheckを入れました。

いきなり地平線が現れました。

God Rayも所々に見えます。

今度はLight Shaft OcclusionのCheckを外してLight Shaft BloomのCheckを入れました。

画面全体が金色になりました。

Light Shaft Occlusion とLight Shaft Bloomの両方にCheckを入れてみます。

これは全然違う。

この二つはそのまま残しておく事にします。

Directional LightのAtmosphere and Cloudの以下の値を変更してみます。

まずこれらの値が変更できるようにCast Cloud ShadowsにCheckを入れます。

Checkがない状態です。

ある状態です。

雲の影が闘技場に投影され、闘技場が1割位暗くなりました。

その後、以下の値を弄ってみましたが変化があんまりよく分からなかったです。

のでDefault値に戻しました。

Cast Cloud ShadowsのCheckはそのままにしておきます。

後は、SkylightのCloud Ambient Occlusionです。

これが

こうなりました。

この2つのScreenshotを見比べるだけだとあんまりよく分からないですが、On、Offを繰り返すと雲の底の影が強調されているのが分かります。

あった方が雲の厚み感が増します。

これも残しておくことにしました。

今まで勉強したVolumetric Cloud関連で調整するParameterは以上です。

後、Material InstanceのParameterの調整もありますがそれは今回はやらないです。

現時点ではLevelは以下の様になりました。

もう少し改良出来る点はあるかもしれませんが、前と比較したら及第点は取れているでしょう。

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

来週からはMonsterのAnimationの追加をやります。

6. Gaeaの勉強

先週は、Gaea Tutorial for Beginners #1 | Intro to the series & Analyzing the Interface [8]を勉強する予定でしたが、GaeaのUIについての解説を自分で作成しました。

その理由は、今のVersion 1.3.2 CommunityのUIとこのTutorialで使用しているGaeaのVersionのUIが全く違うからです。

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

Gaeaでは以下の3つの方法でTerrainの作成が出来る事を説明しています。

今のVersionではGraph以外で作成する事は出来なくなっているはずです。

確認します。

今のVersionのStart画面です。

Graph、LayerそしてScriptの選択はありません。

LayerやScriptが今のVersionには無い証拠です。

<Interface>

Interfaceの解説です。

<<3D Viewport>>

まずは3D Viewportの操作方法の解説です。

TutorialではMouseの左ボタンを押す事でCameraを動かせると説明していますが、今のVersionではそのやり方ではCameraは動きません。

Alt+ Mouseの左ボタンを押しながらMouseを動かす必要があります。

MouseのWheelでZoom が出来るのは今のVersionでも同じです。

Mouse のMiddle Buttonを押す事でPanningが出来るのも、今のVersionでも同じです。

後、Tutorialでは解説が無かったですが、Space Keyを押すとTerrainがDefaultの位置に戻ります。

<<Menu Bar>>

次はMenu Barの解説です。

Tutorialでは以下の機能がMenu Barに存在しています。

これらの機能についてかなり分かりやすい説明が行われていました。

しかし今のVersionのGaeaのMenu Barは以下の様になっています。

Tutorialの説明をそのまま、当てはめられるのは0.5kとSaveの横にある+ボタン位です。

ただし、New、Open、Save、Redo、そしてUndoはどこソフトでも同じ事をしているので、全体としてはこの部分の機能を理解するのは難しくは無いです。

先週の私のこの部分の説明を読み直します。

今のVersionのMenu Barの機能に沿って、Gaea、Untitled.tor、0.5k、Auto、そして+について簡単な説明がしてありました。

New、Open、Save、UndoそしてRedoについては他のSoftと同じですと書いていました。

自分で書いて自分で読み直しての感想ですが、それなりに分かりやすい説明でした。

今、読み直して付け足して説明すべき事は、

以下に示した様に

Mouseを重ねるとそのButtonの機能が表示される事、

公式のサイト(https://docs.quadspinner.com/Guide/Interface/Getting-around.html)がある事

(ただし、今見た感じだとMenu Barの説明はあんまり分かりやすくなかったです。)

についてです。

Increment ボタンつまり+ボタンですが、その機能について以下の説明を行っています。

この機能、3D ModelのDesignではよく使う機能なんでしょうか?

正直、何に使用するためのものか分かっていません。

後、Tutorialでは以下の機能についても説明されていますが、今のVersionでは、これらのボタンは別な場所に配置されているので

私の説明はこれらのボタンの機能についてはここでは解説していません。

<Toolbox>

<<Toolbox>>

Toolboxの中のNodeと違いToolboxそのものは今のVersionとTutorialのVersionでほとんど同じなので、Tutorialの説明でしっかり理解する事が出来ます。

ただしこのTutorial、Toolboxの使い方は実際にNodeを使用してTerrainを作成する時に教えるので、今ここでは解説しません。と言って終わっています。

私の説明も基本的にはTutorialと同じです。

<<Node Graph>>

TutorialではNode GraphにToolboxからNodeを何個が選択して配置して、Terranが作成出来る事だけ示しています。

私はNode GraphのMenu BarやTool Barの機能も一応、説明しました。

これは蛇足だったかもしれません。

今、これらの機能を説明されてもNodeでTerrainを作成した事が無い人にはチンプンカンプンだからです。

と思ったらTutorialでも一応、Tool Barの機能について簡単な説明をしていました。

今のVersionはこれらのButtonはDefaultでは表示されていませんが、Node GraphのMenu Barの右端にある三本線をClickして以下のBoxを開き

Show Graph Toolbarを選択すると以下のBarが表示されます。

これらの機能は簡単に説明すると以下に示した、Nodeを右Clickした時に表示されるBox内の機能と同じで

どっちか使用出来れば十分ですし、Boxの機能を理解出来ればこのTool Barの機能についても大体理解できるようになります。

TutorialでNode Graph内の操作として、

  • Mouseの中ボタンを押した状態で、Mouseを移動するとPanning
  • Mouseの左ボタンを押した状態で、Mouseを移動すると四角が表示され、その四角内のNodeを全部選択出来る

の2つの機能が紹介されていました。

この機能については紹介するのを忘れていました。

Node Graphの右下にある以下のIconの機能についての解説です。

私はここで重要なのは

これだけと言ってこの機能だけしか説明していません。

Tutorialはそれなりにしっかり説明しています。

この部分の説明を今作成する事にします。

まず分かりやすいようにTemplateから開く事にします。

Gaeaを開いたらMountainからHero Mountainを選択します。

すると以下に示した様にNode GraphにはNodeが2つ表示されています。

Mountain ノードをClickすると以下に示した様にMountainノードが僅かに光ります。

更に以下に示した様に左端のProperties Panelに、選択したNodeのPropertiesが表示されるようになります。

このPropertyを色々弄ってみます。

結果です。

なんだこれは?

最初の状態に戻したい。となったとします。

その時に、先程の3つのIconの内の真ん中のIconを押します。

これでDefaultの値戻り、

ませんね。

あれ?

あ、間違えて覚えていました。

説明を読んだら、RefreshしてRebuildするって書いていました。

これはあれです。

Nodeって常にReal Timeで計算しているんじゃなくて、何かが新しくなったら計算し直すんです。だからごくまれに前のNodeの計算結果が変更されたけどそのNodeはそれを知らなくて前の古いDataの値を使用して計算している事が起きます。その時にこのForce Refreshを使用すると、新しいDataの値を使用して計算し直してくれると言う訳です。

うーん。

多分、これで合っているはずです。

私が前のNodeを更新して後ろのNodeが更新されなかった経験がまだ一回しかないです。のでこのIconの機能を試したことないです。だからこの解釈であっているのかどうか、本当の所は分かりません。

多分、あっているでしょう。

今、新しくGaeaのTemplateを開いたんですが、以下の様になって計算してくれません。

Nodeがあるにも関わらず

Terrainは平のままです。

これはちょうどいい機会なので、Force a Refresh Iconを試してみましょう。

押しました。

はい。しばらく計算してMountainのTerrainが現れました。

この解釈であっています。

最後の右端のIconですが、

これは選択しているNodeのSeedの値をRandomに変更します。

右上のIconについてですが、

先週は、+のIconの使用方法だけ説明して、残りのIconに関しては私も知らない。と言って終わっています。

一応、この部分の説明も作成しておこうと思います。

まずは以下に示したIconです。

機能的には先週勉強した+とほぼ同じです。

左Clickすると以下のBoxが現れ

New Graphを選択すると新しいNode Graphが追加されます。

その下に今まで作成したNode Graphの名前が表示され、選択するとそのNode Graphが表示されます。

次はAt のIconです。

選択すると以下のNodeが表示され選択したNodeを追加する事が出来ます。

試しにMountainノードを追加してみます。

Mountainノードを選択した状態でAt IconをClickします。

すると以下に示した様に

Mountainが追加されました。

でそれが何なんだという話ですが、

このMountainを選択すると、Node Graphのどこ場所にいてもMountainノードの所に飛んでくれます。

例えば今、Graph(1)のTextureノードを見ていたとします。

ここでMountainノードのParameterを確認したくなったとします。

そしたらMountainノードをいちいち探す必要があります。普通なら。

それをAt IconのMountainを選択すると

以下に示した様に、一瞬でMountainノードを示してくれます。

一種のBookmarkですね。

次の炎のIconですが、Bakeする時のResolutionを決定するという事以外何もわかっていないです。

というかこのBakeがいつどこで起きているのかが、まだよく分っていません。

BakeはすべてのNodeで行われているのか?とか、SaveしたProjectを開いたときには、Bakeは新しくし直しているのか?とかが、分かっていません。

のでこれ以上は語れません。

Gaeaの勉強に費やせる時間が終わってしまったので、最後の三本線のIconとSettingについては来週やる事にします。

6.2 分からない事の記録

以下に示したように、Nodeをある部分から選択して、

その部分のNodeを別のGraphに一発で移動させる方法があったはずです。

これを忘れてしまいました。

これも来週以降調べる事にします。

7. Houdiniの勉強

先週、公式のTutorialであるFOUNDATIONS | OVERVIEW [9]の勉強をしましたが、8分のTutorialの内、2分46秒の勉強で終わってしまいました。今週は最後まで終わらせます。

7.1 先週の復習

先週、何を勉強したのか既に忘れてしまっているのでその復習をします。

FOUNDATIONS | OVERVIEW [9]の内のThe Houdini Workspaceの勉強をしていたんでした。

このThe Houdini Workspaceが8分のTutorialでそのうちの2分だけ勉強したのが先週の内容でした。

まあ、良いです。

Houdiniを起動させて先週の復習を開始します。

まずCを押して以下のUIを表示しました。

こんなのも完全に忘れていました。

流石に一週間に一回の勉強で全部覚えておくのは無理があります。

この後、4つのSub画面を見た感想が書いてありました。

その後でTorusを作成しています。

同じ方法でTorusを作成しました。

今度はTorusのWireを表示しました。

四分割の画面の表示です。

Zoomした後で、4つの画面のTorusの位置がバラバラになってしまいました。

はい。

Defaultの位置への直し方を知りたいです。

次はNetwork Pane内から以下のUIを表示しました。

TorusのGeometry Levelに移動しました。

Tab MenuからLineを追加しました。

Display Pointを使用してPointを表示しました。

ま。復習したら全部思い出しましたね。

7.2 FOUNDATIONS | OVERVIEW [9]のThe Houdini Workspaceの続きを勉強する

いきなり以下のような6つのTorusをLineのPointを使用して作成しました。

うーん。

どうやったの?

速すぎて何をしたのか全然分かりません。

コマ送りで確認します。

まずLineの位置を少しだけ上げています。

Lineの位置の値を見ると以下の様になっていました。

Display Pointを解除してTorusだけを選択しました。

ここでModifyを選択しているみたいなんですが、見えない。

試しに自分のProjectでModifyを選択してみました。

こっちがTutorialのTool Barです。

うん。Modifyを選択していますね。

そしてCopy to Pointsを選択します。

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

この後、Lineを選択しますが、これ単に選択しただけなのかShiftを押して選択したのかが分かりません。

そしてEnterを押しているみたいです。

以上でした。

やって確認するしかないですね。

まずLineの位置を移動しました。

ModifyのCopy to Pointsを選択しました。

こんな結果になりました。

うーん。出来ない。

何回かやったら偶然出来ました。

うーん。

Network Paneが以下の様になっています。

これGeometry Nodeですよね。

Objectに戻したらTorusしかありません。Lineノードはどっかに行ってしまいました。

Tree Viewを開いたら以下の様になっていました。

LineはTorusのObjの中に移動したみたいです。

うーん。これは初めて見るHoudiniのProgrammingです。

一寸自分の力だけで読んでみます。

まずこのCopy to PointsノードがTorusをCopyしてLineのPointにPasteしているんです。

となるとそのCopy to Pointsに繋がっているTorusが形状をLineがPointをパスしているはずです。

CopyToPoints(Torus, Line_object(line));

という関数を実行しているのと同じ事をしているんです。

はい。理解出来ました。

TutorialのはTorusのPointsが大量に表示された状態です。

これを

を選択して

を選択して

消しています。

まず以下のIconですが、名前はGeometry Select Modeと言うみたいです。

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

ただし私のCopyしたTorusには最初からPointが表示されてないので、Primitivesに変更しても何も変化がないです。

それより早くNetwork PaneのCodeの説明をしてくれって思っています。

お、Network Paneに移動しました。

これから今、作成されたCodeについて解説してくるみたいです。

を追加して

Torusに色付けました。

おい!

それ違うだろう。

今の時点で今まで見たことがない作成されたCodeが存在しているんだから、まずそれを解説すべきだろう。なんでそれをしないで新たなNodeを追加するの?
Black BoxにBlack Box掛けたら益々訳分からなくなるでしょう。

あー。

こういう教え方するから、みんな理解出来なくなって「Houdiniは難しい。諦めた。」ってなるのね。

他のTutorialを当たるべきかもしれませんね。

一応、出来る所までやってみて考えます。

Network Pane上でTab Menuを表示しAttributeを選択してAttribute Randomizeを選択しました。

以下の様にAttribute Randomize ノードを追加しました。

結果です。

Torusの色が変わりましたね。

これでは本当に何も分からん。

ひょっとすると、このTutorialはHoudiniはこんな事出来ます的な紹介で、この後のTutorialでしっかり教えてくれるのかもしれません。

どんどん先を見てみます。

Copy to Pointsノードを選択して

Optionを選択しGlobal Seedの値を変更します。

色が変わりました。

今度はAttribrandomizeノードを選択した状態でAlt + 左ClickしてAttribrandomizeノードを複製します。

Attributeをpscaleに変更して以下の様に繋ぎます。

更にDistributionにあるMin ValueとMax Valueを以下の様にします。

結果です。

それぞれのTorusのサイズが変わりました。

これ、AttribrandomizeノードのAttributeの名前をPscaleにすると

Torusのサイズが元に戻ってしまいます。

という事はpscaleというParameterがあってその値をこのNodeで調整しているという事になります。

今度はPointJitterというNodeを追加しました。

PointJitterノードの以下のParameterを変更しました。

以下の様になりました。

今度はRBD Bullet Solverノードを追加して

地面に衝突させています。

やってみます。

Tutorial通りにやったら一応出来ました。

これって毎回同じように落ちるんでしょうか?

そうみたいですね。

今度は以下に示した様にLightを追加して影を付けています。

やってみます。

まずSmooth Shadingをします。

次にObject Levelに戻ってTorusを選択し

RenderのDisplay AsにSubdivision Surface/Curvesを指定します。

またSmooth Shadingを選択します。

Gridを追加しました。

Enterを押すと勝手にOriginに配置してくれるそうです。

試してみます。

GridがOriginに配置されました。

うーん。

以下の所からGridのサイズを100 x 100に変更しました。

Point Lightを追加しました。

画面が真っ黒です。

LightのIntensityを100にしました。

Torusが見えるようになりましたが、影がないです。

以下のIconにCheckを入れたら

影が現れました。

dを押して以下のBoxを示します。

Lightを選択してOverride Light Map Sizeの値を4096にします。

うーん。これどっちを選択してもダメじゃないですか。

Tutorialを見たらどっちも押さないで閉じていました。

何もしなくても変更した値は保持されるみたいです。

結果です。

以上でした。

これでFOUNDATIONS | OVERVIEW [9]のThe Houdini Workspaceは終わりでした。

7.3 FOUNDATIONS | OVERVIEW [9]のThe Houdini Workspaceを勉強した感想

流石にこれは単にHoudiniはこんな感じで使用します。と言う紹介で、これからずっとこんな感じで勉強させられる事は無いと思います。

この調子で勉強させられたら、Nodeの仕組みとかは何にも理解出来ないままになってしまいます。

確認のために次のTutorialであるPanesを見てみます。

7.4 Panesを勉強する

これはたった3分の動画なので最初に軽く全部見てみます。

見ました。

Paneの設定についての解説でした。

やっぱり非常に基本的な事しか説明していません。

これはNetwork PaneのNodeについては後でしっかりしたTutorialを勉強すると思っていて間違いないでしょう。

今、Nodeの説明が全然ないと慌てる必要は全くないと思われます。

あー良かった。

一応、PaneのTutorialもやっておきます。

試しにSquabと言うNodeを探して配置してみたら

Tutorialと同じMonsterがViewportに配置されました。

以下のButtonを押してScene Viewを拡大します。

一番下にあるTimelineは消えないんですね。

Tabの話とかしています。

これらは先週、自分で勉強したのでここで説明される範囲の事は既に理解しています。

以下の三角のIconを押すとPaneに関係する機能が使用出来るBoxが表示されます。

これは先週は勉強しませんでした。

以下の3つのIconの機能を説明しています。

このIconの機能はこのTutorialの勉強をする前に散々遊びで使用していたので、既に理解していました。

Tutorialでは以下のようなWindow表示を作成して

DefaultとしてSaveしようとしています。

いやそれ真似して元の標準のWindow形式に戻れなくなったらどうしたら良いですか?

一寸この部分は自分でやるのは止めておきます。

以下のBuildで色々なWindow形式を選択できるそうです。

Technicalを選択しました。

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

Radio Buttonつまり以下に示したUIも違うと言っていました。

うん。

全く同じじゃね。

あ、分かりました。

これはBuildの隣にあるMainの話でした。

Mainを開くと以下に示したようなBoxが現れ

例えばOceanを選択すると以下に示したようなRadio Buttonが表示されます。

こういうUIをRadio Buttonと呼ぶのに一寸抵抗があるんですが、一般的な名称何でしょうか?

調べたら以下の様な形状しか出て来ませんでした。

以上でした。

うん。

これくらいの内容が最初のTutorialとしてはまあ無難でしょうね。

7.5 View Toolsを勉強する

流石にこれだけだと一寸短い気がするのでもう少しだけ勉強します。

次のTutorialであるView Toolsを見ます。

何を勉強するのかと思ったらViewportの操作方法についてでした。

うーん。

一番嫌いなヤツです。

まあ勉強しない訳にもいかないのでやりますか。

<Tumble、Track、Dolly>

この操作方法を表す単語は初めて聞きました。こっから調べることにします。

まずTumbleですが、回転しながら落ちる事を指すそうです。

Mouseの左Clickで出来ます。

これってObjectをLockしてカメラがそのObjectの周りをまわるやつです。

Tumbleと言う言い方がどれだけ一般的なのかは不明です。

Trackです。

MouseのMiddleボタンを押す出来ます。

これはPanningの事ですね。

画面がそのままSlideして動きます。

Dollyです。

まずDollyの意味ですが、以下に示した様に台車と言う意味がありました。

映画産業でこの台車の上にカメラを載せて撮影したのが由来で、

以下に示したようなレールの上を走るカメラで撮影したのとDollyというようになったそうです。

ふーん。勉強になりました。

Mouseの右Buttonです。

これはZoomでした。

調べていたらThe 16 Types of Camera Shots & Angles (Video Guide) [10]に色々なCameraの動かし方が載っていました。

DollyはZoomとは全然違うみたいです。

うーん。でもこのサイトに紹介されている例を見ても同じにしか見えません。

Trackの解説です。

分かりました。

カメラ自体の位置を移動しないで撮影した場合がZoomやPanで、カメラ自身が移動して撮影した場合はDollyやTrackになるんです。

これだわ。

Tumbleはこのサイトにも無いですね。

見つけました。

このサイト[11]に以下の分かりやすい図が書かれていました。

これ何のサイトなのかすらよく分からないんですが、このCameraの動きの説明はこれ以上ないくらい分かりやすいのでそのまま引用させてもらいました。

要するにCameraが対象物(原点?)に対して回転して撮影するのがTumble、前後に動いて撮影するのがDolly、上下左右に動いて撮影するのがTrackになる訳です。

完璧に理解しました。

Camera Viewを選択していない時でも

AltかSpace Barを押しながらMouseで同じ操作をするとTumble、Track、Dollyが行えます。

<Space Bar + AもしくはSpace Bar + G>

Space Bar + Gで選択しているObjectにFocusした位置にCameraが移動するそうです。

Space Bar + Aで全体を移す位置にCameraが移動するそうです。

試してみます。

以下の様にObjectを3体配置してみました。

Squabを選択した状態でSpace + Gを押してみます。

Squabだけを映すようになりました。

Space + Aを押します。

この画面に戻りました。

今度はCragを選択しました。

Space + Gを押します。

Gragだけ映すようになりました。

全然関係ないですが、Houdiniの座標はYが上です。

結構びっくりです。

Alt + Gでも同じ事が出来るか試してみました。

以下のWindowが開かれました。

出来なかったです。

これぐらいで今週のHoudiniの勉強は終わりにします。来週はView Toolsの続きを勉強する事にします。

8. Volumetric Cloudの勉強内容をまとめる

先週、今までのVolumetric Cloudの勉強内容をまとめていたら、以下にあるSample Mapを使用すると

Paint用のWidgetが正常に作動する事を発見しました。

このPaint用のWidgetを使用すると

が可能な気がします。

今週はこれを確認します。

8.1 Paint_Cloudで雲を作成

今、Paint_Cloudを開いて見たら以下の様になっていました。

Load Buttonを押したら以下の様なError Messageも出て来ました。

以下に示したのが私がUnreal Engine Volumetric Paint Clouds Tutorial [12]に載っていたやり方で作成したPaint用のMapのWidget表示です。

はい。

全く同じでした。

という事は、先週の

は間違いという事になります。

まあでも100%先週の判断が間違っていたと言うのも言い過ぎで、私が作成したPaint用のMapは最初は以下に示したようなWidgetだったので

以下に示したPaint_CloudのWidgetと比較したら

Widgetが全部正常に作動しているような気になってしまうのも仕方ない部分があります。

更に言うと以下に示したようなPaintが名前にあるMaterialしか雲を表示しませんでした。

以下に示したM_VolumetricCloud_03_MultipleProfiles…のMaterial達は雲を表示する事は無かったです。

つまりこれらのMaterialはまた別の目的のために使用するという事です。

まだVolume Cloudには謎が多いです。

8.2 Volumetric CloudのTutorialの構成について

結局、先週夢見たPaintで作成した雲をSaveして自在に使用する方法を教えるTutorialを作成する事は無理と分かりました。

ので前からの計画である以下のTutorialを作成する事にします。

8.3 Volumetric Cloudについての状況をUser目線で整理する

この章の目的は、UE5でGameを作成している人達にVolumetric Cloudの使用方法を理解してもらえるようなTutorialを作成する事にあります。

そこでUE5のUser目線でVolumetric Cloudの何が知りたいのか、何処を直したいのかなどについて検証します。

まずVolumetric Cloudそのものについて知らないUserが大半だと思うので以下のような説明をします。

<Volumetric Cloudとは>

Third Person TemplateでProjectを作成すると以下のようなLevelが表示されます。

雲が真ん中で2つに切れているやつです。

OutlinerでVolumetric Cloudを探し、

目のIconをClickして閉じると

以下に示した様に

今まで表示されていた雲が一気に消えました。

この雲がVolumetric Cloudです。

ここでUserの興味を引くために以下のような超上空からVolumetric Cloudを撮影した映像を見せるのも良いかもしれません。

<Userが知りたい事>

ここが私の興味のある所と一般にUEでGameを作成している人の違う所で、私の興味は

  • どうやってVolumetric Cloudが作成されているのか
  • 使用されているMaterialの実装
  • PaintとかPlaceなどのPluginにあるVolumetricの使用方法について

などですが、一般にUEでGameを作成している人の興味は

  • Gameに使用するにはどうしたらいいのか
  • もっと質の高い雲を表示したい。(Assetを買ってもいい)

である感じがします。

なのでTutorialを作成するなら、

  1. これよりも質の高い雲の作成方法を教える。
  2. このTutorialはVolumetric Cloudについて理解するのが目的で、Gameに使用したり、質の高い雲を作成したりするのが目的ではありません。と明言する必要があります。

のAかBを選択する必要があります。

となるとやっぱりAを目指すしかなくなります。

うーん。よし分かりました。

8.4 今までVolumetric Cloud関連で使用したParameterの調査

まずVolumetric Cloud関連のParameterについての説明からやります。

これは、今週の戦闘システムの所でも少しやりましたが、しっかりここで整理します。

まず今までのTutorialで使用したparameterを以下に示します。

<Volumetric Cloud>

  • Layer Bottom Attitude
  • Layer Height
  • Use per Sample Atmospheric Light Transmittance

<Directional Light>

  • Light Shaft Occlusion
  • Light Shaft Bloom
  • Atmosphere and Cloudの欄全部
    • Cast Cloud Shadowsとその関連
    • Cast Shadows on Clouds
    • Cast Shadows on Atmosphere

<Skylight>

  • Atmosphere and Cloudの欄全部
    • Cloud Ambient Occlusion

以上でした。

今週はこれらの機能について調べてここにまとめます。

8.5 Volumetric Cloud関連で使用したParameterの機能について

以下にParameterの機能をまとめます。

と思ったんですが、戦闘システムの所で既にやっている箇所もあります。やっていない箇所だけ調べます。

完全にまとめるのは来週にします。

<Volumetric Cloud>

まずVolumetric Cloudそのものですが、知っておくべきParameterは以下の3つです。

<<Layer Bottom Attitude >>

これは戦闘システムの所でまとめました。

<<Layer Height>>

これも戦闘システムの所でまとめました。

<<Use per Sample Atmospheric Light Transmittance>>

これです。

こんな解説がありました。

うーん。これって重要なんでしょうか?

使用しても差があんまり分からないです。

使用前です。

使用後です。

このParameterは2022-07-18のblog によるとBen Cloward先生のVolumetric Clouds - Building Worlds In Unreal - Episode 32 [13]で勉強したみたいです。

2022-07-18のblog には

こんな解説がありました。

この解説の言っていることはよく分からないんで、もう一回Volumetric Clouds - Building Worlds In Unreal - Episode 32 [13]の解説を見ます。

以下の箇所からTranscriptを表示させます。

表示したTranscriptからUse per Sample Atmospheric Light Transmittanceを探すと

18:01にありました。

Tutorialのその辺を見るとこのParameterの意味が分かりました。

まずここでSampleと言っているのは多分Objectの事でしょう。

そうすると以下のような意味になります。

まず全てのObjectがLitされるときにある値を使用します。

その値はすべてのObjectで同じ値が使用されています。

ところがこのParameterにCheckを入れると、それぞれのObject毎に違う値を使用してLitを計算するようになります。

はい。こういう意味でした。

Tutorialの例ではこのParameterにCheckを入れた場合と入れない場合は結構違っていました。

試しに太陽を雲の後ろ側に移動してみました。

無い場合です。

ある場合です。

ある場合の方が雲の端が白くなります。

ただBen Cloward先生なんかは、無い方が綺麗じゃない。と言っています。人それぞれでしょう。

<Directional Light>

Directional Light内のParameterでVolumetric Cloudに関係しているParameterは、Light Shaft Occlusion、Light Shaft BloomそしてAtmosphere and Cloudの欄にあるParameter全部です。

<<Light Shaft Occlusion>>

これは戦闘システムの所でまとめました。

<<Light Shaft Bloom>>

これは戦闘システムの所でまとめました。

<<Atmosphere and Cloudの欄全部>>

この欄の中で特に重要な以下の3つについて解説します。

<<<Cast Cloud Shadowsとその関連>>>

これは戦闘システムの所でまとめました。

<<<Cast Shadows on Clouds>>>

このParameter、DefaultでOnになっています。

のでOnのままでいいでしょう。

<<<Cast Shadows on Atmosphere>>>

このParameterもDefaultでOnになっています。

<Skylight>

Sky LightでVolumetric Cloudに関係するParameterはCloud Ambient Occlusionだけです。

<<Atmosphere and Cloudの欄全部>>

<<<Cloud Ambient Occlusion>>>

これは戦闘システムの所でまとめました。

8.6 DefaultのVolumetric CloudのMaterialに使用されているm_SimpleVolumetricCloud_Instの親Materialである m_SimpleVolumetricCloudを改良して好きな形状の雲を作成する

やっぱりUE5のUserからしたら「自分が望む雲の形状を作成したい。」と言うのが一番の望みでしょう。

その方法をここにまとめます。

まずVolumetric Cloud専用のProjectを作成します。Volumetric Cloud Testと名付けました。

このProjectを開いて新しいLevelを作成します。

以下の様になりました。

この雲の形状を変更します。

まずこの雲をはるか上空から見ると以下の様になっています。

これが平面の雲の形状です。

更に、雲を正面から見ると以下のような形状になっています。

これらは、Volumetric CloudのMaterialにセットされているm_SimpleVolumetricCloud_Instの

親Materialであるm_SimpleVolumetricCloudの

以下の部分示した実装の

Texture Sampleノードで指定されています。

この①のTexture SampleにセットされているCloudWeatherTexture

の以下に示したRのImageが

以下に示した様に雲の平面の形状を作成しています。

雲の正面のImageは以下に示したCloudWeatherTextureにセットされているGのImageと

②のTexture SampleノードにセットされているCloudGradientTextureの

以下に示したImage

で以下に示したような形状が形成されます。

こっちは少しだけ複雑です。

今回はやり方の説明じゃなくて、実際にやってみてその結果を載せる事にします。

Texture Sampleの①に以下のImageを作成しました。

Texture Sampleの②に以下のImageを作成しました。

これで雲を作成します。

以下のような雲が形成されました。

上空から見ると以下の様になっています。

Texture Sampleの①にセットしたImageのRのImageと同じ形状です。

正面から見た場合です。

キノコ上の形状になっています。

これはTexture Sampleの①のGのImageとTexture Sampleの②のImageから製造されています。

少しだけ離れた所から撮影しました。

今週は2枚のTextureのImageを変える事で雲の形状をある程度変更出来る事を示しました。

もう少し具体的な内容は来週以降詰めます。

9. DirectXの勉強

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

その後で「DirectX 12の魔導書」、「HLSLシェーダーの魔導書」と「Direct3D 12 ゲームグラフィック実践ガイド」を勉強します。

9.1 C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window[14]を勉強する

まず前のTutorialで作成したFile一式をDuplicateしてEpisode2と名付けています。

<Episode Two Folder>

丁度いいので2023年の勉強用のFolderにDuplicateしました。

<A Windows Process>

DuplicateしたFileにあるSlnを実行します。

開かれたVisual Studioを実行します。

結果です。

普通に動いています。

このWindowを閉じようとしてxのIconを押します。一見Windowは閉じたように見えますがProgramはBackgroundで動き続けています。

Tutorialによるとその理由は以下に示したCodeに理由があるそうです。

これって去年の最後の方で日本語の3つの教科書で勉強してたやつじゃないですか。

何をやっていたのか確認します。

まずDirectX 12の魔導書ですが、2022-12-04のblogで以下の実装を作成しています。

しかしこの実装がどんな機能を持っているのかは全く分からない。ただ本にそうやって書けと言われたから書きました。とだけ書いています。

2022-12-12のBlogDirect3D 12 ゲームグラフィック実践ガイドの「2.2 アプリケーションクラスの作成」にWindows Procedure()関数の機能についての説明が書いてあったと書いてあります。

それによると

となっています。

それじゃ、以下に示した様に、WNDCLASSEX.lpfnWndProcにこの関数を実装して使用する必要があるんじゃないの?

となって C++ DirectX 12 Game Engine - [S01E01] - Creating Our First Window [15]の実装を確認しています。

その結果、

しかなくて、しかもDefWindowProcが何なのか何処にも指定していない事に困惑しています。

HLSLの魔導書のSample CodeもWindow Procedure()関数を使用してないはずと確認しています。

するとHLSLの魔導書では、以下に示した様に

しっかりWindow Procedure()関数を実装していました。

成程ね。

C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [14]でも、ここでWindow Procedure()関数を実装するんでしょうね。

その前にDirect3D 12 ゲームグラフィック実践ガイドの「2.2 アプリケーションクラスの作成」のWindow Procedure()関数についての説明を読み直しましょう。

以下の図がとても分かりやすいです。

Direct3D 12 ゲームグラフィック実践ガイドの2.2 アプリケーションクラスの作成、図2.8 ウィンドウシステムの概略より

この図に基づいて、先程のWindowに表示されているX Buttonを左Clickした場合を考えてみます。

まずX buttonを左Clickした訳ですが、この図の右端のキーボード、マウスなどからEventが発生したのと同じ事が起きたはずです。

するとWindow OSに通達が行きます。

はい。

そしてMessage Queue にWindowに表示されているX Buttonが押されたよ。と言うWindow Messageが追加されます。

その通知をWindow Procedureに通知します。

しかしC++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [14]ではまだ、Window Procedureを実装していないので、ここでProgramを終了しろ。と言う命令をWindow OSに発する事は出来ません.

のでWindowは閉じてもProgrammingはBackgroundで動き続けます。

はい。

大体こんな感じでしょう。

C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [14]の勉強に戻ります。

まず以下の関数を追加します。

やっぱし。

と思いましたが、結構細部は違います。

まず関数の名前が、WindowProcedureではなくWindowProcessになっています。

Tutorialの解説によるとこの名前は何でも良いそうです。

まあ、ここで関数そのものを作成しているのならそうなりますね。Overrideした場合は違いますが。

この関数はLResult型を返します。

ので、以下に示したDefWindowProc()関数を返す事にしたそうです。

この部分は他のTutorialでも同じはずです。

確認します。

DirectX 12の魔導書」の場合ですが、

同じ関数を返しています。

ただParameterの名前が違うのもありますね。この辺の細かい違いは後で確認します。

「HLSLシェーダーの魔導書」の場合ですが、

こうなっていました。

後、ここで使用されているParameterですが、

WindowProcedure()関数の方で定義されていました。

あれ?

「HLSLシェーダーの魔導書」でもMsgProc()関数と言う名前の違う関数になっていますね。WindowProcedure()関数と言う言い方は一般的じゃないのかもしれません。

まあここでは、MsgProc()関数もWindowPrcess()関数もWindowProcedure()関数と呼ぶ事にします。

まあ、その辺はやっていく内に理解出来るでしょう。

もう一回、C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [14]のWindowProcedure()関数を確認します。

はい。他のWindowProcedure()関数と全く一緒です。

次にCALLBACKについて解説しています。

CALLBACKは関数のLogicを変更する能力を持たせると言っています。

うーん。

CALLBACKが何をするのか全く覚えていません。調べます。

調べたらCALLBACKそのものの定義は沢山出てきたんですが、関数の宣言部分にCALLBACKと書く理由について解説しているSiteは見つかりませんでした。

というか関数のこの部分で宣言しているモノの一般的な名称自体忘れてしまっています。

のでこれはまた後で調べます。

それぞれのParameterについて解説しています。

最初のParameterであるHWND hWndですが、

Window HandleのCopyだそうです。

2番目のParameterですが、

Message型のParameterだそうです。

このParameterはWindow Close Message型だったり、Window Resize Message型だったりするそうです。

三番目と四番目のParameterは

このMessageのArgumentだそうです。

この値によってMessageの受け取られ方を変更する事が出来るそうです。

何!!

これって結構重要な情報です。

次に以下のCodeを追加しました。

もしmessageがWM_DESTROYだったらPostQuitMessage(0)を実行しろ。という事ですね。

これがProgrammingの実行を終了するためのEventを発生させるんでしょうか?

そして以下に示した様に.lpfnWndProcにこの関数を指定しています。

そして、もう一回Programmingを実行してWindowを開き

Windowの右端にあるX Buttonを押してWindowを閉じています。

そして今度は、Windowが閉じた時に、同時にProgrammingの実行も終了しました。

うーん。

成程、WindowProcedure()関数がどんな働きであるのかよく分かりました。

よく理解しているうちに自分のProjectの実装もやってしまいます。

まずは以下の関数の枠組みを作成しました。

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

これでWindowを閉じた時にProgramの実行も止まるためのEventが発生するはずです。

最後にwcex.lpfnWndProcにこの関数をセットします。

これで完成のはずです。

テストしてみます。

実行しました。

普通にWindowが表示されました。

それではWindowの右端にあるXのIconを押します。

Windowが閉じただけではなくProgramも終了しました。

出来てます。

ここでキリがいいので今週はここまでとします。

9.2 DirectX 12の魔導書を勉強する

去年書いたCodeから推測すると「3.2.1 ウィンドウの生成」の途中までやったようです。

今週は、Windowを表示させる所までやる事にします。

まず以下に示したShowWindow()関数を追加します。

Windowが表示されました。

この実装の解説の所には一瞬だけWindowが現れて消える。と書いてありましたが、私のはずっと残っています。

多分以下のCodeのせいだと思います。

Comment outしてしまいましょう。

う。

Comment outするためのShort Cutを忘れてしまいました。

月日の経つのは早いです。

Visual Studioを毎日のように触っていたのはもう何年も前の事になりました。

調べたらCtrl + K + Cでした。

今度はWindowは一瞬だけ表示されて消えました。

Message Loopを追加します。

結果です。

今度はWindowはずっと表示されていました。

Windowを閉じるとProgramの実行も止まりました。ただし開いたConsoleは閉じません。

まあ出来てはいます。

開いたConsoleが閉じないのは、Visual Studioの設定によるせいでしょう。

うーん。

Codeを一寸だけ読んでみます。

MsgにMessageをパスしてそれが、うーん。分からん。特にRM_REMOVEが分からん。

PeakMessage()を調べます。

公式のPeekMessageA function (winuser.h) [16]に詳しい説明がありました。

まずPM_REMOVEですが、

QueueにあったMessageは消されるそうです。

そんだけでした。

Return Value

0か0以外が返されるそうです。

C++では0以外がTrueで0がFalseだったはずです。

となるとMessageがある限り最初のIfはTrueになりますね。

TranslateMessage()関数は何をしているんでしょうか?

今度はこれを調べます。

公式のSiteのTranslateMessage function (winuser.h) [17]に解説がありました。

要するにこれでMessageが人間にも読めるようにしているんでしょう。

あ、分かった。

これ人間に読めるように変換するんじゃなくて、WindowProcedure()関数に読めるように変換しているんです。

となるとDispatchMessage()関数は翻訳したMessageをWindowProcedureに送る役割をしているはずです。

一応、確認します。

公式SiteのDispatchMessage function (winuser.h) [18]をみると

やっぱりそう書かれていました。

そしてもしmsg.messageがWM_QUITだったらLoopを中止してWindowを閉じるわけです。

うーん。

成程。

あれ?

他のTutorialはどうやってWindowを表示し続けていたんでしょう。

いやWindowを表示し続けるのは出来るかもしれませんが、

TranslateMessage()関数やDispatchMessage()関数を使用しないでどうやってMessageをWindow Procedureに送っていたんでしょうか?

確認します。

C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [14]の場合です。

思いっきり同じ事していました。

むー。

全く覚えていなかったです。

この事をC++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [14]ではMessage Eventと呼んでいたんですね。

HLSLシェーダーの魔導書の場合も以下に示したようなほとんど同じCodeがありました。

うーん。でもこの実装だとmessageがWM_QUITじゃなくてもmessageが無くなったらLoopが終わってしまいます。

ので完全に同じではないですね。

Direct3D 12 ゲームグラフィック実践ガイドはまだここまで勉強していないはずです。

はい。

今週の「DirectX 12の魔導書」の勉強は、3.2.1ウィンドウの生成を最後まで読み、所謂Message Eventと呼ばれる機能について勉強しました。

9.3 HLSLシェーダーの魔導書を勉強する

「HLSLシェーダーの魔導書」はどこまで教科書を読んだのか忘れてしまいました。

それから調べます。

思い出しました。

「HLSLシェーダーの魔導書」はWindowの作成方法の説明が無くて、いきなりDirectXを使用して三角形を表示する所から始まっているので、他の教科書がDirectXの話をするまでPendingしていたんです。

はい。

それじゃ今週も「HLSLシェーダーの魔導書」の勉強はお休みですね。

9.4 Direct3D 12 ゲームグラフィック実践ガイドを勉強する

今週は「2.2 アプリケーションクラスの作成」を読みます。それだけやります。

まず軽く全部読みました。

Win32(Windows API?)を使用したWindowの作成方法について解説しています。

他の教科書と違うのは、App Classを作成してそこでWindowの作成を処理している所です。

つまりMain()関数からはApp Class呼び出しているだけになる実装形式を取っています。

最初、何をしているのかよく理解出来なくて混乱しました。

以下の方法で勉強する事にしました。

まずこのApp Classの構造についてまとめます。

次にこのApp Classの中でどうやってWin32 でWindowを作成するための実装が行われているのかについてまとめます。

最後に、Windowを作成するための実際のWin32の実装を他の教科書の実装と比較してどうなのかを検証します。

<App Classについて>

最初に何でApp Classを作成するのかについて説明がされていました。

簡単にその説明をまとめると、

Windows APIを用いてWindowを作成する方法はどのAppでも全く同じなので、一回クラス化してしまえば、全部のAppでそのクラスを呼び出すだけでWindowを作成出来るので後が楽。」

という事でした。

うーん。ひょっとして「HLSLシェーダーの魔導書」でWindowの作成方法についての解説が載ってないのはこのせいなの?

Windowsの作成方法を何年も前にClass化してしまってそれを呼び出しているだけだから、説明する必要も感じてないし、逆に説明しろって言われても既に細かい点は忘れてしまった。って感じなのでしょうか。

確認します。

「HLSLシェーダーの魔導書」のSample Codeを見ましたが、windowを作成するためだけのClassを作成しているという感じではなかったです。

まあ良いです。

Direct3D 12 ゲームグラフィック実践ガイドの勉強に集中します。

App Classの構造は簡単に言うと以下の様になっているみたいです。

  • 初期化
  • Messageの取得
  • そのMessageをWindow Procedureに送る

この初期化で、Window Classを作成したり、CreateWindow()関数を作成したりするんでしょうか?

Messageの取得とそのMessageをWindow Procedureに送るのは、他の教科書では、以下のような実装で一緒にやってしまっています。

敢えて分ける必要あるんでしょうか?

それともこの部分とは違う所の話なんでしょうか?

後、この中ではWindowProcedure()関数の話は出て来ませんね。

この関数は、Window Classを作成する時に使用されるので初期化の工程に含まれているんでしょうか?

続きを読みます。

<App Classの中のWindowを作成するための実装について>

App ClassのPublic なMember Functionは以下の3つだけでした。

これ実際に使用する関数はRunだけじゃない?

と思っていたら以下の様にPrivateなMember Functionがありました。

これ初めて見た時、Termって何?ってなったんですが、Terminationの略みたいで、終了時に呼び出すための関数でした。

後は、その名前から何をするための関数であるか想像つきます。

今度は実装を見てみます。

Run()関数の実装です。

MainLoop()関数の実装が分からないと何をしているのか分からないですね。

InitApp()の実装です。

InitWnd()関数を呼び出しているだけですね。

うーん。

入れ子構造過ぎないでしょうか。

まだWindowを作成するための実装が現れません。

やっとInitWnd()関数の実装が出て来ました。

Window Classを作成していますね。

Window Procedure()関数はどうでしょう。

以下に示した様にWc.lpfnWndProcにはWndProcを指定しています。

今の所、このWndProc()関数については何の解説もないです。

CreateWindow()関数もここで使用していました。

続きを読んでいたら、いきなりWndProc()関数の実装が載っていました。

WndProc()関数に関する説明が無くていきなり感がありました。

次がMainLoop()関数です。

ここではWindow ProcedureにMessageを送るためのおなじみの実装がありました。

やっぱり一体化していました。

最後にMainからApp Classを使用してWindowを作成する時の実装が載っていました。

非常にスッキリです。これならWin32を全く知らない人でも使いこなせます。

<実際のWin32の実装を他の教科書の実装と比較>

これは実装が終わってからやります。

それよりもApp Classの使用に対しての感想をまとめる事にしました。

<App Classを使用する事に対しての感想>

App Classを使用する事で、Win32を知らない人でもWindowの生成が出来るようにしたのは、凄いと思います。

しかしApp Classの実際の構成が最初の構想とかなり違う気がします。

これってそういうもんなんでしょうか?

何か納得できない気持ち悪さを感じます。

まあ、実際に実装してみてたら又感想が変わるかもしれません。

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

10. まとめと感想

今週は、量をSaveしながら勉強したので先週のようにやり過ぎて時間が無くなってしまったという事は無かったです。量はこれぐらいが丁度いい感じです。

後、前文を書く時間がまだないです。

前文を書く事こそが、私の楽しみなので、近い内に必ず復活させます。

11. 参照(Reference)

[1] Klaus. (2022, May 21). How To BUILD AN ISLAND In 20 mins | Unreal Engine 5 Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=Obfq-Zh3iXs

[2] Sky Light. (n.d.). Unreal Engine 4.27 Documentation. https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/LightingAndShadows/LightTypes/SkyLight/

[3] renderBucket. (2022, April 28). Unreal Engine 5 Tutorial - Niagara Fluids - Flamethrower [2/2] [Video]. YouTube. https://www.youtube.com/watch?v=28YFVQjgwbA

[4] renderBucket. (2022b, December 4). Unreal Engine 5 Tutorial - Shading Niagara Fluids - Honey [Video]. YouTube. https://www.youtube.com/watch?v=iHxNQE9n_Gw

[5] Zhang, C. & Xue, Daqing & Crawfis, Roger. (2005). Light propagation for mixed polygonal and volumetric data. CGI: Proceedings of the Computer Graphics International. 249- 256. 10.1109/CGI.2005.1500434.

[6] Ben Cloward. (2022b, October 13). Rock Shader - Advanced Materials - Episode 3 [Video]. YouTube. https://www.youtube.com/watch?v=Q2XI8cuSBMk

[7] Unreal ART - Unreal Engine tutorials. (2022, August 20). Unreal Engine 5 tutorial _How to Reduce your project size [Video]. YouTube. Retrieved October 18, 2022, from https://www.youtube.com/watch?v=h8BhgG6MEnM

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

[9] Magee, R. (n.d.). Foundations | Overview | SideFX. https://www.sidefx.com/tutorials/foundations-overview/

[10] The 16 Types of Camera Shots & Angles (Video Guide) | Boords. (2023, January 11). boords.com. https://boords.com/blog/16-types-of-camera-shots-and-angles-with-gifs

[11] Alias Help. (n.d.). http://desprod.dmu.ac.uk/alias_2010/index.html?url=WS73099cc142f48755360aa6ed11a9c1effaa-69e6.htm,topicNumber=d0e7382

[12] Zero Conditional. (2021, March 2). Unreal Engine Volumetric Paint Clouds Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=SlR3eDr4jQc

[13] Ben Cloward. (2021, May 27). Volumetric Clouds - Building Worlds In Unreal - Episode 32 [Video]. YouTube. https://www.youtube.com/watch?v=dolfk2z4LDo

[14] OlympusMonsTutorials. (2021, March 3). C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [Video]. YouTube. https://www.youtube.com/watch?v=rWylZKi8QbM

[15] OlympusMonsTutorials. (2021, February 17). C++ DirectX 12 Game Engine - [S01E01] - Creating Our First Window. YouTube. https://www.youtube.com/watch?v=2vrEIhAajhM

[16] PeekMessageA function (winuser.h) - Win32 apps. (2022, August 23). Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-peekmessagea

[17] TranslateMessage function (winuser.h) - Win32 apps. (2022, August 4). Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-translatemessage

[18] DispatchMessage function (winuser.h) - Win32 apps. (2022, July 28). Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-dispatchmessage