UE4の勉強記録

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

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

1. 今週の予定

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

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

先週まとめた以下の事をやります。

後、草のMaterialの場合、Displacementを実装させないと写真を張り付けた感が凄く出てしまいます。

その辺の実装方法についても調査・検証します。

Niagaraの勉強>

先週、勉強したCGHOW氏のSprite Based Animated Butterflies in UE 5.1 Niagara Tutorial | Download Files [1]を実装します。

<Materialの勉強>

Ben Cloward先生のSnowy Rock Shader - Advanced Materials - Episode 4 [2]を勉強します。

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

魔法使いのEffectを作成します。

<Gaeaの勉強>

Andrea Cantelli氏のGaea Tutorial for Beginners #5 | Creating the shape of our first terrain [3]の続きを勉強します。

先週のErosionについてのまとめの続きを行います。

<Houdiniの勉強>

今週も公式のTutorialであるFOUNDATIONS | OVERVIEW [4]の続きを勉強します。

<Volumetric Cloudの勉強>

Volumetric のPluginにあるMaterial全部の雲の表示方法を確認します。

DirectXの勉強>

Olympus Mons Tutorials氏のC++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [5]のFormatting Our Codeを勉強します。

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

2.1 Displacementの実装方法について

たまたまですがYouTubeのお薦めに出てきたUsing Poliigon displacement textures in Unreal Engine 4 [6]にDisplacementの使用方法が紹介されていました。

これを勉強します。

まず軽く全部見ます。

見ている途中で知ったんですがUE5にはTessellationが無いそうです。

公式のCommunityにWhere is the “Tessellation” options in Ue5 Materials [7]と言う質問が載っていました。

軽くこのSiteの解答を読んだ感じでは、NaniteがあるからTessellationは要らない。と言うのがUE5の立場みたいです。

言われてみると世界中に衝撃を与えたUE5のデモであるValley of the Ancientでは

そもそもLandscape自体使用していません。

Landscapeは軽めに作成して石や岩、そして草なんかも全部Naniteで全部配置すべきという考え方なのかもしれません。

Pluginを使用したらUE4のTutorialで出てきたようなやり方も出来るみたいですが(Material Displacement in Unreal Engine 5 [8])

あんまり主流のやり方ではないみたいです。

うーん。

今確認したら確かにUE5のMaterialには以下のTessellationのParameterが無かったです。

でもMaterialのMainノードには

があるのでLandscapeの変形出来そうなんですが?

後、雪山を歩いたときの地面の変形はどうするんでしょうか?

これTessellationなしだと出来ないんじゃ。

あ!

UE5を使用して作成しているGameのBlack Myth WuKongで雪山を歩いて足跡が付いているSceneがありました。

https://www.youtube.com/watch?v=nOMIwsupy9k

より

これ見ると雪の上を歩いたときにLandscapeのDisplacementが確実に起きています。

となるとUE5でもLandscapeの変形をする方法はあるはずです。

これは後で考える事にします。

Where is the “Tessellation” options in Ue5 Materials [7]を読んでいたらDisplacing Geometry: Creating ‘Ninety Days’ in Unreal Engine 5 [9]というQuixelが直々にUE5でStatic MeshにTessellationを使用する方法を解説している動画が出て来ました。

それよりもこのForumで喧嘩を始める人が出てきてまるで5chのような変な賑わいが始まってしまっています。

まあUE4でTessellationを使用してGameを作成してきた人達が、それがUE5で使えなくなったら怒り心頭に発するのも理解出来ますし、そうやって頑張って来た人の努力が一瞬で無に帰るのを見て、ざまーと思う人の気持ちも分からないではないです。

しかし、アメリカ人も日本の5chのような喧嘩をするんですね。

笑ってしまいました。

それは兎も角、UE5におけるLandscapeのTessellationの方法かそれに代わる方法が存在するのかどうか、とTessellationは使用しないで、Naniteを使用したStatic Meshで代用した場合の正しい方法は知っておきたいです。

今回のDisplacementの調査はここまでにします。

今回のLandscapeに使用するTextureはなるだけ凹凸のない物にします。

2.2 Nodeの線をWarpさせるNodeがあったはず。それを探す

これは先週の内に見つけました。

Named Rerouteノードです。

ただ先週は実際に試してみる事はしなかったので試してみます。

普通に出来ています。

2.3 Rockのテカリを直します

以下に示したように岩が異様にテカっています。

これはUnreal Sensei氏の以下に示したTutorialにその直し方が載っていたはずです。

The Secret to Realistic Landscapes in Unreal Engine - UE4 Tutorial [10]を見ます。

見ました。

Specularの値を調整してテカリを無くしています。

しかし私のMaterialを見直したら、元々Specularの値には0を入れていました。

という事は私の場合は単純にRockに使用しているTextureが白すぎると言う事みたいです。

以下に示した様に

Textureの色の明るさを調整するParameterを追加して色を濃くしました。

結果です。

これが

こうなりました。

あれ?

岩が暗くなるだけじゃなくて緑の部分が増えていますね。

Landscape自体が緑色になっています。

ふーん。

今まで、緑色だったけど岩が白すぎて見えなかった箇所が可視化されるように成ったみたいです。

このやり方だと、他のLayerに干渉されますね。

一応、以下にUnreal Sensei氏のSpecularの調整方法をまとめておきます。

実際はLandscapeが白すぎたらSpecularの値を0にするだけで十分な気がします。

Specularの必要な地面ってないですし。

2.4 Macro VarianceとDistance Blendingの実装部分をMaterial Function化

どうやってMaterial Function化しようか考えたんですが、やり方がHow to INSTANTLY TEXTURE your landscapes in UE4 - Unreal Engine tutorial [11]に載っていました。

このやり方は別にすべてのLayerに使用出来るMaterial Functionを一個作成すると言うのではなく、単にそれぞれのLayerを別のMaterial Functionとして作成してそれを使用する事で見栄えを良くするすると言う、コロンブスの卵的な整理方法でした。

そのまま採用します。

以下の様になりました。

すっきりしました。

全然、頭を使わないで解決しましたが、これもありでしょう。

2.5 Hex Gridの実装が出来る様にする

これを今からやるのは大変なので、今回はパスします。

2.6 サイズを変えたLandscapeも検討する

今あるLandscapeが壊れたら嫌なので、新しいLandscapeを作成して試してみます。

2倍のSizeでImportしました。

Landscapeを見てみます。

細かい点をPaintで修正するならこれでも何も問題なさそうです。

Maskを追加してLayerを付けてみます。

あれ、何で昔のMaterialが使用されているの?

Materialを変更しました。

うーん。

あんまり大きさが変化した気がしません。

大きいのが常に良いわけではないですが、歩き回った感じではこっちの方が良いです。

2.7 Landscapeの凸凹を直す

うーん。

ここだけ手動でSmoothにしてみました。

かなり良い感じになりました。

どうせ手動で修正しないといけないのなら、4 x 4 km^2のLandscapeもGaeaの無料版で作成した方が良い気がします。

この島はかなり退屈です。

行きたいと思う場所がないです。

残りの時間はLandscapeの凹凸を直します。

どのくらい大変なのか分からないので自分で経験してみます。

一時間位やりましたが気持ち悪くなりました。

もうやめます。

こういう頭は使わない単純労働は私には合わないです。

後以下に示しますが。

Smoothにしたから良いと言う訳でもなさそうです。

Smoothにしたらなんか変になってしまった箇所も沢山あります。

こういうのは直さないでそういう使用という事にした方が良い気がします。

2.8 新しいLandscapeの作成について

流石に今使用しているIslandのLandscapeは品質が低すぎなので、新しいTerrainをGaeaで作成する必要があります。

これはGaeaの勉強で作成します。

それまではこのLandscapeを使用します。

2.9 来週の予定

来週からFoliageを追加します。

これでLandscapeの凸凹も隠してしまいます。

そういえば一個Foliageで勉強しないといけない事がありました。

Procedural Foliageについてです。

こいつで生成した木にはCollisionが発生しないはずです。

でも何で突然、色々なUE5のTutorialで紹介されているんでしょうか?

もしかしてCollisionが追加されたとかあるんでしょうか?

その辺も調べる事にします。

3.Niagaraの勉強

今週は先週勉強したCGHOW氏のSprite Based Animated Butterflies in UE 5.1 Niagara Tutorial | Download Files [1]を実装します。

先週のBlogを読み直して思い出したんですが、これ理解出来ない部分があったんです。その部分が今回実装出来るかどうか分かりませんが出来る所までまずやります。

3.1 Sprite Based Animated Butterflies in UE 5.1 Niagara Tutorial | Download Files [1]を実装する

<Materialの作成>

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

Tutorialとは違い、黒字に赤の矢印です。

これでMaterialではRの値を得るだけで良くなるはずです。

Texture EditorでRのImageを見ると以下のようになっています。

このTextureを使用してMaterialを作成します。

まず以下の様に実装しました。

結果です。

今は灰色と白ですが、NiagaraでParticle Colorに色を指定したら赤や緑に変換出来るはずです。

更にここから矢印を回転させます。

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

こんな回転、何も見なくても自分で実装出来るは、と自分でやったら出来ません。

何で?

先週のBlogで確認したらCustom Rotatorノードの代わりにRadial Gradient Exponentialノードを使用していました。

Radial Gradient Exponentialノードは

こういうやつでした。

勘違いしていました。

<矢印のMaterialを使用したNiagaraの作成>

<<Niagara Systemの準備>>

Fountain Emitterを追加したNiagara Systemを作成しました。

名前はNS_Butterflyとしました。

要らないModuleを消しました。

消したModuleは

Particle Spawn SectionではShape Location Module、Add Velocity Moduleの2つです。

Particle Update SectionではGravity Force Module、Drag Module、そしてScale Color Moduleの3つを消しました。

最後にEmitter Update SectionのSpawn Rate Moduleを消してSpawn Burst Instantaneous Moduleを追加しました。

こんな感じになりました。

<<矢印のMaterialをSpriteに使用する>>

今度はSpritのMaterialを交換して矢印を表示します。

まずSpriteのSizeを大きくします。

Particle Spawn SectionにあるInitialize Particle Moduleの

Sprite AttributesにあるSprite Size ModeをUniformに変更して

Uniform Sprite Sizeを100に変更します。

TutorialではここでMass ModeをUnsetに変更していますが、

おそらくですが、これはSpriteのサイズを変更するために必要な事ではなくて、いつもの設定をこのTimingでついでにしただけだと思います。

ここでやっとRender SectionのSprite Renderer Moduleの

MaterialにM_Arrowをセットしました。

結果です。

矢印は写っていますが、向きがおかしいです。

これを直すためにParticle Spawn SectionのInitialize Particle ModuleのSprite Rotation Modeを

に変更しました。

その結果、必ず矢印が上を向くようになりました。

先週のBlogでは

と述べていました。

Particle Spawn SectionのInitialize Particle ModuleのSprite Rotation ModeをUnsetにするのは、矢印を常に上に向けるためです。

最後にこの矢印に色を追加します。

Initialize Particle ModuleのColorの設定を以下に示した様に変更します。

結果です。

矢印が赤くなりました。

<<矢印を2つに増やす>>

今度はこの矢印を2枚に増やします。

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

結果です。

何も変わっていません。

これは2つのSpriteが全く同じ位置に生成されているからです。

2番目のSprite Renderer ModuleのDefault Pivot in UV Spaceの値を以下の様に変更します。

結果です。

矢印が2つ現れました。

<<2つ目の矢印をGreenにする>>

こっからが少し難しくなります。

まず先週のBlogに書かれている以下の事を理解します。

つまりここに別な色を保持するParameterをセットすればこのSpriteの色を変更する事が出来ます。

一応、自分のSprite ModuleのColor Bindingを確認しました。

ここにセットするための新しいParameterを作成します。

これNiagaraなのでParameterと呼んでいますが、普通に変数(Variable)です。

Particle Spawn SectionにSet Parameters Moduleをセットします。

このSet Parameters ModuleのAttributeを見ると以下の様になっています。

PlusのIconを押して以下のBoxを表示させます。

Make NewからLinear Colorを選択します。

以下のParameterが作成されました。

名前はSub Arrow Colorに変更しました。

色は緑色です。

TypeはLinear ColorでName Spaceは[PARTICLE]です。

これを2番目のSprite Renderer ModuleのColor Bindingにセットすると

以下の様になりました。

Tutorialと逆ですね。

分かりにくいのは嫌なので、このSprite Renderer ModuleのColor Bindingの設定は元に戻して、もう一方のSprite Renderer ModuleのColor Bindingを変更する事にします。

Tutorial同じ様になりました。

<<緑の矢印のSpriteのFacingを変更する>>

ここからが今週のMainであるSpriteのFacingの調整になります。

Sprite Renderer ModuleのAlignmentとFacing Modeの設定は以下の様になっています。

これを以下の様に変更します。

まずAlignmentが何にAlignするのかが分かりません。

これから調査します。

AlignmentにCursorを重ねたら以下の説明が出て来ました。

Texture having an arrow pointing upとは要するにTextureのNormal Vectorの事でしょう。それがどのように並ぶのかを決定すると言っている訳です。

ではそのHowの部分の設定であるCustom Alignmentを見てみます。

何か色々説明しています。

最初の部分はTextureのNormal Vectorを説明しているだけでしょう。ここは無視して次に行きます。

次の文ですが、

Custom Alignmentにセットすると[PARTICLE] Sprite AlignmentにセットされたAxisに向かうようにTextureのNormal Vectorをセットすると読めます。

Sprite Renderer Module内で検索したら

が出て来ました。

これにセットされているAxisに向かうようにTextureの向きを変更するって事でしょうか?

次の文を読みます。

Facing Modeの設定は無視します。

Facing ModeとはAlignmentの下にあるAttributeの事です。

今回はCustom Facing Vectorにセットされています。

この設定は無視される。と言っています。

へー。そうなの。

じゃこれ設定しても無駄なのね。

次の文を読みます。

Unless Custom Facing Vector is set.

はい。

AlignmentにCustom Facing Vectorをセットした場合、Facing Modeの設定を無視して[PARTICLE] Sprite Alignmentにセットされている値に向かうようにTextureがセットされます。

ただしこれには例外があってFacing ModeにCustom Facing Vectorがセットされていた場合は違います。

と言う意味でした。

その後の文はあんまり今回の件には関係ないのでこれまたSkipします。

次はFace Modeです。

以下の解説が書かれていました。

これってAlignmentと同じじゃん。

うーん。

次のCustom Facing Vectorの解説も見ます。

Attributeである[PARTICLE]SpriteFacingに保持されているVectorに向かってBillboardの正面が向くようにします。

とあります。

結局この設定だと[PARTICLE]SpriteFacingに向くことになるみたいです。

AttributeであるSprite Facingには[PARTICLE] Sprite Facingがセットされていました。

そしてその解説には

となっていました。

この時点で緑の矢印は(1, 0, 0)のVectorに正面を向くようになると思ったんですが、

正面を向いたままです。

ここからParticle Spawn SectionのSet Particle Moduleに

[PARTILCE] Sprite Facingを追加します。

これ、Sprite Facingと言うTypeの新しいParameterをここで作成したのか、元々あるParameterであるSprite Facingの値をここで新たに指定したのかがよく分かりません。

多分、元々あるParameterであるSprite Facingの値をここで新たに指定したと思います。

なぜなら先程のSprite Renderer Moduleの

Sprite Facing BindingでこのParameterを使用しているからです。

更にSpritFacingにCursorを乗せると以下の解説が表示されますが、

ここにSprite FacingのTypeがVectorと書かれています。

それに対して先程作成したLinear Colorは以下に示した様に

TypeがLinear Colorであると書かれています。

ので、このSet Parameter Moduleにある最初のParameterは作成したもの、次のParameterであるSpriteFacingはここで初期化したか、または値を変更しただけと判明しました。

Custom Facing Vectorの解説で以下に示した様に

Toward the Vectorと言う表現がありますが、

以下の図を見るとToward the Vectorの意味がよく分かります。

まずこの場合Vectorは(1, 0, 0)なのでX軸の正の方向に向かっています。

そしてBillboardのNormal VectorもそのVectorと全く同じ方向を向いています。

これをToward the Vectorと表現しています。

何となくTowardと言うと向かってと言う訳からVectorの向きに正対してと思ってしまいますが、実際はVectorの向きに沿ってと言う意味でした。

気になったのでDeep Lの翻訳も調べてみました。

何と、あっています。

こういう細かい部分はDeep Lも結構間違えて訳しますが、これに関しては完璧でした。

<<赤の矢印のSpriteのFacingを変更する>>

今度は赤い矢印の方のSpriteのFacingを変更するそうです。

Particle Spawn SectionのSet Parameter Moduleに

Vector typeの新しいParameterを作成します。

名前はFacing2にしました。

Tutorialではこれを赤い矢印をRenderingしているSprite Renderer Moduleの

Sprite Facing Bindingにセットしています。

いやこれするならその前にAlignmentとFace Modeの設定を変更する必要があるじゃん。

と思ったら、これをセットした後でやっていました。

まずAlignmentとFacing Modeを変更して

その後で、Sprite Facing Bindingの設定を

変更しました。

結果です。

Facing2の値とSprite Facing の値が同じなので両方とも同じ向きを向いています。

<<矢印のSpriteがFlapping(蝶が羽ばたくようにパタパタする事)するようにする>>

ここから更に難しくなります。

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

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

その通りです。

ここにSprite Facingをセットしました。

そしてそのSprite Facingの値に以下の実装をセットしました。

このYawの回転ですが、Z軸の周りを半時計まわりに回転します。

正面から見た図です。

Yawの値を上げると

緑の矢印が半時計周りにグルグル回転し始めました。

これだけだと何とも言えないので、

Particle Spawn SectionのSet Parameter ModuleのSprite Facingの値を以下の様に変更して

緑の矢印のBillboardのNormal VectorをY軸にTowardするようにセットして

Yawの値を上げました。

これもZ軸に対して半時計周りに回転しました。

これだと。Z軸に対して回転しているのか。Billboardを正面から見た時に左右に回転しているのかが不明です。

ので以下の様にZを1にしました。

この状態でYawの値を上げたんですがBillboardが動きません。

全く動かないんです。

これは面白い。

Sprite Facingの値をX=1に戻しました。

これでX軸の周りを回るRollの値を増やしてみました。

これもBillboardは動きませんでした。

うーん。よく分かりません。

ここはここまでにして続きをやります。

この後、Tutorialでは蝶がパタパタする角度じゃないと色々やり直しているんですが、私の先週のBlogを見ているだけでは何を直したのか分からないのでもう一回Tutorialを見ます。

分かりました。

蝶が羽ばたくようにしたいのに、それぞれのBillboardの真ん中を中心に回転しています。これを2つのBillboardの中心で回転するようにしたいんです。

あれ、この問題Tutorialは起きていません。最初から2つのBillboardの中心で回転しています。

私のだけそれぞれのBillboardの真ん中を中心に回転しています。

兎に角この問題をまず直します。

この問題の原因が分かりました。

Default Pivot in UV Spaceの値を(0.5, 0.5)と(-0.5, 0.5)にしていました。

Tutorialでは(0, 0.5)と(1, 0.5)でした。

これで2つのBillboardの中心で回転するようになったんですが、今度は緑と赤が逆になってしまいました。

これは0と1を交換して直しました。

これでTutorialと同じ状態になりました。

ここからTutorialはYawの値をTweetしていたら以下の様になって

これはオカシイと直し始めます。

私の場合もCameraを移動していると以下の様にTutorialと同じ結果になりました。

これってCamera の位置によって見え方が変わっているだけなのか、

Cameraの位置によってBillboardの向き自体が変わっているのか知りたいです。

兎に角、Tutorialではこの問題を解決するために以下の方法を採用しています。

Particle Spawn SectionにあるSet Particle Moduleの

Sprite Facingを消して

Particle Spawn SectionにSprite Facing and Alignment Moduleを追加しました。

でもこの問題は直っていません。

そしたらSprite Facing and Alignment Moduleは消して、元に戻してしまいました。

はい。

ここでTutorialは更に色々やっていますが、私は同じ事をやるのが嫌なのでとりあえず2つのSprite RendererのAlignmentを

Velocity Alignedに変更してみました。

直りました。

Cameraをどの角度に変えても

2つのBillboardが重なる事は無くなりました。

うーん。

なんで?

Velocity Alignedの解説を読みます。

うーん。

分からん。

何でこれでCustom Alignmentと違う結果になるの?

ひょっとしてArrow pointing up てTextureのNormal Vectorじゃないって事。

公式のDocumentであるNiagara Renderers [12]に以下の解説がありました。

これ見るとParticleに矢印が付いているって書いていますね。

つまりParticleについているSpriteのNormalとは別な矢印が存在しているって事です。

あ。

段々、分かってきました。

そういえばContent ExamplesのNiagaraにそういうのがあったはずです。

こういうやつです。

後、CGHOW氏のTutorialでもSprite Rotation Sprite Alignment Sprite Facing | UE5 Niagara Tutorial | Download Project File [13]で勉強していました。

このTutorialは後で勉強する事にします。

色々考察したんですが、ここは今ある情報だけで考えても分からないとの結論に達しました。

この辺で諦めて先に進ます。

今度はこのSpriteの動きをパタパタさせます。

まずParticle Update SectionのSet Particle Moduleの

Sprite FacingのYawの値にSineをセットし

そのSineのAttributeの値を変更します。

結果です。

緑の矢印がパタパタしはじめました。

それは良いんですがパタパタの角度が少し違う時がある気がします。

はい。

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

残りは来週やる事にします。

4.Materialの勉強

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

4.1 Snowy Rock Shader - Advanced Materials - Episode 4 [14]を勉強します

まず全体の構成を知るために軽く全部見ます。

40分以上の大作ですが、最初の半分はUnityにおける実装を説明しているのでその部分はSkipして残り半分のUE5の解説だけ見ました。

以下の右端に示したような雪が積もったRockを作成しています。

内容的には前回作成したRockと前々回作成した雪を組み合わせたものになっています。

Rockと雪の実装はそのまま使用すると複雑すぎて訳分からないくなるので、Material Functionを使用して整理してから組み合わせています。

LerpノードのAlphaでRockの場所と雪の場所を指定していますが、このAlphaの指定方法が少し複雑な位で、後はそんなに難しくないです。

今週のNiagaraの勉強と比較するとかなり簡単に見えます。

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

まずRockのMaterialをMaterial Functionを使用して整理します。

以下にRockの実装を示します。

赤線①で囲った部分はRockのBaseを作成するための実装です。ここでMaterial Functionを一つ作成します。

その下の赤線②で囲った部分はRockのMacro DetailとMicro Detailの実装の部分です。Macro Detailの実装とMicro Detailの実装は同じなのでここで一個のMaterial Functionを作成してMacroとMicroの両方に使用するそうです。

はい。

まずRock BaseのMaterial Functionだそうです。

これを見るとInputは特にないですね。

つまりRockに使用するTextureはそのままMaterial Function内に閉じ込めている訳です。

このMaterial functionを使用する事が出来るのはこのMaterialだけでこのMaterial Functionに一般性は全くないです。

これだったら直ぐに作成できます。

Outputには以下に示した5つがありました。

これも特に問題ないです。

Tutorialの説明を聞いていたら、ここで使用されているTextureはParameter 2Dになっているので

Material Instanceでその内容を編集する事が可能になっているそうです。

あ、はい。

やっぱりTextureの編集も出来ないMaterial Functionって一寸オカシイと思っていました。

後、以下に示したRockScaleもParameterになっていました。

これってMaterialのサイズを決定するParameterでしたっけ。

まあでも内容は理解しました。

今度はMacroとMicro DetailのためのMaterial Functionです。

こっちはInputが凄いあります。

あー分かりました。

Color、Roughness、そしてNormalをそれぞれInputしています。

これらはBase Materialに属しているDataでこのMaterial Function内でBase MaterialとDetail Materialの混合もやっている訳です。

更にDetail MaterialのUVの値を見るとMacroでもMicroでもInput出来る様になっています。Textureも同じようになっています。

Tutorialを見てたらInput Functionノードの解説で以下のUse Preview Value as Defaultについて解説していました。

流石にこれくらいは常識です。

この部分はSkipしておきます。

以下にこれらのMaterial Functionを使用して整理されたRockのMaterialを示します。

Detail ScaleにMacroとMicroのTexCoord[0]に掛ける値が表示されていますね。

流石にこれだけ整理されるとBlackbox化してしまった感があります。

更にこの後にSnowのMaterial Functionも紹介されています。

このMaterial Functionはこれから作成します。

以下にこのSnowの実装を示します。

Tutorialの解説によるとこの実装は前々回に作成した雪のMaterialの実装そのままだそうです。

違いはMaterial Functionに変更した事とRockと混合するための実装を追加した所だそうです。

この混合の割合を決定するための実装ですが以下に示したSnow Maskノードが管理しているそうです。

これもMaterial Functionですね。

それぞれの実装を見ていきます。

まずColorです。

LerpノードでInputされたRockのColorと雪のColorを混合しています。

勿論LerpノードのAlphaにはSnow Maskが繋がっています。

次はNormalです。

RockのBase Normalと雪のNormalをBlend Angle Corrected Normalノードを使用して混合しています。

その後でRockのDetailを含んだNormalとLerpでBlendしています。

Tutorialではこの部分の理論を詳しく解説していますが、今一納得出来ないです。

何か変な感じがします。

この辺は実装する時に何が変なのか確認します。

Snow Sparklingです。

この実装ですがここはSnow Maskと掛けています。

Lerpは使用していません。

これでSnow Maskが有るところだけSparklingが発動するようになります。

Snow Maskの実装です。

ここからこの実装の解説です。

今週の勉強の肝ははっきりいってこの実装方法だけです。

気合を入れて勉強します。

まず雪は岩の上にのみ積もります。

その上の部分を判明するために以下に示したようにTransform Vectorノードで

World Spaceに変換します。

その結果にMaskしてB Channelの結果だけ取り出します。

BはZの値が入っていますが、これが高い方が上って事なんでしょうか?

この値が0の所は平なので雪が積もるって事でしょうか?

この計算結果のPreviewがTutorialで紹介されていました。

あれ、こういう風になるんだ。

雪が積もる部分は白、積もらない部分は黒になっています。

うーん。

World Viewに変更したから下向きのNormalのBの値はMinusになったって事でしょうか?

今度はこの結果に10を掛けています。

結果です。

Tutorialによると雪は積もる箇所と積もらない箇所以外の合間の部分は存在しないので10を掛けてその灰色の部分を消したそうです。

次の実装ですが以下の値をAddノードで足しています。

このInput CoverageはRockを覆う雪の量を決定するInputなはずです。0だと-15で1だと3になるのか。

これらの値を追加するとどうなるんの?

Tutorialを見たら分かりました。

以下にTutorialの説明をまとめます。

-5を足した場合です。

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

真っ黒です。つまり雪が積もる部分が減りました。

当然、3のような値を足したら以下に示した様に

雪の積もる部分が増えます。

以上です。

最後に結果を示します。

4.2 Snowy Rock Shader - Advanced Materials - Episode 4 [14]を勉強した感想

まだ実装していないので何とも言えないですが、全体的にはそんなに難しくない気がしました。

今まで勉強した2つのTutorialもTextureを用意するのが大変で、Tutorialそのものはそんなに難しくなかったのかのしれません。

Snow Maskの実装もTransformノードの結果が今一分からない部分を除けば大体理解出来ました。

これを勉強してすぐに知りたいと思ったのはVirtual Textureを使用して雪を被せた場合とどう違うのかです。

こういうUE5の最新の技術と比較したらどうなのかについてはこのTutorialでは学ぶ事は出来ません。

このMaterialと前のNiagaraの勉強はUE5のGame制作には直接結びつかなくても、UE5の地力をつけるための筋トレみたいな感じで勉強している訳で、それは仕方ないです。

その辺は我慢しながら勉強するしかないです。

今週のMaterialの勉強はここまでとします。実装は来週やります。

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

今週は魔法使いのEffectを作成します。

と思ったらDragon族のEffectを作成するのを忘れていました。

そっちを先に作成します。

5.1 Dragon族の攻撃Effectを追加する

ドラゴンのEffectですが、攻撃力が同じ亡霊族と同じにしておきます。

ここでいきなり問題発生です。

先週、

と設定しましたが、Data Sheetには以下の様に記録されていました。

うーん。

どうしよう。

地面が氷攻撃するのは何となく分かります。

火が雷攻撃するのも有りと言えばありか。

となると緑が火の攻撃もありですね。

はい。解決。

それではAnimationを追加していきます。

Monsterの攻撃Animationを管理しているLevel BPのAttack Animation関数では以下のような順番でDragon族のAnimationを設定しているのでその順番でEffectを追加します。

まずDragon地面です。

今使用している攻撃AnimationのCopyを作成しました。

ここにIceのEffectを追加しました。

更にIceのEffectの発生する位置をずらしました。

Preview画面です。

Dragonが光っていてよく分かりません。

Level上で確認します。

なんとDragonを小っちゃくしていたのでEffectも同じように小さくなってしまっています。

その分Animation内で拡大する必要があるみたいです。

MonsterをSpawnするための関数をみたらDragon族はScaleを0.2倍していました。

つまり5分の1のSizeになっています。

その分Animation Sequenceの方で大きくしてみます。

しました。

Reviewの画像です。

実際のPlay画面です。

前よりは格段に良くなりましたが、まだ敵に届いていません。

色々、微調整したら以下の値でちょうどいい攻撃をするようになりました。

こんな感じです。

Skeletal MeshのScaleを変更すると何かがおかしくなるのは前のRGBの作成の時に経験しました。

のであんまりやらない方が良いかもしれません。

Packagingのテストはした方が良いですね。Dragon族の攻撃Effectが完成した後でやる事にします。

次は火のDragonに雷攻撃のEffectを追加します。

こんな感じになりました。

Animation Sequenceにおける設定です。

以下の様になりました。

良い感じです。

同様に最後のDragonの攻撃Effectも作成します。

Animation SequenceのPreviewの画像です。

実際のGame画面で確認します。

これで十分でしょう。

最後にPackagingしてこれらのEffectが同じ様に発動するか確認します。

ただし、普通にPackagingしたのではDragon族が現れるのはStage9からです。

Testするのにそんなに長くGameをPlayする事は出来ません。

Stage毎に登場するMonsterを管理しているW_OpponentSummonDecideの

Stage1の実装を少しだけ変更して

Stage1からDragon族だけ召喚されるようにしました。

これでPackagingします。

今回は5分位でPackagingが終わりました。

Exe FileからPlayしてみます。

Effectは普通に発動しています。

氷攻撃のEffectです。

普通に発動しています。

最後に火の攻撃Effectです。

これも普通に発動しています。

問題ないですね。

5.2 魔術師のEffectを追加する

これが一寸、問題があります。

いや、問題がある部分があります。と言った方が正解に近いです。

まず問題のないMonsterを召喚するAnimationのEffectの追加からやります。

使用しているAnimation SequenceのAttack02_MagicWandAnim

をDuplicateします。

このDuplicateした方にNiagaraのEffectを追加します。

いきなりぴったりなEffectを見つけました。

NS_Status_LevelUpです。

こんなEffectです。

しかもSpawn Burst Instantaneous Moduleを使用しているので

Effectが消えてくれるはずです。

試しにAnimation SequenceのAttack02_MagicWandAnimのDuplicateした方に付けてみました。

今度はLevel上で試してみます。

LevelBPの設定を変更しました。

結果です。

普通に発動していますが、このCameraの位置からだと光の直撃したEffectが見えないのでかなり地味なEffectになってしまっています。

一寸だけ調整します。

こんな感じにしました。

試しにEffectを2個にしました。

結果です。

かなり良い感じになりました。

今度は対戦相手の魔術師の召喚AnimationにEffectを追加します。

凄いEffectを発見しました。

NS_Status_Teleport_Burstです。

こんなEffectです。

以下に示した様にSpawn Burst Instanantaneous Moduleを使用して

いるので一回Effectが発動したら消えてくれるはずです。

Animation Sequenceに組んでみました。

こんな感じです。

何か、何回も発動している感じがします。

何で?

Play画面で確認します。

綺麗なEffectが表示されました。

かなり良い感じです。

あれ、Effectが止まりません。

うーん。

このEffectをDuplicateしてそれを直す事にします。

原因が分かりました。

System StackのSystem State Moduleの

Loop BehaviorがInfiniteになっていました。

Onceに変更しました。

テストします。

一回だけEffectが発動して終わりました。

直りました。

今度は魔術師が魔法を使用する時です。

これはAnimation Sequenceを交換するだけで出来ました。

対戦相手の魔術師が魔法を使用する時です。

調べたらこれは無かったです。

対戦相手の魔術師は戦闘が始まったら魔法は唱えなかったです。

ここまでは簡単な所です。

次に難しい部分について検証します。

5.3 魔術師が魔法を唱えた後のEffect

魔術師が魔法を唱えた後、その対象のMonsterには魔法の効果が発動します。

ところがその部分はAnimationもないのでEffectの追加も出来ません。

うーん。

そうか、先にAnimationを追加すれば良いのか。

調べました。

Level BPの以下の部分のどこかにAnimationを挟めばいいです。

以下の様に魔法を掛けられたMonsterのAnimation用の関数を追加します。

この関数を実装します。

とりあえず回復魔法を受けた時のAnimationだけ追加する事にしました。

一応、敵のMonsterにも回復魔法が掛けられるようになっていますが、そのAnimationの実装は後でします。

今は、味方だけのAnimationを追加しました。

途中でMonsterの種類によって使用するAnimation Sequenceが別になる事に気が付きました。

なのでHelper Methodを追加しました。

Helper Methodの実装です。

掛けられた魔法とMonsterの種類によってAnimationを選択できるようになっています。

今回は、掛けられた魔法は回復魔法しかなく、Monsterも妖精族の3つのMonsterの時だけ実装しました。

魔法を掛けられた時のAnimationですが、

付属のAnimationに魔法で回復した時のものが無かったので

Damageを受けた時のAnimationを採用しました。

Animationが終わった後、元のIdlingのAnimationに戻す実装です。

最初、元のIdlingのAnimationに戻す実装を全部作っていたんですが途中で、前に作成したSet Anim for Monster関数を使用すれば良い事に気が付いて上記のような実装になりました。

テストします。

出来ています。

Screenshotがうまく取れませんでした。

でも魔術師が魔法を唱えた後で、DamageのAnimationが発動しました。その後でIdlingのAnimationに戻ったので出来ています。

残りの魔法のAnimationも追加します。

よく考えたらDamageのAnimationを使用するなら以下の実装で魔法を受けた全部のMonsterのAnimationを表示出来ます。

これだと後で、Effectを追加するの事が出来ないですが、その時はDamage Animation関数をDuplicateして別な関数を作成しそこにEffectを追加したAnimationをセットします。

万が一、魔法を対戦相手のMonsterに掛けた時もanimationが発動するようにしました。

というか対戦相手のMonsterに魔法を掛けた事は無いです。

これもきちんと動くのかテストして確認する必要があります。

ここからが問題です。

回復と攻撃力2倍の魔法を受けたMonsterのAnimationは無事追加されましたが、魔法SwitchのAnimationを追加する必要があります。

所がこの魔法、魔法を受けたMonsterのAnimationの前のNodeであるCalculate Player Magic Effect()関数で既に位置を交換してしまっています。

うーん。どうしよう。

以下の様に実装の順番を変えました。

まず①で魔術師が魔法を唱えたAnimationを実行します。次に②で魔法を唱えられたMonsterのAnimationを実行します。最後の③でCalculate Player Magic Effect()関数を実行します。

これでSwitchの魔法のAnimationもMonsterが交換する前に実行出来るようになったはずです。

しかしSwitchの魔法を使用する前にこの実装でも回復魔法を受けたMonsterのAnimationが正しく実行されるのかを確認します。

しました。

回復魔法と攻撃力2倍の魔法の両方を試しましたが何の問題の無かったです。

魔法を受けた時のAnimation時のScreenshotは取れませんでした。

それではSwitchの魔法を受けた時のMonsterのAnimationを追加します。

この後、IdlingのAnimationを追加する必要がありますが、一端これでTestします。

Errorになってしまいました。

原因が判明しました。

Play Magicked Monster Animationノード内の

以下のVariableが、

Switchの魔法の時はNullになっています。

ので以下のNodeで

Noneが選択されErrorになりました。

以下に示した様に

Noneの時はSwitchの魔法を使用した時なので、どの選択肢を選んでも良いです。

Player Right Wingに繋げました。

これでerrorにはならないはずです。

テストします。

今度は出来ました。

Screenshotは取れませんでした。

交換される2体のMonsterがDamageのAnimationを発動して、位置を交換した直後のScreenshotです。

最後に魔法にかかったMonster達のAnimationをIdlingに戻すための実装を追加します。

以下のHelper Methodを作成して交換魔法の時の2体のMonsterのAnimationをIdlingに直すときにも対応できるようにしました。

この関数の実装です。

単にSet Anim for Monster関数を繰り返し使用しているだけです。

この後、魔法を掛けられたMonsterにEffectを追加する予定でしたが、それは来週に先延ばしします。

このAnimationの追加だけでも結構実装が変わったので、そのCheckが終わってからEffectを追加する事にします。

来週は、

  • 今週追加したAnimationのBugの確認
  • Packingして同じように動くか
  • 魔法を掛けられたMonsterのEffectの追加

を行います。

今週はここまでです。

6.Gaeaの勉強

6.1 今週の予定

今週は何をする予定だったのか忘れてしまったのでの先週のBlogを読み直します。

思い出しました。

先週、調査したErosion Groupに含まれる15個のNodeをそれぞれの機能から分類するのをまずやります。

その後で、Andrea Cantelli氏のGaea Tutorial for Beginners #5 | Creating the shape of our first terrain [3]の続きを勉強します。

後、GaeaというかこういうNoiseからLandscapeを生成する方法が完璧じゃない事も分かってきたのでその点についても論じます。

6.2 Erosion Groupにある15個のNodeを整理する

先週、Erosion Groupにある15個のNodeの機能について詳しく調査しました。

これらを更に分類しようと思います。

色々な分類方法があると思いますが、ここで大切なのはErosionの工程で使用出来るかどうかです。

まずErosionの工程に使用出来るか出来ないかで分ける事にします。

<出来る>

Erosion、Wizard

この2つはErosionの効果を追加するだけじゃなくて、どんなErosionを追加したら良いのか不明な時に、とりあえずErosionを追加しておくか。と言う時にも使用出来ます。

<かなり出来る>

Alluvium、Thermal、Deposits、Hydro、Sediment、

ここに選んだ5つのNodeはErosionをある条件に基づいて追加します。独特のErosionを追加します。

それがその地形にあったErosionなら良いですが、雪山でしか起きないErosionを火山とかに使用した場合、見た目が変になるのか、それとも誰も気が付かないのか不明です。

<微妙>

Convector、Crumble、Fluvial

Terrainは一寸変化しますが、微妙な変化しか追加しません。あくまでもDefault値の場合ですが、Parameterを弄ったら変わるのかもしれません。

<単体では役に立たないが、他のNodeの補佐に使用出来る>

Micro Erosion

Micro ErosionはErosionを使用した後で使用するNodeです。そういうNodeなのでここに入れました。

<出来ない>

Breaker、Buildup、Stratify、HydroFix

ここに分類されたNodeは追加しても変化が全く見られないNodeか、変化が大きすぎてErosionとして使用するのは適切でなない。と判断されたNodeです。

Breakerは別で、亀裂を追加しますが、堆積物は追加しません。

これってErosionとして使用して良いのか判別出来なかったのでここに分類しました。

ああ、そういう事か。

Erosionの定義がまだあんまりよく分かっていなかったです。

調べます。

National GeographicのHomepageにErosionについて分かりやすく解説している記事[15]がありました。

Grade 6-12という事は中学生から高校生向けという事でしょうか。

分かりやすければなんでも良いです。

この記事が俊逸で、Erosionについて何でも説明しています。

まずErosionの定義ですが、地面が風や水そして氷などの自然の力によって削り取られてその削り取られた部分が別な場所に移動する事だそうです。

この定義の中に3つ位、必要な条件がありますね。

  • 削り取られるのが地面で有る事
  • 地面を削り取るのが自然の力である事
  • 削り取られた部分が移動する事

流石、National Geographicだけあって明確で厳密な定義です。

この定義を見るとErosionは堆積物が無くても、逆に堆積物だけあっても良い事になりますね。

もう少し読み込んで判断する事にします。

Erosionに似た言葉にWeatheringというのが有るそうです。

Weatheringの場合は、削り取られた石や土が移動しないそうです。

もしくは、自然の力で削り取られる所までがWeatheringでその後に削り取られた部分が移動するのをErosionと言うそうです。

Weatheringを先に調べます。

National GeographicにWeatheringについての解説[16]もありました。

この解説ではWeatheringについて以下の

  • Mechanical weathering
  • Chemical weathering
  • Biological weathering,

の3つに分類してそれぞれの例を詳しく説明しています。

本当に読んでいて面白いです。

専門用語には解説がついていてCursorでClickすると解説が表示されます。

こんなの小学5年生になったら理解出来る内容です。しかしこの内容の精度と深度は大学でも通じます。

こういうのを読んでいる子が14歳位で大学に飛び級してくるんですね。アメリカは。

ErosionのPageに戻るとErosionでもWeatheringと似た分類をしていました。

ここではMechanical weatheringに対応する現象をPhysical Erosionと言っていました。

そしてPhysical Erosionの原因は主に

の3つからなる事が解説されていました。

水の場合、例えば雨だと

  • splash erosion,
  • sheet erosion,
  • rill erosion,
  • gully erosion.

の4つタイプのErosionを生成するそうです。

この4つのタイプのErosionがどんなものなのか全然分かりません。

記事の解説を読んだら分かりました。

Splash Erosionは水たまりみたいなErosionです。

Sheet Erosionはそれが重なって一枚のSheetになった状態です。

Rill ErosionはそのSheetが更にくっついて小川になった状態です。

最後のGully Erosionはその小川が更にくっついて大きな川になった状態だそうです。

Googleで調べたらSplash Erosionを調べているのにSheet Erosionの写真が出てきたりして訳分からなくなります。

大体Erosionの仕組みが分かりました。

細かい点に関してはまた必要になった時に読む事にします。

元のErosion GroupのNodeに戻りますが、

基本として

  • Erosion + Micro Erosion
  • Wizard

を使用してその先に

  • Alluvium、
  • Thermal、
  • Deposits
  • Hydro、
  • Sediment、

をその時々に使用します。

<Alluvium>

川とその堆積物を追加したい時に使用します。

<Thermal>

崖の周りに堆積物を追加したい時に使用します。

<Deposits>

大量に堆積物を追加したい時に使用します。

<Hydro>

これは見直したら全く堆積物が溜まっていません。要らないです。

<Sediment>

Terrain全体に堆積物を積もりたい時に使用します。

と言う感じで使用していきたいと思います。

6.3 GaeaなどのNoiseからLandscapeを生成する方法が完璧じゃない事

ほとんどのしっかりしたLevel Designの教科書ではGaeaを含むThird PartyのSoftでTerrainを作成してそれをUEにImportしろ。と言っています。

確かにUEで直にLandscapeを作成すると山の形がもっこりしていてすぐにCGだと分かります。

それに比べるとGaeaなどのNoiseからTerrainを生成してHeight MapとしてImportした方が本物っぽいLandscapeを作成する事ができます。

しかしUE5では基本的に1Pixelを1m^2に拡大します。

結果として以下に示した「2.LandscapeのみのGameを作成する」のLandscapeのような

自然界には絶対にあり得ない、とげどげした地形が誕生しています。

これをいちいち手動で直していたら気がくるってしまいます。

こんなの無理です。

これって絶対防げない問題何でしょうか?

<UE5になってNaniteを使用すればStatic Meshをほぼ無限に配置出来るようになった件について>

これも考えておかないといけない問題です。

つまりStatic Meshで地形を作成するなら、そんなにLandscapeを頑張って作成する必要は無くなります。Landscapeは適当に作成してその上に配置するStatic Meshを頑張れば良い訳です。

UE5の時代に入ってGaeaだけ上手に作成出来ればLandscapeは完璧という事では無くなってしまったんです。

Gaeaの勉強もどの程度すべきなのか見定める時が来たのかもしれません。

6.4 Gaea Tutorial for Beginners #5 | Creating the shape of our first terrain [3]の続

先週はErosionの所まで勉強したんでした。今週はその続きからやっていきます。

<Changing Parameters>

ParameterってどのNodeのParameterを調整するんでしょうか?

一回軽く全部見ます。

見ました。

Parametersと題には入っていますが実際はParameterはほとんど弄っていません。

それよりのErosionの後にSurfaceノードを付けています。

これはどう解釈すればいいんでしょうか?

一応、今までのまとめでは以下に示した様に

最後にTerrainの表面をLookDev Groupのノードで仕上げてからErosion GroupからErosionを追加するのが正しいと思っていました。

ここだと逆ですね。

これは後で検証します。

<Adding Breaker>

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

これはTerrainに亀裂を追加するNodeです。

Breakerノードはあまりにも表面を変えてしまうのでErosionとしては使い道がないです。

何で今更ここで使用するのか不思議です。

これ使用するならErosionとLookDevの前に使用すべきだと思います。

<Other Changes>

ここは今までのNodeを一寸見直しているだけです。

<Adding Primitives>

ここから山以外の平地のTerrainの作成になります。

Geo PrimitivesのRidgeノードを追加します。

<Creating Mountain Ridges>

ここはRidgeノードのParameterを弄っているだけでした。

<Combining Nodes>

ここでCombineノードを使用して山のTerrainとRidgeノードを合成します。

ここ少しびっくりしたんですが、合成をするのはErosionやLookDevの手前でしています。

<Adding Turrets>

ここ何でAdding Turretsって題なんでしょうか?

やってる事はCombineノードのParameterの調整です。

この辺の題は内容と全く合ってないです。

私なら

  • Adding Primitives
  • Creating Mountain Ridges

で平地部分の作成という題にします。

そして

  • Combining Nodes
  • Adding Turrets

を平地と山の合成と言う題でまとめます。

<Bypass Fit>

Bypass機能について説明しています。

<Micro Erosion>

最後にMicro Erosionを使用してTerrainの表面と整えています。

ここでMicro Erosionを使用するのは大賛成です。

これでこのTutorialは終わりです。

6.5 Gaea Tutorial for Beginners #5 | Creating the shape of our first terrain [3]を勉強した感想

Nodeの並べ方は代々において賛成です。

唯一、納得できないのはBreakerをErosionの後で使用した事で、Breakerは川などによって地表が削られた状態を再現するためのNodeなのでその削られた下にErosionによるDepositが無いのは納得出来ないです。

更に言うとBreakerノードが生成する亀裂はかなり大きく、表面の形状を大きく変形してしまいます。もし使用するにしてもErosionノードを使用する前にやるべきだと思いました。

でもまあ、どうやってTerrainのNodeを組むのかはかなり理解出来ました。

6.6 もう一度手順を考える

先週、以下の手順をまとめましたが、平地の部分の手順が抜けていました。

更に全体の手順である以下の部分と合成して

一個の大きなTerrainの作成の手順をここで作成します。

  1. Geo Primitivesを使用して基礎の地形を作成します。
  2. Displace、Fold、CarverなどのNodeを使用して基礎の地形を大きく変形します。
  3. Apertureを使用して縁を調整します。
  4. 最後に表面をLookDevで調整します。
  5. 噴火や隕石の落下などの天変地異を起こしTerrainを破壊します。SwirlやWarpノードを使用します。
  6. 時間が経ってTerrainが変形します。まずはApertureを使用して縁を直します。
  7. 平地の部分のTerrainを作成します。Ridgeノードなどを使用します。
  8. Combineノードで平地とそれまで作成したTerrainを合成します。
  9. LookDevを使用してTerrainの表面を仕上げます。
  10. 最後にErosionを追加します。
  11. 更に最後にMicro Erosionノードを使用して表面を仕上げます。

出来ました。

このやり方で、初心者でもそれなりのTerrainが作成出来るはずです。

7.Houdiniの勉強

今週も公式のTutorialであるFOUNDATIONS | OVERVIEW [4]の続きを勉強します。

先週はParameterの途中まで勉強しました。

以下のBoxの使用方法が分からないと書いたところで終わっています。

7.1 Parameters

先週の続きからやります。

Houdiniを開いてNetwork Paneに以下のNodeを追加しました。

Scene Viewの画面です。

Motion FXそしてNoiseを選択して以下のBoxを表示しました。

Tutorialを見直すとまずAmplitudeの値を調整しています。

同じ事をしてみます。

Amplitudeの値を半分にしてみました。

結果です。

Characterが歪んでしまいました。

これってひょっとしてScaleのXからNoiseを開いたからなんでしょうか?

試しに全部元に戻して今度は

Translateのxから開きます。

おお、X軸上に左右にブレながら動いています。

こういう事か

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

X軸のブレが10分の1になりました。

簡単にこのNoiseの機能を説明すると以下のNoiseに表示されている値を

Objectの元のParameter、今回は以下に示したTranslateの値に

追加します。

Amplitudeは単純にこのNoiseの値にAmplitudeの値を掛けているだけです。

その他のParameterもこの生成されたNoiseの形状を管理するためのものでした。

NoiseのBoxを閉じたらNetwork Paneに以下のNodeが追加されていました。

新しく追加されたMotionfxノードを開くと以下のような実装がありました。

この辺はどこまで勉強すべきなのか不明なのでTutorialの続きを見る事に戻ります。

Tutorialはこの辺のNodeについては全く触れないで今度はParameter PaneにあるMagnified Glass(虫眼鏡)の使い方を説明しています。

ここでSearch All/HeadingsをClickすると以下のBoxが表示されます。

ここに書かれている色々な設定でSearchが出来るそうです。

試しにTutorialが選んだParameter with Non-Default Valuesを選択します。

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

あれ?

これって先程Noiseで変更したParameterです。

All Parametersに変更したら以下に示した様に

Noiseにあった全部のParameterが表示されました。

これはNetwork PaneのNoise1ノードが選択されていたからみたいです。

これで終わりでした。

先週、分からなかったNoiseの使用方法は理解出来ました。

そんなに簡単では無かったですが、やっぱりHoudiniは他のSoftより少しだけ複雑です。

7.2 Select Objects

TutorialではObjectの選択方法を紹介しています。

Clickして一個だけ選択したりBoxを表示して全部のObjectを選択したりしています。

これって何かする必要がありましたっけ。

そのままClickすれば出来たような。

試してみます。

以下に示した様にTutorialと似た感じにObjectを並べました。

あれ、出来ない。

Coordinateがグルグル回ってしまいました。

CtrlとMouseでもShiftとMouseでもObjectを選択する事が出来ません。

うーん。

分かりました。

Scene Viewの左側にあるToolの中の以下のIconをClickするとObjectを選択出来るようになります。

Object上で左ClickすればそのObjectを選択出来ます。

Object以外の場所で左ClickするとBoxが表示されます。

Tutorialと同じようにObjectを選択する事が出来るようになりました。

いや、これ簡単だと思ったけどかなり大変でした。

Ctrlを押しながら、選択されているObjectを左ClickするとそのObjectは選択から外れます。

Shiftを押しながら、選択されていないObjectを左Clickすると、その前に選択されていたObjectはそのまま選択された状態で、更に新しいObjectを選択した状態にします。

Scene Viewの上部にある以下のIconを選択する事で

以下のように選択する事も可能です。

これBlenderの勉強した時に学んだやつと一緒です。

以下の様に矢印が選択されていない状態でも

Sを押しながらObject上で左ClickするとそのObjectを選択する事が出来ます。

これは前にどこかで勉強したはずです。

もしくは以下のSecure Selection Iconを外します。

これでもObjectを自由に選択する事が出来るようになります。

Aを押すと全部のObjectが選択できるようになります。

試したら確かに全部のObjectを選択しました。

あれ、全部のObjectが写るように画面の位置を変更するんじゃなかったんでしたっけ。

訳分からん。

TutorialではNを押すと全部の選択を外すと言っていますが、これは出来ませんでした。

分かりました。

Scene Viewの左のIconは以下のような選択をする必要があります。

この状態でAを押すと全部のObjectが選択されます。

更にNを押すとその選択されたObjectの選択が全部外されます。

この状態で右Clickすると以下の様なBoxを表示します。

これもTutorialと同じに出来ました。

これで終わりです。

<Select Geometry>

Scene Viewの上のBoxのIconをClickして以下のBoxを開いて

Smooth Wire Shadedを選択します。

すると以下に示した様に

選択しているObjectのGeometryを見る事が出来ます。

更にScene Viewの右端にある以下のIconを選択すると

以下のようなVertexを表示する事が出来ます。

しかしこの状態ではこれらのGeometryを選択する事は出来ません。

いや。

Object LayerからGeometry Layerに移動すれば選択出来るじゃん。と思ったらTutorialも同じ事を言っていました。

そして別な方法でGeometryを選択出来る事を示しました。

まずScene Viewの左端にある以下のIconを右Clickします。

そして以下に示したBoxを表示させ

Pointsを選択します。

そして以下の矢印のIconを選択すると

以下に示した様に

Geometryを選択する事が出来ます。

Edgeも同様に選択する事が出来ます。

選択したEdgeをDouble ClickするとそのEdgeに繋がっている全てのEdgeを選択する事が出来ます。

Tutorialを見ていたらこれをLoopと呼んでいました。

あ、確かにBlenderを勉強した時にLoopと習いました。

今度はScene Viewの上部にある以下のIconを選択して

ObjectのGeometryをClickすると、以下に示した様に

Faceを選択出来るようになります。

ここでAを押すと

以下に示したようなFaceをつなぐLineが現れて、

二つの選択したFaceをつなぐFaceを選択出来るようになります。

今度は以下に示した様な3つのIconを選択しました。

この状態で以下の選択をした場合は

選択した箇所の裏側にあるFaceは

選択されません。

目のIconの選択を外すと

以下に示した様に選択したPolygonの裏側のPolygonも選択されます。

はい。

これも似た機能をBlenderで勉強しました。

UEの機能を覚えているのは当然ですが、Blenderの機能も結構覚えています。

次はScene Viewの上部にある以下のIconを選択します。

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

ここからそれぞれのGroupを選択する事が出来ます。

試しにEyesを選択しました。

次はScene Viewの上部にある以下の以下のIconを選択します。

これはPaint Brushみたいな機能だそうです。

この辺で頭に入らなくなってきました。

もう少しやりたかったですがここらが限界のようです。

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

7.3 今週学んだことで大切な事のまとめ

今週は細かい使い方や機能とは別に一個大きな事を学んだので、忘れないうちにそれをここに書き残しておきます。

それは以下に示したScene Viewの左側に並ぶIconについてですが、

これどれを選択するかによってShort Cutの機能とか全部変化します。

例えば以下に示したCameraが選択された状態で

Aを押すと以下に示した様な

全ての配置されているObjectが見えるような位置にCameraが移動しますが、

以下の矢印のIconが選択された状態でAを押すと

以下に示した様に配置されている全てのObjectを選択するようになります。

このようにScene Viewの左側のIconの選択は今まで習った操作方法の根本を変更する機能を持っています。

8.Volumetric Cloudの勉強

先週、以下に示したPluginにあるVolumetricのMaterial

の一部はDetailやDetail2の値を変更する事で以下に示した様な雲を表示出来る事が分かりました。

今週は他のMaterialも同じようにDetailなどの値をTweakする事で雲が表示出来るのかを確認します。

8.1 ProgrammerとProdigy

このVolumetric Cloudは最終的にはYouTubeのTutorialとして公開する予定です。

それで構成は以下の様に考えています。

  1. 最初の30秒で、Defaultの雲と改良した雲を表示する
  2. 次の2~5分でやり方を示す。
  3. 余談やTipを3分位話す。
  4. 最後にお得情報を1分位話す。

大体8~10分位で一個の動画にしたいと思っています。

この三番目の話題に、今まで前文で書いていたような話も追加していきたいと思っています。

それで前文に必ず書いておきたいと思った話があるのでそれをここに書く事にしました。

このTutorialで教えるのはあくまで私の考える最高のUEの使い方なんで、そこには私の哲学が入っている訳です。

哲学というと分かりにくいので考え方と言う事にします。

私はなにかを学習する事で、最も大切だと思っているのは、基礎力をUpする事です。

これは分かりやすく陸上の練習に例えて説明します。

ある競技に参加するためには100mを11秒で走る能力が必要だとします。

しかし100mを12秒でしか走れない人がいるとします。

この人が100m11秒で走れるようになるためにはどうしたら良いのか?

フォームの矯正、とか練習量を増やす。とか筋トレを始める。など色々あると思います。

この様に足りない部分の補強をするための練習こそが私が考える最高の練習方法なんです。

この私の考え方は全てに一貫していてUEの勉強についても同じです。

UEでProgrammingを組むのに、ProgrammingのSkillが少し足りない人がいる。

その人が普通にProgramを組めるためにはどんな勉強したらいいのか、

とか

どういう教え方したらそういうSkillが足りない人でもProgrammerとして一線で活躍している人達と同じように理解出来るようになるのか。

を最も重要視して作成しています。

これ聞いて、ふーん。立派じゃん。と思う人もいるかもしれませんが、実はProgrammingの分野に関してはそうじゃないんです。

これAlgorithmを勉強した人なら常識ですが、Programmingの世界ではCodeの書き方によって実行速度が1000倍位平気で変わります。

つまり凄いAlgorithmを見つけたら他の人のCodeより千倍位早く動かす事が出来るわけです。

まあこの分野は研究され尽くされているので、1000倍の差が付く事は無いと思いますが、それでも2倍位早くする方法ならそれなりにあると思います。

これをさっきの陸上の話に例えると、人によって走る距離が変わってしまうって事になります。

普通の人は100mを走る必要があるのに、凄いAlgorithmを発見した人は50mを走れば良くなるわけです。

100mを11秒で走るのは結構大変だと思いますが、50mを11秒で走るのはまあ、普通の人なら余裕でしょう。

Programmerの世界ではそれなりにですがこういう誰も思いつかないAlgorithmを見つける天才(Prodigy)がいます。

こういう人には私の勉強方法では絶対勝てません。

しかし私は100mを走らないで50mを走る方法を探す努力は劇薬だと思っているんです。見つかったら大勝利間違いなしですが、見つからなかったらビリになります。

そして凡人にはこれを見つけるのはかなり難しいです。

こういう優れたAlgorithmを見つける人は、元々の性質が普通の人と一寸違うんです。

言い方は悪いんですが、いつもどうやったらサボれるのか。を考えているんです。

いやサボるというのは一寸ニュアンスが違って、成果を得るための最小限の努力をどうやったらもっと少なく出来るのかを考えている。というべきでした。

これ凡人が中途半端に真似すると、単なるサボりになってしまいます。

だから100mを11秒で走る努力をした方が、無難なんです。

少なくとも努力をしますから。

努力ってそれなりに費用対効果が優れていて、これにある程度は頼る癖は付けておいた方が得なんです。

また優れたAlgorithmを見つけたとしてもそれを貫くのもかなり難しいです。

50m走ればすむ方法を見つけたとしても、周りからズルいとか言われて、結局100m走らされる羽目になったりします。

前もって文句を言われるかもしれないから、100m11秒で走れるようにもしておくか。と考える人は結果150m走る事になったりします。

ここで50m走れば十分であるAlgorithmを見つけたとしても、文句言ってくる連中全員と戦うのは大変です。

そういう訳で、私のTutorialはBestじゃないけどBetterを目的にしてやっていきます。

8.2 PluginにあるVolumetricのMaterialのParameterを弄って雲を表示させる

<M_Sky_CustomNode_Prototype>

これは何をしても動かないです。

以下に示した様にCodeが繋がっていません。

<M_VolumetricCloud_01_FalloffFunction>

MIを作成して以下に示した様にDetailの値を変更すると

以下に示した様な雲が現れました。

<M_VolumetricCloud_02_Profiles_PaintClouds>

これは何にもしなくても雲が現れるやつです。

以下の雲が現れました。

この雲はあんまりかっこよくないですね。

<M_VolumetricCloud_02_Profiles_PaintClouds_Morning>

MIを作成してDetailの値を変更しました。

この雲はTilingが目立ちすぎです。

他のParameterを弄ったらもっと良くなるんでしょうか?

<M_VolumetricCloud_02_Profiles_PaintClouds_Small>

MIを作成してDetailの値を変更しました。

この雲は綺麗な形状です。

このまま使用出来ます。

<M_VolumetricCloud_02_Profiles_Soft>

MIを作成してDetailの値を変更しました。

雲は現れませんでした。

次にDetail2の値を変更しました。

これもきれいな雲です。

<M_VolumetricCloud_03_MultipleProfiles>

ここからM_VolumetricCloud_03になります。

DetailやDetail2の値を弄ったんですが雲は生成されませんでした。

Materialの実装を見て考えたんですがよく分かりません。

ここで一寸分からなくなりました。

このM_VolumetricCloud_03は全部使用方法がよく分かりません。

一端ここで中止とします。

予定が大幅に狂ってしまいました。

とりあえず今週はここでVolumetric Cloudの勉強は終わりにします。

9.DirectXの勉強

9.1 C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [5]のFormatting Our Codeの勉強

まず軽く全部見ます。

見ました。

簡単にこの節のまとめると、

このままCodeを継ぎ足していくと、後で訳分からなくなってしまうので、Helper Method(C++だからHelper Function?)を作成してCodeを整理しておきましょう。

という事です。

ここで初めて知ったんですが、pragma regionの使い方です。

これって自動で作成されるもんだとずっと思っていました。

公式のDocumentであるregion and endregion pragma [17]も一応読んでおきました。

前にC++でCodeを書いていた時は、あんまりMicrosoft Learningは利用しなかったんですが、これかなり分かりやすく書いてあります。これからはちょくちょく利用する事にします。

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

以下の様にGobal Variablesの箇所をComment outします。

Tutorialではこれは必要だけど結果的にBulkyだと言っています。

Bulkyってどういう意味だったけ?

調べてたら大きくて場所を取る事を言うそうです。

Largeとどう違うんでしょう。

  • being large in size, mass

と書かれていました。

つまりサイズや重さに限定して大きい(Large)事をBulkyと言うみたいです。

まあそれはともかくとしてBulkyなので以下に示した様にRigonを追加します。

以下に示した様に元々、WinMain()関数内のCodeを役割によって分けてあります。

これらを別のFunctionにします。

以下に示した様にInitializeVariables()関数を作成し

WinMain()関数内のInitialize Global VariablesのCodeを移します。

当然、WinMain()関数内には作成したInitializeVariable()関数を追加します。

Tutorialはこの後、Testして同じように動くのか確認しています。

そして抜き出したFunctionは以下に示した様にComment outします。

そしてこれらのFunctionは見栄えを良くするためと可読性を上げるためにWinMain()関数の後に並べる事にします。

そしてPredefined FunctionをWinMain()関数の前に作成します。

次のCreate Window Classの部分もFunctionにします。

Create WindowClass()関数をPre-Declarationsに追加します。

最終的には以下のような関数が出来ます。

最後に以下に示したDeclarationを追加します。

以上でした。

9.2  C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [5]のFormatting Our Codeの実装

それでは実装します。

まず以下のGlobal VariableをCommentでまとめます。

更に#Pragma Regionを追加します。

それで色々なSiteを見たんですが以下の様に書いた方が良い気がします。

ここはGlobal Variableを集めた箇所でFunctionでは無いですが、Summaryで解説した方が分かりやすいです。

後、SummaryをPragma Regionの内側に入れた方が見易い気がします。

これで行きます。

まずInitializeVariable()関数を作成しました。

実装部はWinMain()関数の/* Initialize Global Variables */の部分です。

TutorialみたらFunctionという括りで分けていました。

あ、そういう事か。

さっきのGlobal Variableもそういう括りだったみたいです。

じゃ直します。

以下の様に直しました。

まずGlobal Variablesです。

Pre-Declarationsです。

ここにFunctionの宣言を追加します。

今は何もないです。

ここにはFunctionの実装を書きます。

次にOperationです。

ここはWinMain()関数が来ます。

今度はPragma Regionなどを追加します。

Pre-Declarationsです。

FunctionであるInitialize Variables()関数とWindowProcess()関数の宣言をここに書きました。

Operationです。

WinMain()関数を含みました。

TutorialではWindowProcess()関数の実装もここに含まれています。

でもWindowProcess()関数は単なるFunctionです。

WindowProcess()関数の実装はFunctionsの所に配置します。

以下にFunctionsを示します。

で、関数なんでSummaryも追加しておきます。

こんな感じでSummaryを仕上げました。

ReturnするTypeは書き込む箇所がないみたいです。

WinMain()関数内にある他の実装も関数化します。

Create Window ClassにあるCodeを関数化しました。

名前はCreateWindowClass()です。

Pre-Declarationsに関数名を追加します。

更に実装も追加します。

実行してきちんと動くか確認します。

Errorになってしまいました。

何で?

確認しましたが全部あっている気がします。

問題がどれなのか分かりません。

うーん。

Rebuildしました。

直りました。

普通に実行出来るようになりました。

そういや全部あっているはずなのに動かないときはまずRebuildするってC++でCode書いている時は常識でした。

Summaryも追加しておきます。

次はCreate and Display our Window Classの実装を関数化します。

関数の名前はInitialize Window()です。

Pre-DeclarationsにInitialize Window()を追加します。

FunctionsにInitialize Window()の実装を追加します。

Return 0がErrorになっています。

この関数のReturn ValueはVoidなので無しでなければなりません。

Return 0を外しました。

確認のためにSample codeを見たらPostQuitMessage(0)が追加されていました。

同じようにしました。

Summaryも追加しました。

最後にListen for Message Eventsの実装を変更しました。

名前はMessageLoop()です。

Pre-Declarationsに追加しました。

Functionsに実装を追加しました。

Summaryも追加しました。

テストします。

普通にWindowを表示しました。

WinMain()を整理します。

これで完成です。

9.3「DirectX 12の魔導書」の3.3.2 DirectX D12の初期化の続きを勉強します

先週はD3D12CreateDevice()関数のParameterについて勉強しました。

D3D12CreateDevice()関数そのものについても「Direct3D 12 ゲームグラフィック実践ガイド」の「2.3 Direct X 12の初期化処理」でかなり理解が進みました。

先週の続きから勉強します。

D3D12CreateDevice()関数の2番目のParameterにセットするLevelの設定方法について解説しています。

これ先週読んだ時は、訳分からなかったんですが、今は理解しました。

このCodeを実行するHardがどのLevelのDireceXを使用出来るのか分からない訳です。

じゃあどうするかと言うと、普通ならどんな古いHardでも動くように一番古いLevelをセットします。

しかしそれではDirectXの綺麗な映像が見られる最新のHardを使用している人が損してしまいます。

そこでこの本では最新のHardを使用している人も古いHardを使用している人も誰もが損しない方法を編み出したんです。

その方法とは以下のArrayを作成して

以下に示した様に最新のLevelから順に試していきます。

ダメだったらその下のLevelを試す。という方法を採用しています。

はい。

これでD3D12CreateDevice()関数の2番目と3番目のParameterの設定方法は分かりました。肝心の一番目の設定方法が分かりません。

教科書の続きを読みます。

一番目のParameterの取得方法が書かれていました。

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

Nullptrを使用した場合、Video Cardが複数ある場合どのVideo Cardが選択されるのか不明になります。のでここでは選択すべきVideo Cardが指定出来る方法を使用します。

段々、この本の著者の本気が出て来ているのを感じます。

こんなの他の教科書と同じようにnullptrで妥協しても良いはずなのに、逆に全力で最適解を探しに来ています。

しかもその後で、実際にはnullptrを使用した方が良い場合もあります。と謙虚さも忘れていません。

中々熱い本です。

ではそのやり方を勉強する事にします。

大体理解しました。

まず使用出来る全部のVideo Cardの名前を得る必要があります。

それを得る機能を持っているObjectをまず作成します。

使用出来る全部のVideo Cardの名前を得る機能を持っているObjectは以下に示した

IDXGIFactory6型のObjectです。

Sample Codeでは名前は_dxgiFactoryになっていました。

更にSample Codeでは宣言と同時にnullptrを使用していました。

初期化する前の無用なErrorを避けるためでしょうね。

このObjectをCreateDXGIFactory1()関数を使用して初期化します。

と教科書には書いていますが、Sample Codeでは以下に示した様にCreateDXGIFactory2()関数を使用していました。

しかも初期化の仕方も教科書とは少し違っている気がします。

まあ良いです。

これでIDXGIFactory6型のObjectである_dxgiFactoryが初期化されました。

今度は_dxgiFactoryにあるMember functionの機能を使用してこのHardで使用出来る全部のVideo Cardの名前を取り出します。

あ、その前に取り出したVideo Cardの名前を保持するための変数を作成します。

取り出したVideo Cardの名前を保持するVariableはTypeはIDXGIAdapterで名前はtmpAdapterになっていました。

更にVideo Cardの名前が複数出て来る事が予測されるので、IDXGIAdapter型のArrayも作成しています。名前はAdaptorsになっていました。

これらの変数を使用して以下の実装でこのHardで使用出来る全部のVideo Cardの名前を取り出しています。

この実装を見ると

このHardで使用出来るVideo Cardの名前を取り出す機能を持った_dxgiFactoryにあるMember functionはEnumAdapters()のようです。

この次の実装が何をやっているのか不明だったんですが、教科書を読み直したら分かりました。

ここでIDXGIAdapter型の変数に保持されているのはVideo cardの名前じゃなくてVideo Cardの名前の情報も入っているEnumを持つObjectでした。

だからこのObjectからまずVideo Cardの名前の情報も入っているEnumを取り出し、更にそのEnumからVideo Cardの名前を取り出します。

Sample Codeの実装です。

まずDXGI_ADAPTER_DESC型のEnumを作成します。

名前はadescになっていました。

Adaptersに入っているIDXGIAdapter型の変数を一個取り出し、そこからGetDesc()関数を使用してadescにDataを移します。

次のadesc.DescriptionでVideo Cardの名前を抜き出します。

もしその名前にNIVIDAが有ったらそのIDXGIAdapter型の変数をtmpAdaptorに保持します。

はい。

大体、この解釈であっているでしょう。

それで最初の以下のD3D12CreateDevice()の実装に戻ります。

一番目のArgumentには先程、NIVIDAが有ったIDXGIAdapter型の変数を保持したtmpAdaptorがセットされています。

ふう。

これでD3D12CreateDevice()関数の実装方法を一応理解しました。

実際の実装は来週やります。

9.4 HLSLシェーダーの魔導書を勉強する

先週は以下のErrorが表示されたので途中で止めてしまいました。

Sample CodeのSample02_02は正常に実行出来るので、私のPCにこのDllが入っていないという事は絶対にないです。

でもどう直せば良いのかが分かりません。

Sample Codeを色々見てみます。

Sample.after_1.fxを見ると

この教科書の改造がすでに終わった状態のCodeが書かれています。

これを代わりに実行してみます。

あれ、普通に出来ました。

もう一回、Sample.fxに実装を書き込んで試してみます。

実行します。

あれ?

普通に出来た。

うーん。

先週のErrorは一体何だったんでしょう。

Visual Studioを再起動したら直ったんでしょうか?

まあ、良いです。

一応出来たのでCodeを読んで考える事にします。

まずは以下に示した2つの関数からです。

VSMain()関数はOpenGLにおけるVertex Shaderと同じでしょう。

そしてPSMain()関数はOpenGLにおけるFragment Shaderなはずです。DirectXなのでPixel Shaderと呼ばれています。

次にそれぞれの関数のParameterですが、

このShader Fileで生成されたStructが使用されています。

うーん。もうGLSLではどうやったのか忘れてしまいました。

こういう風にParameterをPassするのか。

更にPSMain()関数のReturn Valueは以下の様になっています。

うーん。

これ何を返しているの?

ここに説明されていました。

結局頂点情報を返しているだけでした。

Pixel Shaderの方はPixelの情報を返しているだけですね。

こっちはすぐに分かりました。

試しに黄色くしてみました。

なっています。

今週はSample Codeを改造しても動く事が確認出来たのでこれでOKとします。

後は、教科書を一寸だけ読んで終わりにします。

教科書読んでいたら以下の表記についての解説がありました。

これ、Codeを見た時、何これ?と思ったんですが忘れていました。

これはSemanticと呼ばれていて、このDataの使われ方を説明するものだそうです。

上の例だとposのDataはPositionに使用されると説明している訳です。

この後のPOSITIONの解説は非常に分かりやすいです。

でもここは重要そうなので来週、もう一回勉強する事にして今週の勉強はここまでにします。

9.5「Direct3D 12 ゲームグラフィック実践ガイド」の「2.3 Direct X 12の初期化処理」を勉強します

今週は、先週やらなかった以下の変数を打ち込む事をしましょう。

結局、これらの変数を初期化するためにID3D12DeviceをD3D12CreateDevice()関数で初期化する訳でしょう。

それぞれの変数を一寸見ておくのは損にはならないでしょう。

これはD3D12CreateDevice()関数で初期化するObjectです。これからこのObjectを使用してDirectXを使用するのに必要な他のObjectを生成するのに使用するはずです。

Command Queueです。

Command Queueって何をする変数でしたっけ。

Blogを見直したら2022-11-06のBlogで勉強していました。

この教科書の丸コピーですが、以下の様にまとめていました。

そして以下の図を見てやっとCommand Queueを理解したんでした。

成程、思い出しました。

この時はまだ概念としてしか理解していませんでしたが、この章でこれを実装する事になるみたいですね。

中々感慨深いです。

IDGISwapChainです。

SwapChain自体は、「DirectX 12の魔導書」でも「3.2.2 Direct3Dの初期化」で宣言しています。

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

Blogも見直しましたが、この変数はまだ何も勉強していません。

これからどんな変数なのか判明する事でしょう。

次に行きます。

これも何の情報もないな。と思ったら解説にColor Bufferと書いてありました。

FrameCountがどこにも宣言されてなくてErrorになったので、Sample Codeから

をコピペしました。

Command Allocatorです。

これも何をするObjectなのか不明です。

公式のDocumentのID3D12CommandAllocator interface (d3d12.h) [18]を見てみます。

以下の解説が書かれていました。

うーん。

分からん。

Command AllocatorってCommand Queueをどうするの?

その辺の関連性が分からないとこの説明の意味もあんまりピンと来ません。

この説明で唯一理解出来たのはDirectX 12ではCommand Allocatorを絶対使用しないといけない事だけです。

Command Listです。

来たぁ!

やっとCommand Listに出会えました。

これが描画Commandを集めてCommand Queueに送るObjectです。

Descriptor Heapです。

こんなの勉強したかな?

と確認したら2022-11-06のBlogでしっかり勉強していました。

これか。

餃子定食のお盆に当たるObjectか。

この「Direct3D 12 ゲームグラフィック実践ガイド」にはDescriptor Heapの解説は載ってなかったって書いています。

一応確認します。

検索した限りでは何の説明のないみたいです。

Fenceです。

2022-11-06のBlogには以下の解説がありました。

これも実際に使用するようになったら理解出来るでしょう。

次の2つの変数はFenceに関連した変数でしょうね。

文字通りFrameの番号だそうです。

FrameってFrame/SecのFrameの事?

これも後になったら判明するでしょう。

CPUのDescriptorだそうです。

流石に頭が回らなくなって来ました。

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

まあそれなりには勉強出来ました。

10.まとめと感想

今週は一寸風邪気味だったので抑えて勉強しました。

それでも最終的にはそれなりの量になりました。

11.参照(Reference)

[1] CGHOW. (2022b, December 27). Sprite Based Animated Butterflies in UE 5.1 Niagara Tutorial | Download Files [Video]. YouTube. https://www.youtube.com/watch?v=U1uLVV979xE

[2] Ben Cloward. (2022, October 20). Snowy Rock Shader - Advanced Materials - Episode 4 [Video]. YouTube. https://www.youtube.com/watch?v=UHUJJ_nE5dQ

[3] Andrea Cantelli. (2020d, June 2). Gaea Tutorial for Beginners #5 | Creating the shape of our first terrain. YouTube. https://www.youtube.com/watch?v=swAL_i4jPO4

[4] Magee, R. (n.d.). Foundations | Overview | SideFX. https://www.sidefx.com/tutorials/foundations-overview/

[5] OlympusMonsTutorials. (2021, March 3). C++ DirectX 12 Game Engine - [S01E02] - Refining Our Window [Video]. YouTube. https://www.youtube.com/watch?v=rWylZKi8QbM

[6] Poliigon Documentation. (2018, October 16). Using Poliigon displacement textures in Unreal Engine 4 [Video]. YouTube. https://www.youtube.com/watch?v=1GkS9-94k80

[7] T. (2021b, November 7). Where is the “Tessellation” options in Ue5 Materials. Epic Developer Community Forums. https://forums.unrealengine.com/t/where-is-the-tessellation-options-in-ue5-materials/259689/1

[8] Peyton Varney. (2022, March 21). Material Displacement in Unreal Engine 5. YouTube. https://www.youtube.com/watch?v=4YcWDpXCNi4

[9] Quixel. (2022, June 1). Displacing Geometry: Creating ‘Ninety Days’ in Unreal Engine 5 [Video]. YouTube. https://www.youtube.com/watch?v=j-qXa-0fIxA

[10] Unreal Sensei. (2020b, August 9). The Secret to Realistic Landscapes in Unreal Engine - UE4 Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=UIycCZl4lYE

[11] Unreal Sensei. (2020b, August 7). How to INSTANTLY TEXTURE your landscapes in UE4 - Unreal Engine tutorial [Video]. YouTube. https://www.youtube.com/watch?v=mP8eHwVEA0o

[12] Niagara Renderers. (n.d.). https://docs.unrealengine.com/5.1/en-US/render-module-reference-for-niagara-effects-in-unreal-engine/

[13] CGHOW. (2021, July 23). Sprite Rotation Sprite Alignment Sprite Facing | UE5 Niagara Tutorial | Download Project File. YouTube. https://www.youtube.com/watch?v=EIP6mg8V5YU

[14] Ben Cloward. (2022b, October 20). Snowy Rock Shader - Advanced Materials - Episode 4 [Video]. YouTube. https://www.youtube.com/watch?v=UHUJJ_nE5dQ

[15] erosion | National Geographic Society. (n.d.). https://education.nationalgeographic.org/resource/erosion/

[16] Weathering | National Geographic Society. (n.d.). https://education.nationalgeographic.org/resource/weathering/

[17] C. (2021a, August 3). region and endregion pragma. Microsoft Learn. https://learn.microsoft.com/en-us/cpp/preprocessor/region-endregion?view=msvc-170

[18] S. (2021c, July 22). ID3D12CommandAllocator (d3d12.h) - Win32 apps. Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nn-d3d12-id3d12commandallocator