UE4の勉強記録

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

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

1.今週の予定

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

UE5.2でLandscapeを作成し直す。

  • LandscapeをNanite化する
  • Water SystemのRiverを追加する
  • 先週までのFoliageのテストをもう一回5.2で試す

Niagaraの勉強>

CGHOW氏のRibbon Fire in Unreal Engine 5.2 Niagara Tutorial [1]を実装します。

<Materialの勉強>

Ben Cloward先生のAdvance Material Tutorialを勉強します。

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

BGMを追加します。

<Gaeaの勉強>

Colorの勉強か、Buildの勉強をします。

<Houdiniの勉強>

今まで勉強したFOUNDATIONS | OVERVIEW [2]の復習をします。

<UEFNの勉強>

UEFNの勉強の続きをします。

YouTube動画の作成>

Davini Resolveを使用して動画の作成の練習をします。

DirectXの勉強>

 C++ DirectX 12 Game Engine - [S01E03] - Creating A Game Engine [3]のFinishing Touchesを勉強します。

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

2.1 UE5.2でLandscapeを作り直す

新しいProjectをUE5.2で作成するのか、それとも先週UE5.2で作成したProjectをそのまま使用するのか迷っています。

うん。Height Mapから作り直したい気持ちもあります。

現在のMapだと砂浜と海の部分が同じ高さなので

Occeanを配置した時に、差が出ません。

このLandscapeの元のHeight Map自体があんまり良くないです。

作り直します。

2.2 GaeaでLandscapeを作成し直す

今回は試しという事でTemplateを使用します。

以下のMaskを追加しました。

Buildの設定を忘れてしまいました。

2023-01-08のBlogにBuildの設定が載っていました。

これをそのまま利用します。

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

出来ました。

2.3 新しいProjectでLandscapeを作成する

以下のLandscapeを作成しました。

Materialは先週作成したのを使用しました。

Shader Complexityを見ます。

うーん。

それなりに重いです。

LandscapeをNanite化します。

もう一度、Shader Complexityを見ます。

うーん。

Nanite化するだけでこんなに負担が減るんですね。

今度はここにWater Systemを追加します。

しました。

Packagingしてみます。

Packagingの設定を忘れてしまいました。

2023-01-08のBlogにPackagingのやり方がまとめられています。

それで復習しました。

Packagingする前にHLODでBuildもやっておきます。

Buildが失敗しました。

これは理由があって、Water SystemのOcceanで谷に水を貯めようとして色々やって一寸Levelがおかしくなってしまったんです。

再起動したら普通に水が写っていたんで、直ったと思ったんですが駄目だったみたいです。

一応、Packagingしてみます。

Packagingは普通に出来ていました。

Exe. Fileを起動します。

うーん。

普通に川も湖も再現されています。

今度は川の周りに岩を配置します。

以下の岩をMega ScanからDownloadしました。

以下の様に湖と川の周りに岩を並べました。

当然ですが、岩もNaniteです。

CameraのSpeedが上手設定出来ません。

Short Cutを調べます。

Mouseの右Buttonを押しながら、Wheelを回転するとCameraのSpeedの値を調整できるようです。

出来ました。

こっちは簡単に出来ます。

結果です。

岩は片面しかないStatic Rockは役に立たないです。

大きさは5倍とかにしても気になりません。最初は大きな岩で大体の形状を作成して、その後で小さな岩で細かい部分を補う事にすると作業効率が高まります。

以下の様に渓谷を覆ったら、下の部分が洞窟みたくなるのか試して見ます。

以下の様に覆ってみました。

Playして確認します。

なんと

裏側は透けていました。

使用しているMaterial Instanceの設定をTwo Sideにしてみます。

結果です。

だめですね。

ならば岩を10倍の大きさにして覆ってみました。

Playして渓谷内に侵入します。

洞窟にはなっていますが、とても歩けるような状態では無いです。

洞窟の入り口から覗くとFogが凄いです。

うーん。

Fogの調整とかも必要になるのか。

まだまだ勉強すべき事が沢山あります。

調べたら

NumenBrothers氏がLet's Build the RPG! - 56 – Landscape Cave Sculpting and Lighting – Unreal Engine 5 Tutorial [4]でCaveの作成方法やCave内でのLightの設定方法について解説していました。

これ軽く見たんですが、かなり勉強になりました。

後で、しっかり勉強する事にします。

2.4 Foliageを追加してみる

以下の様に川の周りにRiver Layerを追加しました。

このRiver LayerにRockをFoliageで追加します。

しました。

実際に歩いてみるといい感じです。

Landscapeの小石とFoliageの小さな岩と手動で配置した大きな石のバランスが良いです。

色は少しオカシイです。

岩にCollisionを追加するのを忘れていました。

今回はこのまま行きます。

川の上流まで登って来ました。

こんな急な所で水が流れていたら滝になっているはずです。

後、向こう岸の川辺のLandscapeは単なる灰色になっていますが、ここは小石が見えてほしいです。

後は川の色です。

水色過ぎます。

まず直し方の分かる川辺のLandscapeの小石と灰色の境界から直します。

以下の様になりました。

うん。

なんか川の追加方法が分かって来ました。

<川の追加方法について>

今回のように適当に川を追加すると変な川が形成されます。

のでGaeaのRiverの機能を使って適切な場所に川を形成する必要があります。

後、Landscapeの大きさもGaeaの元々の大きさを維持すべきかもしれません。勝手にサイズを変更していましたがその結果、川が非常に細くなってしまう事がありました。

しかしこの川辺に使用しているMaterialは凄いです。これだけで川岸っぽい感じがでています。

<Foliageについて>

Foliageに関しては数が1000個位しか配置していないので遅延は全く起きてないです。

以下の箇所にLandscapeの境界があります。

ここで遅延が起きる可能性はあります。

しかしもっと別な問題がこのLandscapeとこの川にはあります。

のでこのLandscapeを使用するのは今週だけにして来週は新しいLandscapeを作成する所からやり直します。

<今週のまとめ>

今週、Landscapeに川を適当に自分で追加して、ある問題に気が付きました。

それは、川が流れるべき箇所と言うのはLandscapeの形状によって一義的に決まってしまうので勝手に川の場所を自分で決定するへんな川が形成されるという事です。

更に、前回まで使用していたLandscapeはサイズがGaeaの時よりかなり小さくしているので、川のサイズが20㎝程度になってしまい、現実味が無くなってしまいました。

ここから、

  • 川は必ずGaeaで生成する。
  • GaeaのTerrainのサイズはUEでLandscapeを生成するときも守る

をまもる必要がある事が判明しました。

今からGaeaでLandscapeを作成し直す時間はありません。今週のGaeaの勉強でRiverの追加を勉強するか、もしくはTerrainを作成する事にします。

後、Landscapeに洞窟を追加する方法ですが、NumenBrothers氏がLet's Build the RPG! - 56 – Landscape Cave Sculpting and Lighting – Unreal Engine 5 Tutorial [4]で説明しています。

今週は軽く見ただけですが、来週しっかり勉強する事にします。

今週のLandscapeの作成は岩を並べる事に時間が大幅に取られました。

ほとんど岩を並べていただけな気がします。

岩を並べて気が付きましたが、以下のような池は、自然には発生しません。

もっと川の写真を見て自然の川の周りにどんな岩や砂が形成されているのかを観察する必要があります。

Googleで、「川、上流」で検索したら以下のような写真が出て来ました。

なんか、私が今回作成した川とは全然形状が違います。

そうだ。

岩が水に濡れると黒くなるんだ。

それが一点、更にWater Systemの川の色が水色過ぎます。

これだけ今調べますか。

Unreal Engine 5 Quick Tutorial: How To Change Water Color (Water Plugin)[5]に解答がありました。

何とこのTutorial、30秒の長さです。

今、見る事にします。

DetailのWater MaterialにセットされているMaterial Instanceを開き

そのAbsorptionの値を変更します。

ここで指定した色が水の色になるそうです。

うーん。

Tutorialでは緑色にしています。

このMaterial InstanceってEngineに保管されているやつでしょう。

これ変えちゃったら全部の水の色が緑になっちゃうんじゃないでしょうか?

まあ水の色の変え方は分かりました。

30秒の投資でこれだけ理解出来れば、まあ損した気はしませんね。

Material InstanceをDuplicateして試してみました。

前よりはマシですが、写真そっくりのLevelを作成するまでにはまだまだ長い道のりを歩く必要がありそうです。

川の設定も変えてみました。

こっちはかなり良い感じです。

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

3.Materialの勉強

今週はMaterialを先にやる事にします。なんかMaterialの勉強とDirectX 12の勉強はいつも割り食って勉強に使用する時間が少ない気がします。

順番を変更するとそれが変わるのか試してみます。

3.1 Car Paint Shader - Advanced Materials - Episode 9 [6]を実装する

今週からUE5.2で実装する事にします。

<First Example>

はい。出来ました。

Previewの結果です。

Level上の結果です。

<Chameleon Paint>

これは先程の実装のLerpの値を変更するだけです。

Previewの結果です。

Level上の結果です。

思ったより質感ないです。

何て言うか、奥行きが無いです。

<With Sparkling>

まずVoronoi Noiseを探す事から始めます。

全然、形が違う。

TutorialのTextureは

感じです。

検索で出て来るVoronoi Noiseは以下に示した様な

カエルの卵のようなTextureです。

先週のBlogを読み直したら同じ事言っていました。

Tutorialを見直すと、ここで使用しているTextureの拡大画面がありました。

これは以下のVoronoi Noiseと同じです。

このSiteを見てみます。

Ronja's tutorialsのVoronoi Noise [7]です。

ナニコレ?

Unityなの?

UnityでHLSLの勉強が出来るの?

このサイトの最初のPageに以下の解説がありました。

ふーん。

Unityを使ってHLSLの勉強が出来るのか。

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

まあそれは兎も角、Tutorialで使用しているVoronoi Noiseと同じTextureはこのサイトでは提供していません。

他のVoronoi Noiseは微妙にTutorialのImageと違います。

GIMPで作成しますか。

公式サイトの14.5. Cell Noise [8]にそれらしきものが載っていました。

このサイトのやり方を元にNoiseを作成します。

しました。

一寸明るすぎますね。

Adjust Brightness and Contrastを使用して暗くします。

これで試してみます。

実装です。

それぞれの値は調整しました。

Previewの結果です。

Levelの結果です。

うーん。

Sparklingは少しだけ確認出来ます。

Powerの値を下げてみました。

そんなにキラキラしなくなりましたが、こっちの方が車のPaintっぽいです。

Tutorialで確認しましたがこっちの方がTutorialの結果に近いです。

三つの結果を並べると前の2つより表面のざらつき感が加わった分、更に本物の車の塗料感があります。

<Clear Coatを使用する>

MainノードのShading Modelの値をClear Coatに変更しました。

Clear CoatとClear Coat Roughnessに値をセットしました。

これで表面がWaxを塗ったようになるはずです。

Previewの結果です。

うーん。

どうなんでしょう。

Level上に配置してみます。

言われてみると、確かにWaxが掛かった感じがします。

Clean Coatが無い状態と比較してみます。

うーん。

一見しただけでは差は無いですね。

少なくとも私には違いは分かりません。

Tutorialで確認します。

Roughnessの前にLerpノードを使用するのを忘れていました。

直します。

結果です。

Preview上の結果です。

Clear Colorの値を0にしました。

これは違いが一目瞭然です。

Level上の結果です。

Shading ModelがDefault Litである前のMaterialと比較しています。

うーん。

正直そんなに差は感じません。

<Carbon Fiber>

まず、Textureを探します。

うーん。

ぴったしのが無いですね。

もしかして、と思ってComment欄を見たら

Textureが提供されていました。

うーん。気が付くの遅すぎ。

DownloadしてUEにImportしました。

以下にTextureを示します。

まず実装をします。

Previewの結果です。

凄い。

Carbon Fiberが透明なPlasticに閉じ込められているように見えます。

Level上の結果です。

うーん。Preview程のImpactはないですね。

Carbon Fiberも表面に貼られているようにも見えます。

<Carbon Fiber + Clear Coat>

今度はCarbon FiberをClear Coatを使用して実装します。

やり方は先週のBlogにまとめたやり方に沿ってやりました。

Previewの結果です。

Level上の結果です。

はい。分かりました。

以下の赤線で囲った実装がClear CoatのCoat Enable Second Normalの機能を担当していたんです。

近づいて見ると分かりますが、Clear Coat Bottom Normalノードを使用した方は

本当に透明なPlasticにCarbon Fiberが閉じ込められた感じがします。

一方でMaterialで全部実装した方は

凄く近づくと透明なPlasticにCarbon Fiberが閉じ込められた感じがしなくなります。

Clear Coat Bottom NormalノードはFresnel以外の計算もしていると思われます。

それ以上は分かりません。

<計算Costなどの検証>

最後のCarbon Fiber + Clear Coatは抜群に綺麗に見えましたが、計算Costはどうなのでしょうか?

Shader Complexityを見てみます。

うーん。そんなに計算Costが掛かっている訳でもないみたいです。

Clear Coat Bottom Normalノードを使用して氷の作成をしたら面白そうです。

Clear Coat Bottom Normalノードを使用した氷の作成方法を示したTutorialが無いか調べます。

見つかりませんでした。

今週のMaterialの勉強はここまでです。

いつもMaterialの勉強は短くなるので順番のせいかと思っていましたが、順番変えても同じでした。

実装を習ってもどうやって深堀すれば良いのかが分からないんです。

4.Niagaraの勉強

4.1 Ribbon Fire in Unreal Engine 5.2 Niagara Tutorial [1]を実装する

先週のBlogに手順を細かくまとめたのでそれに沿ってやって行きます。

<Intro>

Niagara Systemを作成します。Templateはいつも通りFountainを選択しました。

UE5.2のNiagara SystemはIconが格好いいです。

<Create Niagara Particle>

Third Person BPを開きました。

MeshにNiagaraを追加します。

実際はNiagara Particle System Componentを追加しました。

以下の様になりました。

Niagara System Assetに先程作成したNSをセットします。

これで本当にThird PersonにセットされるのかPlayを押して確認します。

されていますね。

TutorialはViewportで確認していました。

そっちも一応見ておきます。

NSに戻ります。

要らないModuleを消します。

Particle Spawn SectionにSkeletal Mesh Locationノードを追加します。

Preview MeshにSKM_Quinn_Simpleをセットします。

結果です。

Tutorialの結果とは少し違いますが、Skeletal Meshの形状にSpriteが形成されているのでOKだと思います。

更にMesh Sampling Typeの値をSurface(Triangles)に変更します。

以下の様になりました。

Tutorialの結果は以下の様になっています。

うーん。

原因が分かりません。

Tutorialを見直してみます。

まずParticleのサイズを変えていました。

Particle Spawn SectionにあるInitialize Particle Moduleの以下のAttributeの値を変更します。

生成されるParticleのSizeが小さくなっただけでした。

Tutorialも他に何かやっている感じはありませんでした。

分からん。

どうしたら直るんでしょうか?

Surface Samplingの解説に以下の説明がありました。

CPU Accessが必要になると書いてあります。

多分、これを設定する必要があるんでしょう。

ここで言うSampled Skeletal Mesh AssetはSKM_Quinn_Simpleです。

SKM_Quinn_Simpleを開いてAllow CPU Accessを調べるとありました。

Checkします。

これで直ると思ってNiagaraに戻ると直っていません。

Warningが表示されています。

Fixを押しました。

すると

SurfaceにSpriteが表示されるようになりました。

直りました。

ただしこの変更をSaveすると全てのUE5.2のProjectのSKM_Quinn_SimpleのAllow CPU Accessの設定が変更してしまいます。

うーん。

問題ないでしょう。Saveしてしまいます。

今度はSpriteを一辺に表示して消えないような実装に変更します。

まずEmitter Update SectionにあるSpawn rate Moduleを外してSpawn Burst Instantaneous Moduleを追加します。

Spawn Burst Instantaneous ModuleのSpawn Countの値を200にします。

Emitter Update SectionにあるEmitter State Moduleの

Loop Behaviorの値を

をOnceにしました。

Particle Update SectionのParticle State Moduleの

Kill Particles When Lifetime Has ElapsedのCheckを外しました。

これで完成です。

あ、Skeletal Mesh Location Moduleの位置をParticle Update Sectionに移すのを忘れていました。

先週のBlogに以下の様に書いてあるので

この時点で一回Testする事にしました。

Spriteは普通にQuinnの動きに沿って移動しています。

今度はColorの設定を変更します。

ColorはSpawn Particle SectionにあるInitialize Particle Moduleの

Colorで変更します。

結果です。

Tutorialほど激しく光ってないですね。

Third Personでも確認します。

こっちはTutorialとほぼ同じです。

<Mesh Location>

Tutorialではここで興味深いTestをしていました。

Level上で確認します。

NSは普通にThird Personの動きに沿って移動しています。

ここでSkeletal Mesh Location Moduleの位置をParticle Spawn Sectionに移動します

この状態でPlayをすると以下に示した様にSpriteは最初に生成された位置から移動しません。

Tutorialの説明と同じ結果になりました。

Render SectionにあるSprite Renderer Moduleを消します。

Emitterの名前をSourceに変更します。

と思ったら以下の警告が出ていました。

うーん。

PropertiesのCalculate Bounds Modeの値をFixedに変更してみます。

警告が消えました。

色々Testしましたが、何も問題ないのでこれでやります。

Emitterの名前を変更しました。

新しいEmitterを追加し名前をRibbonに変更します。

Templateは当然、Fountainを使用しています。

Ribbon EmitterのRender SectionにあるSprite Renderer Moduleを消してRibbon Renderer Moduleを追加しました。

次にEmitter Update SectionにあるSpawn Rate Moduleを消してSpawn Particles from Other Emitter Moduleを追加します。

Emitter NameにSourceを追加して

ErrorのFixを押します。

Errorが消えました。

そしてTutorialの説明通り、Particle Spawn SectionにSample Particles from Other Emitters Moduleが追加されました。

Ribbon Emitterにある要らないModuleを消します。

Shape Location Module、Gravity Force Module、そしてDrag Moduleを消しました。

Particle Spawn SectionにあるAdd Velocity Moduleの

Velocity ModeをLinearに変更しました。

結果です。

大体、Tutorialと同じ形状になっています。

今度はParticle Spawn SectionにあるSample Particles from Other Emitter Moduleの

Particle ID Samplingの設定をApply Sampled ID as Ribbon IDにします。

更にSource EmitterのPropertiesを選択してRequired Persistent IDsをEnableします。

Previewの映像が以下の様に変化しました。

Third PersonのImageです。

Play画面のImageです。

やっぱりRibbonとQuinnの間にGapがあります。

これを直します。

<Solve Mesh Gap>

Tutorialでは一回、別な方法で直して、その後でCurling Noiseを使用したらその方法だとへんな渦が作成される事を発見しています。

その後、Curling Noiseを使用してもおかしくならなく方法で直しています。

ここではその最後のやり方を最初から試す事にします。

Particle Update SectionにScratch Moduleを追加します。

Scratch Moduleを開き、Map Setノードに[POSITION]Positionを追加します。

Select Ifノードを繋げます。

このSelect ifノード、ほとんど初めて使用しますが、結構使い方分からなかったです。

以下にSelect ifノードの使用方法をまとめておきます。

まずNodeはSelect ifで検索します。

すると以下のNodeが追加されます。

いや、このNode違うじゃん。

と思いますがこれであっています。

鉛筆のIconをClickして以下のBoxを表示してBoolを選択します。

すると以下のように変化します。

このWild CardのTypeをPositionに変更したいんですが、ClickしてもTypeを変更するBoxは表示されません。

変更方法ですが、以下の様にPinをその変更したいTypeを持つPinとつなげます。

これだけです。

これだけですが知らないと結構、手間取ります。

次にMap Getノードの実装を行います。

[PARTICLE] Ageを追加します。

[INPUT] floatを追加します。

今度はその[INPUT] Floatの名前をNumber of Particleに変更してName Spaceを[EMITTER]に変更します。

今度はその[EMITTER]Number of Particlesの逆数を作成します。

そして[PARTILCE]Ageと[EMITTER]Number of Particleの逆数をGreater Thanノードで比較してます。

先週のBlogでここは何を計算しているのか全く分からないと書いていますが、

[PARTILC]Ageも[EMITTER] Number of Particlesも何を指しているParameterなのか不明なのだから何を計算しているのか不明なのは当たり前です。

先に行ってこれらのParameterが何を指しているのかが判明したらもう一回ここに戻って来て、この計算が何をしているのか考える事にします。

Map Getノードに[PARTICLES] Positionを追加しSelectノードのIf Trueに接続します。

Map Getノードに[INPUT] Niagara Positionを追加しSelectノードのIf Falseに接続します。

Applyを押して完成です。

うーん。Mat Getノードにある以下のParameterでどこで値を指定するんでしょうか?

これって新しく作成したParameterですよね。

どっかで値を指定する必要があると思うんですが。

しかもTutorialでは

微妙に名前が違っていました。

もしこのCodeが動かなかったらこの部分を真っ先に疑う事にします。

System Overviewに戻ります。

Scratch ModuleはParticle Update Sectionの一番最後にセットされていますが、この順番は間違っている気がします。

先週のBlogはScratch Moduleの順番には何も言及していません。

Tutorialを見て確認します。

この順番で合っていました。

Scratch ModuleのParameterであるNiagara Positionに

[PARTICLES][INITIAL]Positionを追加します。

Emitter Update SectionのSpawn Particles from Other Emitter Moduleの

Spawn Rateを50にします。

以下の部分の先週のまとめは間違っていました。

Name Spaceを[INPUT]に変更するのは[EMITTER]Number of Particlesでした。

さっきからこのParameterの名前の決定方法がオカシイと思っていましたが、[INPUT]ならどんな名前でも問題ないです。

Number of Particlesの値にSpawn Rateの値をセットします。

これで完成です。

テストします。

今度はRibbonとQuinnの間に隙間が空いてないです。

はい。

先程のScratch Pad Moduleの実装に戻ります。

先程、

と言いました。

これを今考えます。

一応、先週のBlogでも以下の仮設を考えていました。

一つ分かったのは[INPUT]Number of Particlesの値はSpawn Rateの値が入るので、1秒間に何個のParticleが生成されるかになります。

その逆数なのでParticleが生成される間の時間を表しています。

1秒間に50個のParticleが生成されるので0.02秒になります。

AgeはそのParticleの年齢というか、生成されてからの時間だと思われます。

はい。

分かりました。

  • 生成されてからの時間が02秒より長くなったら、Particleの位置は[PARTICLE]Positionの値と同じままにします。
  • 生成されてからの時間が02秒より短い間は、Particleの位置は[PARTICLES][INITIAL]Positionに変更します。

これをやっていました。

となると以下の疑問が生まれます。

  • これ常にParticleの位置を[PARTICLES][INITIAL]Positionの値と同じにすればよくない?

これを試します。

実装を以下の様に変更しました。

Testします。

走っている時はこれでOKです。

ただし止まると以下の様にRibbonが消えてしまいます。

うーん。

成程。止まっている時のRibbonを表示するために

  • 生成されてからの時間が02秒より長くなったら、Particleの位置は[PARTICLE]Positionの値と同じままにします。

の実装があるんですね。

ああ、とうとう理解出来ました。

Ribbonの性質って以下の様になっているんです。(2021-07-04のBlogより)

直近で生成されたParticleだけがその位置をQuinnのSkeletal Meshと同じ位置にしたいんです。

それ以外のParticleの位置はそのままの位置でいて欲しい訳です。

それを可能にするのが以下の2つの条件です。

  • 生成されてからの時間が02秒より長くなったら、Particleの位置は[PARTICLE]Positionの値と同じままにします。
  • 生成されてからの時間が02秒より短い間は、Particleの位置は[PARTICLES][INITIAL]Positionに変更します。

ただこの説明で全部、説明出来るのかどうか不安もありますね。

例えば、常にParticleの位置を[PARTICLES][INITIAL]Positionの値と同じにした場合、何で以下のようなRibbonが形成されるのかよく分かりません。

これが起きるためにはParticle Update Sectionで限られた数のParticleがUpdateされる必要があります。

やっぱりRibbonの仕組みは理解出来てない部分があります。

ま、BlackboxBlackboxとして扱っていくしかありません。

ある程度理解出来たことで良しとします。

<Strach Velocity>

ここはNiagara SystemのModuleの値を微調整しているだけなので結果だけ示します。

以下の様になりました。

<Fire Texture>

Fire用のMaterialを作成します。

取りあえず以下の実装まで作成しました。

結果です。

それなりには炎っぽいです。

今度は色を追加します。

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

Dynamic ParameterのTemperatureのDefaultの値は4000にしました

結果です。

うん。炎っぽいです。

Tutorialの説明通りにMain Nodeの設定を変更して

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

Depth Fadeノードは使った事ないです。

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

あ、思い出した。

これ昔勉強したやつだわ。

公式サイトのDepthFade[9]で確認します。

Depth Fadeノードを使用した場合は以下の様にOpaqueなObjectと重なった場合、

ぼやっとします。

使用しない場合は以下の様に境目がくっきりします。

実装の結果ですが以下の様になりました。

<Effects>

Ribbon EmitterのRender SectionのRibbon Renderer Moduleを選択して

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

更にParticle Update SectionにDynamic Parameter Moduleを追加して

Temperatureの値を4000にしました。

Tutorialではこの値は2万になっているんですが、恒星でも作成するつもりなんでしょうか?

結果です。

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

TutorialではTemperatureの値をCurveで指定していたので同じようにCurveを使用します。

ただし値は独自の値に変更しています。

結果です。

さらに微調整して以下の様になりました。

<Camera Offsets>

炎がCharacterの内側で発生しているようです。

それを直します。

これってやったけど駄目だった奴ですよね。

先週のBlogを読み直したら以下の様に書いてありました。

一応試してみます。

Particle Update SectionにCamera Offset moduleを追加します。

Camera Offset Amountの値は30にします。

結果です。

うーん。

僅かに背中に炎が確認出来ます。

これ効いてるんじゃないでしょうか?

先程のDepth Fadeノードのせいでボケて見えているだけじゃないでしょうか?

M_FireのDepth Fadeノードを外してテストしてみます。

以下の様になりました。

ほら。

炎がはっきり見えるようになりました。

Camera Offset Moduleを外してみます。

結果です。

うーん。あんまり違いは分かりませんね。

Camera Offsetが効いているのかどうかは不明です。

でも炎がCharacterの内側で発生しているように見える問題はMaterialのDepth Fadeノードを外せば解決します。

それは分かりました。

この辺がCGHOW氏がぬるいところです。

一個ずつきっちり勉強していけばこういうミスはしないはずです。

こういうミスがある限りどんなに作成したTutorialが凄くてもCGHOW氏を先生と呼ぶ気にはなりません。

結果です。

<Randomize>

炎の形状をRandom化するそうです。

M_FireのPannerノードのTimeにDynamic Parameter ModuleのPanの値を掛けるようします。

ここでNiagara Systemに戻りDynamic Parameter ModuleのPanの設定をします。

ここでAlphaに自作のDynamic Inputを使用します。

これはまだ2,3回しかやった事がないです。

ちょっとドキドキします。

New Scratch Dynamic Inputを選択します。

Map Getノードに[INPUT]Niagara IDを追加します。

先週のBlogを見ると以下の様にNiagara IDからFloatに変換していますが

これのやり方が分かりません。

Tutorialを見直して確認します。

単にNiagara IDとOutput Dynamic InputのPinを繋げただけでした。

これで完成です。

System Overviewに戻ってNiagara IDに[Sample Particle from Other Emitter] Sampled IDをセットします。

テストします。

炎が下向きに移動しています。

値をTutorialがやったように以下の値にすると

炎が下向くに移動するのはなくなりました。

Aの値をBの値より大きくすると炎は上向にPanするようになります。

Random化されているのかどうかはよく分かりません。

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

結果です。

炎の白い部分や黒い部分の位置がそれぞれの炎で変わってはいますね。

もっと分かり易くするためにPanの値を以下の様にしました。

結果です。

うーん。

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

最後にLight Renderer Moduleを追加します。

Render SectionにLight Renderer Moduleを追加します。

Light Renderer ModuleのColor Addの値を以下の様にします。

結果です。

おお。光っています。

なんとここでTutorialは半分でした。

残りのTutorialはまだ勉強すらしてなかったです。

後、この後でDynamic Parameter ModuleのPanに先程作成したDynamic Inputを外して[Sample Particle from Other Emitter] Sampled IDを直接セットしたりしてます。

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

来週は残り半分を勉強する事にします。

そしてその次の週にその分を実装します。その時、Panに先程作成したDynamic Inputを外して[Sample Particle from Other Emitter] Sampled IDを直接セットするのも試します。

4.2 RibbonをSkeletal Meshに追加するのは使えるか?

まずThird Personが移動していない時ですが、

後ろ姿は綺麗でかなり見栄えは良いです。

前方に移動している時です。

そんなに悪くないです。

Ribbonが発生する箇所をSkeletal Meshの一部にしたらそんなに気にならないと思います。

Ribbonを引っ張ると非常に綺麗なEffectになるのは知っていましたがそれをどうやってPlay画面で再現出来るのかは分かりませんでした。

このやり方はかなり有望な気がします。

来週以降も引き続き勉強する事にします。

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

今週は、また病院にいく用事が出来たので、ここは少しだけやる事にします。

5.1 BGMを探す

DOVA-Syndrome [10]から探します。

ピッタシなのを見つけました。

これで試してみます。

UEにImportしました。

あれ、MP3だ。

これどうやってPlayするのか忘れてしまいました。

調べます。

Wav Fileに変換する必要がありました。

うーん。変換して良いのか?

DOVAの規約を読み直します。

音源利用ライセンス[11]に以下の様に書かれています。

OKですね。

今度は普通にImport出来ました。

Change Music During Gameplay in Unreal 5 [12]のTutorialを参考にして作成します。

まずQueを作成します。

Cueを開きLoopingにCheckを入れます。

あくまでもBGMなので音量を半分にして目立たなくします。

Ambient SoundをLevel上に配置します。

Level BPを開き以下の実装を追加します。

これでPlay中はずっとこのBGMが流れるはずです。

Testします。

流れています。

ただしこのBGMは戦闘中のみに流れた方が合う気がします。

戦闘中のみ、このBGMが流れるようにします。

PlayerのMonsterか対戦相手のMonsterのどちらかが先に召喚された時にBGMが鳴るようにしました。

そしてPlayerが勝利した時か

Playerが敗北した時に

BGMが消えるようにしました。

テストします。

戦闘が始まって終了するまでの間だけBGMが鳴るようになりました。

凄い迫力です。

Gameの面白さが2倍位UPしました。

うーん。

BGMってこんなに重要だったのか。

今週はもうBGMをやる時間が無いのでここまでとします。

6.Gaeaの勉強

来週、Landscapeの作成に使用するTerrainを作成します。

そのためにはRiverノードを含むWater Groupの使用方法を勉強する必要があります。

それも単に使用する方法だけでなくそれで生成されたMaskの使用方法やMaskした後のHeight MapのUE内における正しい使用方法まで確認する必要があります。

うーん。

これの勉強をやった後で、Terrainを作成して更にMaskを作成して更にBuildをするのは結構大変です。

そういえばBuildに関してもXYの大きさも考慮する必要があります。

うーん。

どうしよう。

一番簡単なのはKlaus氏のHow To BUILD AN ISLAND In 20 mins | Unreal Engine 5 Tutorial [13]に沿ってIslandをもう一回作成する事です。

このTutorial通りにTerrainを作成すれば、Water Groupの使用方法を勉強していなくても正しいRiverを作成出来ますし、更にBuildの設定も何も考えなくても正しく設定出来ます。

唯一の問題は、海の高さとBeachの高さが同じになってしまう事です。

これ前回、私が作成した時にTutorial通りに作成しなかったからこうなったのかどうかを確認する必要があります。

その部分のTutorialの解説を見てみましょう。

以下にSea Nodeを追加した所を抜き出しました。

この部分を見てみるとSeaの部分をLevelを指定する事で決定しています。

となると高さをきちんと指定すればBeachがSeaより低くなっている今のLandscapeとは違う結果になりそうです。

よし決めました。

今週は、Klaus氏のHow To BUILD AN ISLAND In 20 mins | Unreal Engine 5 Tutorial [13]をもう一回やる事にします。

6.1 How To BUILD AN ISLAND In 20 mins | Unreal Engine 5 Tutorial [13]でIslandをもう一回作成する

Islandノードを追加します。

Editorを使用して以下の絵を描きました。

形状をもう少し単純化するために以下のParameterを弄りました。

結果です。

取りあえずこれでやってみます。

Distanceノードを追加します。

なんかすごい結果になっています。

一回、Islandノードを選択して、その後でDistanceノードを選択し直すと以下の様になりました。

Falloffの値を下げます。

この目的が分かりません。

単にIslandの高さを上げるためでしょうか?

結果です。

StylizedなLandscapeを作成するためだったらこれで完成でも良いくらいです。

今度はRoughnessを追加するためにWarpノードを追加します。

うーん。

この手順と私の作成した手順の比較検討をしてみたいです。

しかし今それをやる時間はありません。

今週、Terrainを完成させてUEにLandscapeを作成出来る状態まで終わらせないと来週、Landscapeの作成で何も出来なくなってしまいます。

Wrapノードを追加した結果です。

Terrainの表面にわずかな凹凸が追加されました。

この後でTutorialではWarpノードのSizeを変更しています。

これ元々の形状をあまり変化させたくないからやっているそうです。

同じようにSizeの値を下げました。

結果です。

うーん。

私のは前の状態でもあんまり元の形状から変化してないかったので、そんなに差が無いです。

今度はRidgeノードを追加します。

結果です。

今度はWizardノードを接続します。

この辺の手順に関しては細かく検証すると非常に面白いんですが、今週はそれはしないで先に進みます。

結果です。

Crumbleノードを追加します。

Terrainに亀裂を追加しているはずです。

結果です。

Thermal Shaperノードを追加します。

このNodeはあんまり使用した事ないですね。

結果です。

なんとこのNodeを使用したら海岸線のまわりに盛り上がりが見られます。

うーん。

このNode実はかなり使えるのかもしれません。

またWizardノードを追加します。

ここからWater GroupのNodeを追加します。

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

結果です。

全部のNodeの値を弄っています。

しかしそれは単なる微調整なのでここでは解説しません。

ここで重要なのはSeaノードの設定で、

Level、つまり海の高さを0.1にセットしている事です。

1ではかなりの部分が海に沈んでしまうので、0.1の高さを海の高さに指定しています。

これ、UEのLandscapeの設定で高さがGaeaのTerrainの高さと同じなら0.1の高さの違いも認識出来るでしょうか、高さのScaleが例えば10分の1になった場合、この差は無くなってしまうはずです。

これが前回、Water SystemのOceanを配置した時Beachと海の境目が無くなってしまった原因かもしれません。

今回はGaeaで作成したTerrainのサイズとUEで作成するLandscapeのサイズは完全に同じにしますので、Oceanを配置しても海の方がBeachより高くなる事は防げると思います。

TutorialではここでSeaノードのOutputについての説明があります。

最初のFxは海が白くそれ以外は黒いMaskを表示しています。

次のFxはBeachが白く表示されているみたいです。

ここから海に沈んでいないBeachをMaskにする方法を説明しています。

まず以下のようにBeachとSeaのMaskをCombineノードで繋げます。

Combineノードの設定です。

結果です。

なんか青い部分がありますね。

なんとこの後、Texturingを行うのに以下の部分は消してしまいます。

このTexturingと言うかColoringは要らないと思っていたんですが、この部分でMaskも作成しているので、やっぱりやる必要があります。

のでTexturingをやります。

まず以下の様な実装を作成して

こんなTextureを追加しました。

次はFlowを追加します。

結果です。

Flowが無い場合と比較します。

Flowがある場所と完全に混ざっています。

これUEでMaskとして使用する場合どうするんでしょうか?

TextureノードとSeaノードのOutputをPort化します。

このやり方は初めて知ったのでここに記録として残しておきます。

まずNodeを選択した状態でCを押します。

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

Outputを選択します。

すると以下の様にTextureノードからWireで繋がっていたNodeが全部Portで繋がる事になります。

更にBeachとSeaのMaskも作成します。

結果です。

これBeachとSeaの部分が混じっていないですよね。

この実装の方法だと上書き出来るの?

うーん。

多分、そうなんでしょうね。

TutorialではここでBuildの準備を始めます。

うーん。川を追加したいです。

してしまいましょう。

以下の様にして川を追加しました。

WizardノードからRiverノードを接続して川を作成します。

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

このMaskを使用して以下の実装を作成します。

結果です。

この後にSeaの実装を追加します。

結果です。

近づくとしっかり川が形成されているのが分かります。

うーん。

取りあえずやってみましょう。

以下のNodeをHeight MapやMaskとしてExportします。

Extensionを以下の様に変更しました。

設定です。

うーん。

設定が以下の様になっていますがこの辺の説明はTutorialはしてくれませんでした。

ので一端、ここでBuildします。

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

この状態では何とも言えません。

UEで確認します。

Tutorialの設定だと以下のScalingで正しいはずです。

これでLandscapeを作成してみます。

結果です。

Play画面で確認します。

うーん。SeaとBeachの高低差は無いように見えます。

Water Systemを追加して確認します。

何故かWater Systemが表示されません。

一回UE5.2を再Installします。

中々Installしません。

なんか問題があるんでしょうか?

仕方ないので今週のGaeaの勉強はここまでとします。

UE5.2を再Installしたら海が表示されるようになりました。

海の高さを調整しました。

Playで海岸線を確認します。

Landscapeに微妙な角度があり、BeachとSeaの境界が出来ています。

これは行けそうです。

7.Houdiniの勉強

7.1 FOUNDATIONS | OVERVIEW [2]の復習

先週、やっとFOUNDATIONS | OVERVIEW [2]の勉強が終わりました。

今週はその復習をします。

2023-01-08のBlog

The Houdini Workspaceを勉強しています。

ここはUIの簡単な解説とかを勉強していますね。

ここで一番勉強になったのは以下の

3つのPaneの名前です。

2023-01-15のBlog

以下に示したToursを作成して地面に落とすTutorialを勉強しています。

これ今、読み直しても何をしているのか不明です。

こんな難しいTutorialを最初に用意しておくってHoudiniは初心者いびりが好きだなと思いました。

Tumble、Track、Dollyの意味を理解したのもこの週でした。

これらの操作は後で日本語のしっかりしたSiteが、ものすごく簡単かつ正確に説明していたのでショックを受けましたが、まあそういうのも勉強です。

ここで説明されているHoudiniのShort cutは全く覚えていません。

完全に忘れています。

2023-01-22のBlog

Space Bar + HのShort cutについて解説していますが、

これって先週、勉強したConstruction Gridの事じゃないですか。

同じ事を何回も教わっていたみたいですね。

うーん。

もう少し整理して効率的に教えてほしかったですね。

まあ、でもこのまとめたBlogを何回も読んでいれば操作方法は完璧になるでしょう。

2023-02-01のBlog

以下に示した小さな四角を表示してViewを管理する方法を勉強しています。

うーん。

勉強したのは覚えています。

ここで始めてNetwork Paneの操作を勉強しています。

2023-02-06のBlog

この週はNodeを使用して以下のObjectを作成しています。

ここで時間が無くなってしまいました。

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

復習の続きは来週やります。

8.UEFNの勉強

今週はFunctional Programming(関数型プログラミング)について勉強した内容をまとめます。

UEFNはC++やBlueprintを用いず、専用の言語であるVerseを使用してGameを作成します。

このVerseがFunctional Logic Programming(関数論理型Programming)というProgramming言語における最新のParadigmで作成されています。

筆者はProgrammingのParadigmの観点から言うとObject Orient Programming(オブジェクト指向プログラミング)までのProgramming言語しか勉強していません。その次の世代であるFunctional Programming(関数型プログラミング)すら勉強した事がありません。

更にその先にあるFunctional Logic Programming(関数論理型プログラミング)についてはまったく知りません。

ので今週はそのFunctional Logic Programming(関数論理型プログラミング)の勉強の前段階としてFunctional Programming(関数型プログラミング)について勉強した内容をまとめておきます。

これらの勉強はUEの勉強の記録とは違い、既にこの時点で終わっています。

何故もう勉強し終わった内容をあえてここに記録として残しておくのかと言うと、Functional Programming(関数型プログラミング)を齧って分かったんですが、初心者に対して根本の理解の妨げになるかなり大きな罠が仕掛けられていました。

そのため本来ならProgrammingそのものを勉強する前に理解しておくべき

を理解する事自体がかなり困難だったりします。

その罠を抜けて正しい学習が出来る道筋を見つけました。

ので、後からFunctional Programming(関数型プログラミング)を勉強する人達がその罠に引っかかって長い時間を無駄に過ごす事が無いようにここに記録として残しておく事に決めました。

8.1 理解する前までの勉強内容

Verseを勉強するに当たり、Functional Programming(関数型プログラミング)の基礎位は理解しておいた方が良いと思い、YouTubeにあるFunctional Programming(関数型プログラミング)のTutorialを2,3個見ました。

よく分からない。

いやTutorialの言っている事は分かるんですが、Object Oriented Programming(オブジェクト指向型プログラミング)を勉強した時は、歯車がカチッとはまる様に、これがObject Oriented Programming(オブジェクト指向型プログラミング)の哲学で、それを実践するためにはこういう手順が必要なんだ。という事は最初の授業で理解出来ました。

そういうのが無くてFunctional Programming(関数型プログラミング)が何で必要なのか?とかFunctional Programming(関数型プログラミング)とはそもそも何なのか?という根本が理解出来ませんでした。

のでまあ理解出来たのか出来てないのかよく分からないままで動画を見終えてました。

まあ、Totalで一時間も勉強してないし、理解出来ないのもしょうがないね。と思ってその時は諦めて別な事を始めました。

その後、たまたまお勧めで出てきた

オブジェクト指向は万能の薬ではなかった。関数型の流行へ。【プログラミングパラダイム・シフト5】#68 [14]

を見たら、ここでFunctional Programming(関数型プログラミング)について解説している人が、その時の私とまったく同じ状況になっているんです。

部分部分に関してはそれなりには理解出来たんですが、じゃFunctional Programming(関数型プログラミング)って何?となった時に、

うーん。

よく分からん。

ってなってしまっています。

これ見て、気が付きました。

勉強した教材が良くなかった。

まあ、はっきり言えばその教材が間違っているんです。だからその教材で勉強した人は誰も理解出来ない。

この動画に出てた人もそういう教材で勉強したから理解出来なかったし、私もそうだったんです。

良くJavaを使っていた人がC++を勉強するとPointerがよく分からない。って言います。

これ嘘です。というか完全に間違っています。

Pointerの概念を理解していなかったらJavaでProgrammingを書く事は出来ません。

JavaからC++に移って来た人が分からないのはC++におけるPointerの文法なんです。

C++ではJavaでは自動でやってくれているPointerの指定や解除を全部自分でやる必要があります。そのために文法が少し複雑なんです。というかその部分のC++の文法はかなり変で、その部分をしっかり習わないと必ず間違えます。

この事をJavaからC++に移ってくる人達は知らないんです。

それさえ理解すればC++でもJavaとほぼ同じ様にCodeを書く事が出来ます。

本来なら、ここで「君が分からないのは、PointerじゃなくてC++におけるPointerの文法だよ。」ってその道の先輩が指導してくれるはずですが、英語圏、日本語圏問わず、C++界隈にそういう立派な人間性を持った人はいません。

それどころか、C++の優しい先輩たちは、将来の競争相手を潰すために「Pointerの理解が足りない。勉強不足!」っと怒り初心者をMisleadします。

そうなるともう「俺はPointerが理解出来てないのか!もっと勉強しないと。」となって、理解しているはずのPointerの勉強を何度も繰り返す事になります。

そしていつまでたってもC++でCodeが書けなくなってしまいます。

まあ、こんな感じでTrapにはまってしまう訳です。

これと同じ事がFunctional Programming(関数型プログラミング)の勉強でも起きていると分かりました。

なら解決策は簡単で、立派な人間性というか常識的な人間性を持った人が作ったTutorialで勉強すれば良いんです。

8.2 関数型言語とは何か?(Haskellで学ぼう)【歴史~オブジェクト指向との比較】[15]を勉強して

私は日本語でProgrammingを勉強する事はありません。

私は基本的にProgrammingに関しては日本語で書かれた内容はほとんど信じていないからです。

英語を翻訳する段階で伝言ゲーム化するので本来とは違う意味で伝わっている可能性が高いし、そもそも英語圏で出来たものを英語で勉強出来るのに敢えて日本語で勉強する必要性を感じないからです。

そういう私に、Programmingに関して偉そうに日本語で絡んでくる人がいますが、「それStack Overflowで同じ質問したら?」とか言って小馬鹿にしてお終いです。

英語のSiteもこのBlogとは別に運営していますが、そこでの質問に関してはそれなりに真摯に対応しています。

そういう訳で日本語の動画は娯楽関連以外はほとんど見ない私ですが、この関数型言語とは何か?(Haskellで学ぼう)【歴史~オブジェクト指向との比較】[15]はかなり良いTutorialだったのでここに紹介する事にします。

ただし、今ここで記録にまとめるためにもう一回見直しましたが、ここで述べている内容に今の私が全部賛同しているかと言うとそうではありません。

この説明は間違っているのではないのか思う部分もあります。

しかしこの TutorialはFunctional Programming(関数型プログラミング)を勉強する上で大切な内容が紹介されていました。

その事に気づかせてくれた最初のTutorialだったのであえて紹介する事にしました。

それはそれぞれの言語の歴史を紹介した上でFunctional Programming(関数型プログラミング)を最後に紹介している事です。

まず、我々はなんで今更、Object Oriented Programming(オブジェクト指向型プログラミング)を捨てて新しいParadigmであるFunctional Programming(関数型プログラミング)を勉強する必要があるんでしょうか?

うーん。

なんで?

言われてみると、Object Oriented Programming(オブジェクト指向型プログラミング)ってそんな使用を停止するほどの欠点ってあったけ。と思います。

だから何でFunctional Programming(関数型プログラミング)が必要になったのかとか、Functional Programming(関数型プログラミング)の何がObject Oriented Programming(オブジェクト指向型プログラミング)の致命的な欠点を克服出来るのかが理解出来ないんです。

のでFunctional Programming(関数型プログラミング)とは何かという根源的な質問に対する解答が分からないままで勉強が終わってしまっていたんです。

その辺をズバリ解説してはいませんが、最後の言語の歴史についての解説で、何となくその辺が重要なんだと理解出来るTutorialになっています。

8.3 Functional Programming in 40 Minutes • Russ Olsen • GOTO 2018 [16]を勉強して

はい。

その後でこの動画を見たら、Functional Programming(関数型プログラミング)が何なのかについてもう完璧に理解出来ました。

今、この動画を見直して全部ここにまとめ直すには時間が全然足りないので、代わりにこの動画を見た私の解釈によるFunctional Programming(関数型プログラミング)を理解するために何が重要なのかをまとめます。

簡単に言えばFunctional Programming(関数型プログラミング)はObject Oriented Programming(オブジェクト指向プログラミング)の改良版なんです。

Object Oriented Programming(オブジェクト指向プログラミング)は非常に優れたProgrammingです。

そのおかげで、今までにない巨大で大人数が必要なProjectを成功に導く事が出来ました。

ところがObject Oriented Programming(オブジェクト指向プログラミング)は元々はそんな大きなProjectを作成する事なんて考えられていなかったんです。

ので巨大なProjectを実行している内にObject Oriented Programming(オブジェクト指向プログラミング)そのものが抱える致命的な欠点も明らかになりました。

更にCPUの並列処理やInternetとの同期処理などの今まで存在しなかった問題にも対処する必要が出て来ます。

それらに対してもObject Oriented Programming(オブジェクト指向プログラミング)の対応はBestからは程遠いものしか提供出来ませんでした。

それでその欠点を克服した新しいParadigmを持つ言語が必要になったんです。

それがFunctional Programming(関数型プログラミング)なんです。

はい。

これを書くとすぐに反対意見が飛んでくるでしょう。

「Functional Programming(関数型プログラミング)はObject Oriented Programming(オブジェクト指向プログラミング)より先に開発されていました。のでその意見は間違っています。」って

そのお前の意見が間違っているんだよ。バーカ!

Object Oriented Programming(オブジェクト指向プログラミング)の改良版、OOP++とでも呼ぶべき次世代のParadigmを持つ言語を開発するのに、前からあったFunctional Programming(関数型プログラミング)の仕組みが非常に有効であることが分かったので、その骨子も利用させてもらっただけなんです。

ここを理解していないと、昔のFunctional Programming(関数型プログラミング)そのものを勉強する羽目になってそれは理解出来たけど、それが出来るとどうなの?となってしまいます。

大体、Object Oriented Programming(オブジェクト指向プログラミング)があるのに何であえて昔のFunctional Programming(関数型プログラミング)を勉強する必要があるんですか?

ないです。

こんなにObject Oriented Programming(オブジェクト指向プログラミング)が大成功しているのに、なんでその前に戻る必要があるんでしょうか?

自動車が出来て非常に便利になりました。みんな満足しています。しかし自動車事故が起きるから「自動車に乗るのは止めて馬車に乗りましょう。」ってなるわけねーだろ。

となるとFunctional Programming(関数型プログラミング)を勉強するに当たって何が重要なのかも自ずと明らかになります。

まずObject Oriented Programming(オブジェクト指向プログラミング)の欠陥を知る事です。

これを知らないとそもそもFunctional Programming(関数型プログラミング)が必要になる理由すら理解出来ません。

ところが質の悪いFunctional Programming(関数型プログラミング)の教材はこのObject Oriented Programming(オブジェクト指向プログラミング)の欠陥について明確な形で示していません。

何で、このObject Oriented Programming(オブジェクト指向プログラミング)の欠陥がはっきりした形で述べられてないんでしょうか?

これ100%想像ですが、

Object Oriented Programming(オブジェクト指向プログラミング)原理主義者みたいな人がそれなりの権力を持っていて、Object Oriented Programming(オブジェクト指向プログラミング)が持つ本質的な欠点について公に話す事が結構難しいのかもしれません。

末端の人でもProgrammerならそれなりの発言権をもつアメリカ社会でもそうなんだから、Programmerには人権がない今の日本社会だと、更にObject Oriented Programming(オブジェクト指向プログラミング)が持つ本質的な欠点について発言するのはほとんど不可能でしょうね。

日本では、Object Oriented Programming(オブジェクト指向プログラミング)で作成された巨大なProjectが想定通りに動かなくて、末端のProgrammerに責任を押し付けて自殺とか強要して原因を曖昧にして処理していた事件とかあったかもしれません。

本来ならProjectの総責任者に当たる人が「あれ、これはObject Oriented Programming(オブジェクト指向プログラミング)そのものが持つ欠陥が原因だわ。」と気付いて「Object Oriented Programming(オブジェクト指向プログラミング)では解決しない問題があります。」と警告を発しているはずですが、日本でそういう話が今までまったく聞かれなかったって事は、

  1. Object Oriented Programming(オブジェクト指向プログラミング)は完全無欠の言語で、Functional Programming(関数型プログラミング)の人が言うような欠点は存在しない。
  2. Object Oriented Programming(オブジェクト指向プログラミング)は、Functional Programming(関数型プログラミング)の人が言うような欠点は存在は存在していたが、その問題が表面化するたびに、末端のProgrammerに責任を押し付けて自殺に追い込んでいた。ので今までその問題が表面化する事はなかった。

のどちらしかありえない訳ですから。

まあ、こういう訳でFunctional Programming(関数型プログラミング)を勉強するに当たって一番重要と思われるObject Oriented Programming(オブジェクト指向プログラミング)の欠陥を知る事自体がそれなりに難しくなっているでしょうね。

特に日本では!

だからそういう教材で勉強してもFunctional Programming(関数型プログラミング)???ってなってしまう訳です。

ここでもう時間が無くなってしまいました。

ので後は超簡単に箇条書きでまとめる事にします。

次に重要なのが、そのObject Oriented Programming(オブジェクト指向プログラミング)の欠陥をFunctional Programming(関数型プログラミング)がどう克服したのかについてです。

これは理論的な理解と実際のImplementation的な理解が必要になります。

最後に重要なのが、Functional Programming(関数型プログラミング)が提供するその解決方法が本当に実戦で役に立つのかどうかです。

今読み直してみましたが、これでは私以外が読んでもあんまり理解できない内容になってしまったかもしれません。

まあ、常にこのLogicから離れないで勉強したらすぐにFunctional Programming(関数型プログラミング)も理解出来るでしょう。少なくとも私は。

9.YouTube動画の作成

何で、前節の話はこんなに訳分からなくなってしまったんでしょうか?

書いている内に、頭の中の誰かが反論してきてその反論に対抗している内に話が逸れてしまったんです。

後、やっぱり構成とかも考える必要があります。

最初の下書きとするなら上出来です。

YouTubeの内容は、構成を最初からしっかり作っておく事にします。

アメリカではかなり大きな話題になっているけど、日本では全く紹介されない話題を紹介し、解説し、更にそれに対しての私の意見を述べるYouTubeのSub Channelを作成する予定です。

今週はそのChannelに載せる話題をPickupしました。

9.1 集めた話題

今週は突然、病院に行く必要が発生しまして、その病院で待っている間、何もすることが無いので以下の事をまとめていました。のでいつもよりかなり内容が多くなっています。

本当に今アメリカで話題になっている話を集めると、全然日本人が興味を示してくれない事が判明したので、以下のような日本人にとっても関係がありかつアメリカでもそれなりに認知されている話題を選びました。

  • アメリカでの味の素(MSG)の評価
  • アメリカ人に納豆を食べさせると
  • アメリカでは本当に日本のアニメは人気なの?
  • アメリカのZ世代は最強世代
  • アメリカでは日本人はなめられているって本当?
  • 任天堂vs Influencer
  • アメリカの真の支配者は?
  • 何でアメリカではLGBTが政治問題化しているのか
  • アメリカの歯医者と日本の歯医者、患者にとって特なのは本当はどっち?

で、この題でアメリカに2~3年住んだだけの人でも語れる内容を語っても仕方ないので、私のYouTube Channelでしか得る事が出来ないDeepな内容が視聴者にはっきり伝わるようにする必要があります。

どうしたらそのようなDeepな内容を伝える事が出来るんでしょうか?

その辺も一寸考えながら文章を作成していきます。

9.2 任天堂vs Game系Influencer達

これ今週凄い進展があったので、特別に今やる事にします。

今までのように徒然なるままに文章を書いていると文章の最初と最後に一貫性のない内容になってしまう事が判明したので、以下のTemplateに沿って内容をまとめます。

アメリカではかなり大きな話題になっているけど、日本では全く紹介されない話題>

アメリカのInfluencer達からかなり激しい攻撃を任天堂が受けている件

<解説>

<<前提の話>>

これは日本でも同じですが、英語圏でもYouTubeなどにはGame関連の話題を専門に解説するInfluencerが沢山います。

前回のポケモンSVの発売からそういうGame関連のInfluencer達がポケモン任天堂に対してRefundを求める激しい攻撃を始めています。

その理由ですが、最初はGraphicsが陳腐で値段に値しないという意見だったが、そんなにGraphicsは酷くないと言う意見が出て来ると、突然Bugが多く楽しく遊ぶ事が出来ないと言い始めました。

ので私個人はあんまり彼らの言う話を信用していません。

実際にアメリカでも、元からのポケモンファンはGame関連のInfluencerの扇動には組せず、歴代最高のStoryとかの高評価をしています。

ただし、そういう元々のFanからも不満はあります。

ある女の子が今回のポケモンSVに対して、今回のポケモンはどの町に行ってもスカートが買えない。と不満を言っている動画は見た事があります。

<<今回の話>>

EmulatorとModsを使用して改造した任天堂のGameのPlay動画をUpしていたGame実況系のYouTuberが任天堂から著作権侵害の申告をうけ、既に2つのVideoがBanされた。と自身のYouTube Channelで告白しました。

これだけだとまあ、中立的な感じで、お互いの誤解があるので話し合いたい。位のニュアンスに聞こえるかもしれないが、これ本当に英語が分かる人が見ると、

任天堂は私を脅迫しているのでみんなで任天堂を攻撃してくれ。」

としか言っていません。

更にSwitchのGameをHackしてPlay出来るようにしそのシステムだか何だかを販売していた人が、有罪判決を受けて懲役を終えた後、任天堂に対して14億円位の損害賠償金を返却するか、収入の30%を任天堂に支払い続ける必要があるNewsが紹介されました。

これがあまりにも可哀そう過ぎるとなっていて、また任天堂に対しての攻撃になっています。

この2つNewsがネットを駆け巡って、今Game系のInfluencer達が任天堂を総攻撃する事態になっています。

<この件に関する私の意見>

まずこの件は実際は3つの事件が起きており、その内容はそれぞれ微妙に違っています。

のでそれぞれの事件に対しての私の意見を以下にまとめます。

<<ポケモンSVのRefund要求>>

もうアメリカでは新しいGameが販売されるたびにそのGameをどれだけ叩くかでYouTuberの再生回数が決まる。と言う方程式が確立されてしまっています。

のでそういうGame系のYouTuberは実際にはGameなんかPlayしないで叩いていると思われます。

私は普段、GameはPlayしないので彼らの言っている事が一理あるのかどうかよく分かりません。

しかし、実際は何億円も年収があるYouTuber達が、何か月もお小遣いを貯めてやっとSwitchのGameを買う子供たちや大人たちの気持ちを代弁するのは難しいでしょうね。

Fox Newsがコロナのワクチンを打つともっと病気になると散々Newsで言っていたのに、自分たちの本社で働く人達にはワクチン接種を義務付けていたのに似ている気がします。

彼らは、はっきりとは言っていませんが、ポケモンの声優をやらせてくれたら任天堂、並びにポケモンに対する攻撃を止めてやると、言っている感じがします。

金よこせってのが本音だと思います。

<<EmulatorとModsを使用して改造した任天堂のGameのPlay動画をUpしていたGame実況系のYouTuberが任天堂から著作権侵害を受けた件>>
日本人からしたら、どのGame実況が著作権違反に当たるのかを決めるのは、任天堂とそのGameの権利を持っているGame会社だけで、その動画を上げているYouTuberにはなんの権利もないはずです。

しかしアメリカではそうは考えられていません。

これはアメリカに住んだ事が無い人には理解出来ない感覚かもしれませんが、アメリカの著作権ってかなり特殊なんです。

更に白人は、先住民の土地をどんどん奪って自分たちの領土にしていった歴史があり、有色人種の権利を奪うのはなかば当然と考えている層はかなりいます。

で、そういう有色人種が白人に対抗するためには弁護士をたてて裁判するしかありません。

逆に言えば、裁判になったら白人も有色人種も関係なくなります。

で、そうなった場合ですが、今度はアメリカの特殊は著作権が絡んでくると思われます。

アメリカの著作権にはFair Useという考え方があり、みんながやっている事は著作権違反には当たらないとみなされます。

で、このEmulatorとModsを使用して改造した任天堂のGameのPlay動画をUpする以前に、Game実況の動画をYouTubeにUpする件ですが、アメリカでも著作権違反に当たるんでしょうか?

まあ、当たるでしょうね。

更にEmulatorとModsを使用しているのも著作権違反で訴える事が可能なはずです。著作権には著者の意図しない方法で使用してはいけない権利が含まれているからです。

と言う訳で裁判まで行ってもこの戦いは任天堂が勝つと思います。

そうは言っても道徳的にどうなの? 任天堂はそこまでやってやりすぎって言われないの?と思う方もいらっしゃるかもしれません。

その辺についての私の意見をまとめます。

まずEmulatorやModsを使用するのを当然の権利と考えているGame系YouTuberが根城としているのはPC Gameです。

PC Gameをやる層とSwitchのGameをやる層は全然違います。

PC Gameをやる層は、EmulatorやModsを使用するのを当然の権利と考えているGame系YouTuberが任天堂から訴えられたら、SwitchのGameはやらなくなるでしょうね。

でもSwitchのGameをやる層は、PC GamerがSwitchからいなくなったらいじめっ子がいなくなる訳で返って喜ぶ気がします。

この辺は実際に調査しないと本当の事は分かりません。

でもそんな気がします。

<<SwitchのGameをHackしてPlay出来るようにしそのシステムだか何だかを販売していた人が、有罪判決を受けて懲役を終えた後、任天堂に対して14億円位の損害賠償金を返却するか、収入の30%を任天堂に支払い続ける必要があるNews>>

これ、実は結構、深い話が含まれていて、昨今のEpic vs Appleの裁判にも関連する内容でもあると個人的には考えています。

Emulatorを使って任天堂のGameをタダで配ったら、それは漫画村の再来でしょう。

誰だって大喜びしてその海賊版をPlayするはずです。

しかしその海賊版にはMalwareが仕込まれている訳です。

これ日本人は全く知らないでいますが、PCやMacって基本的に自己責任の世界なんです。もしMalwareRansomwareに感染しても自分で解決してね。って世界です。

それに対してSwitchなどのConsole GameはUserの安全は会社側が責任を持っているんです。

だってGameをやる層がそんなにパソコンに詳しい訳ないじゃないですか。

それ故に勝手にEmulatorを使用する事に対しても任天堂はかなり敏感です。

Userの安全が損なわれる訳ですから、Emulatorの使用を暗にほのめかすだけでも、任天堂からしたら要注意人物に写る訳です。

今回、Game系Influencerから可哀そうの大合唱で紹介されている服役中のHackerもYouTubeでは言われていませんが、EmulatorでPlay出来るようにした任天堂のGameにMalwareを仕掛けていたらしいです。

ので単なる第三者から見ても全然可哀そうじゃないです。

しかしYouTubeのGame系Influencerの話だけ聞いている層にはそんな言葉は届きませんでしょうね。

彼らは呪文のように任天堂は、一番のFanを攻撃していると言って発狂しています。

結果としては、任天堂はそれなりの評判が失墜する事態になる事は避けられないでしょうね。

<対策を勝手に考えてみました>

現場で働いている人達からしたら、お前の意見なんて聞いてないよ。って言われそうですが、秘策を思いついたんでそれを書いておきます。

これHolly PotterのGameの炎上見てて思ったんですが、Holly PotterのGameに反対する人達がGame実況する人達を攻撃して引退に追い込んでいたんです。

で思ったのが、この人達本当はHolly PotterのGameを制作している会社に雇われてんじゃないの?です。

これ非常に上手く出来ています。

Game実況者を引退に追いこんで恨みを買っても、Gameを制作している会社もHolly PotterのBrandにも全く傷がつきません。

Game実況者が力を付けて、Gameの内容に文句付ける前に潰す事が出来ます。

Holly Potterの世界観を壊す、AK48をModで使用させろ。と主張して暴れる前に潰せる訳です。

Emulatorを推奨しているGame実況者に対して、お前はLGBTに反対している任天堂の見方をしているから、絶対潰してやるって感じで粘着する外部の団体を秘密裏に雇って裏から潰すんです。

これなら任天堂の評判を落とす事はありません。

更にアメリカの文化として、そういう荒事を実行してくれる会社は沢山あります。Proなので口も堅いです。絶対に漏れることはありません。

任天堂が直接手を下すと、任天堂の評判に傷がつきます。

なのでこういう風に絡め手で攻撃するのも有りな気がしています。

10.DirectXの勉強

10.1 Olympus Engine Projectの勉強

10.1.1 先週の復習

今週は C++ DirectX 12 Game Engine - [S01E03] - Creating A Game Engine [3]のFinishing Touchesを勉強する予定でしたが、先週のBlogを読んだら、まだその前のLinking Our Projectの実装をやっていなかったです。

で先週は何をやったのかと言うと__declspec()の機能について勉強しました。

結論としては、__declspec()には特に機能とかはなくて、

WindowsでDLLを使用するためには、そのDLLを作成する元になったClassや関数の前に__declspec()を付ける必要がある。

と言うWindows特有のRuleでした。

先週、勉強したのはそれだけです。

10.1.2 Linking Our Projectの実装を行う

__deslspec(dllexport)を追加しました。

うーん。

Errorになっています。

Tutorialを確認します。

別にErrorになっていませんね。

Sample Codeも確認します。

思いっきりErrorになっていました。

これは何か原因がありそうです。

調査します。

まずChat GPTに質問しました。

TYPOじゃね。と言っています。

何、言ってんの!

やっぱ検索はGoogleじゃないとまだダメですね。

あ。

Typoしていました。

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

次行きます。

今度はOlympus.hに以下のCodeを追加します。

今度はTYPOしないようにSample Codeから丸コピーしました。

また、IApplication.hに戻って、先程__declspec(dllexport)と打った所をOLYMPUS_APIに変更します。

これでCodeの実装は終わりました。

次はPropertiesの設定を直します。

Olympus Engine ProjectのPropertiesを開きます。

ConfigurationにDebugをセットしC/C++のPreprocessorを選択します。

そしてPreprocessor DefinitionsにBUILD_DLL;を追加します。

Release Modeも同様にBUILD_DLL;を追加します。

2023-04-10のBlogを見ると

Semicolonが入っていません。

これは単にScreenshotを取ったタイミングの問題だと思いますが一応確認しておきます。

しました。

やっぱりそうでした。

これでPropertiesの設定は終わりです。

今度はBlank ProjectのImplementationを行います。

Blank ProjectのApplication.hを開き、Olympus ProjectのIApplication Classを継承します。

Errorになっています。

これはTutorialでもそうなっています。

このErrorを直します。

Blank ProjectのPropertiesを開いて

C/C++のGeneralを選択し、Additional Include DirectoriesにOlympus ProjectのSourceを追加します。

これで先程のErrorは直るはずですが、次いでにBlank ProjectのSource Folderも追加しておきます。

これでBlank ProjectのPropertiesの設定の直しは終わりです。

Blank Projectに戻ります。

Errorはまだ直っていません。

Platformから順に選択してIApplication.hを選択します。

Errorが消えました。

後、Angle BracketsじゃなくてDouble Quotationsでした。

今度はIApplicationのErrorを直します。

Blank ProjectのReferencesからAdd Referenceを選択して

Olympusを選択します。

次にBlank ProjectのPch.hを開き

#include “Application.h”を追加します。

いやこれはおかしいでしょう。

Application.hは何もしなくてもIncludeされるはずです。

と思ったらOlympus.hに直しました。

あ、そうでした。

はい。

IApplicationのErrorが消えました。

これで完成です。

10.1.3 Linking Our Projectの実装を行った感想

はい。3週間に渡って勉強しましたが、これで異なるProject同士で継承する方法が判明しました。

こんなのにと言ったら語弊が有りますが、3週間も掛けてしまったのは一寸心外です。

とは言ったものの、まだReferencesの辺りを理解していません。

と言う訳でまだ、Linking Our Projectの勉強は続きます。

来週はReferencesの辺りが何をしているのかを調査します。

もう、覚悟決めました。

超絶ゆっくり勉強します。

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

DirectX 12の魔導書」を勉強します。

10.2.1「DirectX 12の魔導書」の先週の勉強を復習する

Create Swap Chain For Hwnd()関数を使用してSwape Chainを作成していました。

ああ、思い出してきました。

Direct3D 12 ゲームグラフィック実践ガイド」でもSwap Chainを生成したはずです。

それで「Direct3D 12 ゲームグラフィック実践ガイド」ではCreate Swap Chain()関数を使用してたんです。

そうだ。

Direct3D 12 ゲームグラフィック実践ガイド」で何を勉強したのかも復習しておきます。

Create Swap Chain()関数に使用するParameterの一つであるSWAP_CHAIN_DESC構造体のそれぞれのMemberの機能について詳しく勉強していました。

中々読み応えのある内容でした。

10.2.2 「3.3.5 Render Target View (RTV)」を軽く読む

「3.3.4 Swap Chain」の勉強が終わったので、次の「3.3.5 Render Target View (RTV)」を勉強します。

結構、長い節なのでまず軽く読んで全体の内容を把握します。

軽く全部読みました。

この節のMainの話の一つがDescriptor Heapについてですが、このDescriptor Heapの説明が「HLSLシェーダーの魔導書」の説明とかなり違います。

いや違うと言うとまるでどちらかが間違っているというNegativeな意味にとられてしまうかもしれません。

これは同じ物を説明しているのに、全く違う角度から見て説明しているため、第三者にはその説明がまったく違う内容のように聞こえると言う意味で言ってます。

凄い興味深いです。

DirectX 12の魔導書」と「HLSLシェーダーの魔導書」はその題から推測するに、ほぼ同じ系統の学派に属しているはずです。

にもかかわらずDescriptor Heapの機能の説明の仕方がこんなに違うって、なんかすごい惹かれます。

以下に読んだ内容を簡単にまとめます。

<Render Target Viewとは?>

まずRender Target Viewそのものが何なのかですが、作成したBufferの中身を書き換えたり、Clearしたりするためのものだそうです。

ここで言うBufferは一般的なBufferの事ではなく、Swap Chainの所で散々勉強したDouble Bufferingを指しているはずです。

だってDouble Bufferingでは画面をClearしたり、中身を書き換えたりする必要が常に生じている訳ですから。

ただ確証は無いです。

一応、今回はそうだと仮定して読んでいきます。

<BufferとView>

ここではBufferとViewの違いについて解説しています。

結論から先に書くと、BufferはDataを保持する所、ViewはそのDataの使用方法を指定するものだそうです。

Bufferは概念としても実際の物としても分かり易いですが、Viewって普通に考えたらEditorのScreenとかを指しますよね。

あくまでもDirectX 12におけるViewの定義って事でしょうね。

ただViewって単語の一般的な定義って風景って意味です。そこから転じて見る能力とか、見た感想とかの意味になる訳です。

ViewがBufferの使用方法を指定すると言われると一寸違和感を感じます。

ViewがBufferの使用方法を明らかにする。と言う方がしっくりします。

後、ここでは沢山の種類のBufferについても紹介していました。

うーん。

Double Bufferingについてのみの話だと思っていたんですが違うんでしょうか?

<Descriptor>

Descriptorについてです。

Descriptorについては今までも散々勉強してきましたが、ここでかなり現実的な形で理解する事が出来ました。

Descriptorは先程のViewerにSamplerというものを追加して構成されるものだそうです。

この節の説明によるとViewerにも色々な種類があってそれらをまとめて、+Samplerを追加したのがDescriptorだそうです。

これは凄く納得いく説明です。

Descriptionとは何かの機能を言葉で説明したものを指します。

さっきのViewが見たままを表現しているのに対して、更に詳しい解説を追加しているImageが有ります。

Samplerがどんな機能を持つのモノなのかは不明です。

Descriptorの意味がやっと理解出来ました。

せっかくですので、今までのDescriptorの勉強内容を復習して、その時にどれだけ理解出来ていたのかを確認します。

10.2.3 Descriptorの復習

BlogをDescriptorで検索して、引っかかったBlogのDescriptorに関するまとめを読みます。

こんだけありました。一個ずつ見ていきます。

2022-10-31のBlog

なんと「DirectX 12の魔導書」のChapter1にDescriptorについての解説がある。と書かれていました。

一寸、見てみます。

ありました。

「1.5.4 DirectX 12」でViewの上位概念だと説明されていました。

こんなのViewの概念を知らなかったら、何も分かる訳ないじゃないですか。

まあ、でも教科書が間違った説明をしている訳ではないですし。

2022-11-06のBlog

この週は、DirectX12を理解するためには以下の用語を

理解する必要があるみたいです。とまとめられていました。

まさしくこれらの用語を理解する事がDirectX12を理解する事そのものでした。

以下の推測をしています。

これ、かなり頑張って推測していますよね。

ただ悲しい事にこの時の知識では、Descriptorが何であるかを推測する事はまだ出来ないんです。

この週はDescriptorだけじゃなくて他の用語についても推測しています。

今、読んでみると結構面白いです。

2023-01-08のblog

この週は、今までの勉強内容の復習をしています。2022-11-06のBlogの解説でDescriptorが出ていました。

それだけでした。

2023-02-19のBlog

Direct3D 12 ゲームグラフィック実践ガイド」の「2.3 Direct X 12の初期化処理」で以下のDescriptorがある事を確認しました。

これがDescriptorのClassなんでしょうか?

2023-03-13のBlog

DirectX 12の魔導書」の「3.3 画面色のクリア」を読んで簡単に内容をまとめています。その中でDescriptorが出ています。

もうここまで来ると、今と同じ箇所を読んでいて本当に直近の解釈になりますね。

以下の様にDescriptorを解釈していますね。

うーん。

凄い貴重な記録です。

苦労して理解した難しい概念は中々忘れませんが、どうやってその難しい概念を理解したのかについては人は簡単にしかも完全に忘れてしまいます。

そして赤の他人に、その概念をどうやって理解させるのかも忘れてしまいます。

ので本来は、次の人はもっと簡単にその概念を理解する事が出来るのに、また一から同じ事を繰り返す必要が生まれてしまいます。

その過程を記録している訳で、これは大変な宝に成るでしょう。

以上でした。

今週のDirectX12を勉強する時間が後少しかなくなってしまったので、ここで「DirectX 12の魔導書」の勉強は終わりにします。

10.3 「HLSLシェーダーの魔導書」を勉強する

10.3.1 先週の復習

教科書の「3. 1. 7 ワールド行列を作成して三角形を動かしてみよう」を読んで内容を以下の様にまとめています。

うーん。

成程。

こういう事なのか。

何で定数Bufferを作成した後で、Descriptor Heapの作成になっていたのか不思議でしたが、「HLSLシェーダーの魔導書」がそのようにDirectX 12を整理したからでした。

これを分解して一つ一つの手順を確認するのも良いですが、今回は教科書の進めるままに勉強する事にします。

10.3.2 「3. 1. 7 ワールド行列を作成して三角形を動かしてみよう」を実装する

先週は内容を理解したので今週は実装する事にします。

DownloadしたSampleを開き、Sample_03_01を起動させます。

<定数Bufferを追加します>

何故か、既に追加されていました。

<Descriptor Heapの作成>

以下の様に作成しました。

この部分の実装は「HLSLシェーダーの魔導書」の作者が作成したClassを元にしているので、これを見てDirectX12についてどうこうは言えないです。

のでこのまま進みます。

<World座標を作成>

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

<World座標をGraphic MemoryにCopy>

しました。

<Descriptor Heapを設定>

しました。

<Register b0のDataにAccessするための変数を定義する>

ここからHLSLのProgrammingになります。

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

register(b0)の意味の説明が無いですね。

これでRegisterのb0番地にあるDataがFloat 4x4 Typeである変数、g_WorldMatrixにCopyされると言う事でしょうか?

<World Coordinateと(三角形の)座標を掛けて座標変換を行う>

しました。

VsOutの値をIn.posと先程、Registerのb0番地にあるDataをCopyしたg_WorldMatrixを掛ける事で、三角形の位置を移動させている訳です。

それは分かります。

<結果>

結果です。

三角形がずれています。

10.3.3 「3. 1. 7 ワールド行列を作成して三角形を動かしてみよう」を勉強した感想

うーん。

ここは何を理解すれば良いの?

この教科書でしか使用されていないClassの使用方法を覚えても意味はないですし。

HLSLの使用方法の解説はほとんど無いですし。

うーん。

まあ、あんまり考えないで軽くやる事にします。

10.4「Direct3D 12 ゲームグラフィック実践ガイド」の勉強

10.4.1 先週の復習

SWAP_CHAIN_DESC構造体のMemberの内、FormatとScanline Orderingについて勉強しています。

FormatはRGBAのそれぞれのサイズとかTypeを指定しています。

Scanline Orderingは走査線の描画方法の指定をしています。

走査線を描画する方式には「インターレース方式(飛び越し走査方式)」と「プログレッシブ方式(順次走査方式)」の2つがあり、更に「インターレース方式(飛び越し走査方式)」は奇数フィールドと偶数フィールドを交互に表示するそうです。

10.4.2  SWAP_CHAIN_DESC構造体のMemberの勉強の続き

今週はBufferDesc構造体の最後のMemberであるScalingについて調べます。

公式のSiteによるDXGI_MODE_SCALING enumeration [17]の説明によると

と書かれていました。

生成されたImageとMonitorの解像度のサイズが同じ出ない場合、Imageを拡大縮小してMonitorのサイズに調整する必要がある訳です。

その調整方法をここで指定するみたいですね。

このサイトでは以下の3種類の調整方法が紹介されていました。

それぞれの機能です。

これ読むと、指定しない。Stretchしない、Strechする。の3つの機能のどれかを指定してるだけですね。

どのようなStrechの仕方を指定するのではなく、Strechするかしないかを指定しているだけでした。

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

11.まとめと感想

今週も時間が無いのでまとめは無しにします。

12.参照(Reference)

[1] CGHOW. (2023c, March 31). Ribbon Fire in Unreal Engine 5.2 Niagara Tutorial | Download Files [Video]. YouTube. https://www.youtube.com/watch?v=rVrZltluAuQ

[2] Magee, R. (n.d.). Foundations | Overview | SideFX. https://www.sidefx.com/tutorials/foundations-overview/

[3] OlympusMonsTutorials. (2021, March 17). C++ DirectX 12 Game Engine - [S01E03] - Creating A Game Engine [Video]. YouTube. https://www.youtube.com/watch?v=YgZSSE3qZqA

[4] NumenBrothers. (2023, February 18). Let’s Build the RPG! - 56 – Landscape Cave Sculpting and Lighting – Unreal Engine 5 Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=EYwfDQK645Y

[5] EZ Unreal. (2023, March 16). Unreal Engine 5 Quick Tutorial: How To Change Water Color (Water Plugin) [Video]. YouTube. https://www.youtube.com/watch?v=RYnjffgXKCw

[6] Ben Cloward. (2022, November 24). Car Paint Shader - Advanced Materials - Episode 9 [Video]. YouTube. https://www.youtube.com/watch?v=dtc3WmL5OTU

[7] Voronoi Noise. (2018, September 29). Ronja’s Tutorials. https://www.ronja-tutorials.com/post/028-voronoi-noise/

[8] 14.5. Cell Noise. (n.d.). https://docs.gimp.org/2.10/en/gimp-filter-noise-cell.html

[9] Depth Material Expressions. (n.d.). https://docs.unrealengine.com/5.1/en-US/depth-material-expressions-in-unreal-engine/#depthfade

[10] フリーBGM(音楽素材)無料ダウンロード|DOVA-SYNDROME. (n.d.). フリーBGM DOVA-SYNDROME. https://dova-s.jp/

[11] 音源利用ライセンス|フリーBGM DOVA-SYNDROME. (n.d.). フリーBGM DOVA-SYNDROME. https://dova-s.jp/_contents/license/

[12] ACDev. (2022, November 2). Change Music During Gameplay in Unreal 5 [Video]. YouTube. https://www.youtube.com/watch?v=8wbtWj_MQ9w

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

[14] ゆるコンピュータ科学ラジオ. (2023, April 16). オブジェクト指向は万能の薬ではなかった。関数型の流行へ。【プログラミングパラダイム・シフト5】#68 [Video]. YouTube. https://www.youtube.com/watch?v=67eYUUq8yXs

[15] freeCodeチャンネル. (2022, June 14). 関数型言語とは何か?(Haskellで学ぼう)【歴史~オブジェクト指向との比較】 [Video]. YouTube. https://www.youtube.com/watch?v=4zSEJ7T2Qnc

[16] GOTO Conferences. (2018, November 9). Functional Programming in 40 Minutes • Russ Olsen • GOTO 2018 [Video]. YouTube. https://www.youtube.com/watch?v=0if71HOyVjY