UE4の勉強記録

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

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する。アニメレンダリングの勉強など 7

<前文>

今週のDirectXの勉強

今週は「DirectX 12の魔導書」の2章、「グラフィックスパイプラインとさまざまなシェーダー」を読んで勉強します。

「HLSLシェーダーの魔導書」と「Direct3D 12 ゲームグラフィック実践ガイド」は「グラフィックスパイプラインとさまざまなシェーダー」の内容に関連している部分をPickupして読む事にします。

<「DirectX 12の魔導書」の2章、「グラフィックスパイプラインとさまざまなシェーダー」を読む>

この章はPipelineについての簡単なまとめとHLSLについての簡単な説明で構成されていました。

<<Pipelineについて>>

Input Assembler -> Vertex Shader -> Pixel Shader -> Output-Merger

だけ理解しておけば、大体問題ない気がしています。

と言うか、私がここで確認したいのはVertex ShaderのどのDataをRasterizationするのかだけです。

2022-10-31のBlogにも書きましたが、Viewport変換した後でRasterizationする場合、奥行きのDataはどうやってPixel Shaderに送っているのかが分かりません。それを確認する必要があります。

この本でもVertex Shaderの説明の処で「2D なのにZ方向がある理由」というTipがありました。

この辺の話が後で重要になってくると思っています。

Output-Mergerの説明で、この部分でどのRasterizeされたDataを使用するのかを判断する。と書かれています。

この辺も奥行のDataを使用する箇所なので重要になってくるでしょう。

後、正規化されたNormal VectorをRasterizationした場合、それぞれのNormal VectorはLerpで計算されるはずです。そのそれぞれのLerpで生成されたNormal Vectorって正規化されているんでしょうか?Pixel Shaderでもう一家正規化する必要があるんじゃないでしょうか?

これも確認したい事項の一つです。

<<HLSLについて>>

結構、細かい点ですが個人的に重要な話だと感じた所が色々ありました。

まずShader言語はScript言語と違い、上から一行毎に順に実行されるのではない。と言う事です。

これって何となく当たり前に感じていましたが、改めて言語化されると結構大事だと感じました。

後、重要だと思ったのは行列の指定ですが「Name._11とName._m00が同じ要素を指している。」事です。

これ最初は、何が言いたのか良く理解出来ませんでした。

要するにMatrixの要素を1から数えるのか0から数えるのか。の違いでした。でもこれしっかりと覚えていないとCodeを書くときに間違そうです。

セマンティクスはsemanticsの事だと思います。

Semanticについて私が知っているのはSemantic Errorだけです。Semantic Errorは、理論が間違っている時に起きるErrorです。

この本では、DataをGPUに渡す時にどういう目的で渡すのかを記す事をセマンティクスと呼んでいました。

これって先週勉強したBarrierの事でしょうか?

Positionの行列が、3x3ではなく4x4で表されている事、wの値が1である事について一寸だけ述べていました。

これ昔、Blogの何処かで教授から「PositionとVectorで0と1を分けている。」って聞いたと書いたんですが、調べたら間違っていました。

Stack OverflowのIn OpenGL vertex shaders, what is w, and why do I divide by it? [1] に書かれていましたが、

Wが1である事で正規化されている事を示しているそうです。

Pixel Shaderの解説で奥行きのDataをどうやって活用しているのか理解しようとしたんですが、この部分の説明が今一理解出来ませんでした。これは実装する時に勉強し直します。

<HLSLシェーダーの魔導書>

<<Pipelineについて>>

ここでもVertex Shader Stageでスクリーン座標系まで変換すると書いています。

このVertex Shaderにおける座標変換はProgramableであるのに、何で一様に同じ実装をしなくてはいけないのか?と言う疑問についての回答がありました。

この疑問、私もOpenGLを勉強した時に感じたんですが、質問したらバカにされるかもしれないと思って黙っていたのを思い出しました。

<<HLSLについて>>

この本はShaderの説明で直ぐに三角形の作成になっています。

今週はまだ実際のCodeを書く予定じゃないので、ここまでにしておきます。

Direct3D 12 ゲームグラフィック実践ガイド>

この本も特に付け加える話はないです。もう実装の説明になっています。

DirectX 12の今週の勉強は以上になります。

来週の予定

3つの本、それぞれに書いてある概論的な説明の勉強は大体は終わりました。

来週はSample CodeをDownloadして実際にProgrammingを書いてみます。

それではUEの勉強を始めます。

<本文>

1.今週の勉強について

今週も以下の内容についてやって行きます。

  • Niagara: CGHOW氏のTutorialをやる
  • Materialの勉強
  • RPGPackagingについて
  • Open Worldの検証
  • Gaeaの勉強
  • 雪山のMapの作成
  • 報酬システムの研究
  • Anime Renderingの勉強
  • DirectX 12の勉強

2.Niagara: CGHOW氏のTutorialをやる

今週は、CGHOW氏のChocolate Flip Fluid in UE5 Niagara Tutorial | Download Files [2]を勉強します。

2.1 Chocolate Flip Fluid in UE5 Niagara Tutorial | Download Files [2]を見る

全部を軽く見ました。

Drag Moduleを使用しています。

先週、renderBucket氏のTutorialで教わった内容の一つに「VelocityはGrid 3D FLIP Integrated Particle Velocity Moduleで計算しているので、Errorが表示されてもFixを押してSolve Source and Velocity Moduleを追加してはいけません。」があります。

これをやっているように見えます。

Drag ModuleだってVelocityの値に影響しているはずです。

これは要確認する必要がありそうです。

実際、このFXの結果を見ると液体が地面から漏れて消えています。

この結果は、先週のBlogでまとめた様に、renderBucket氏のTutorialで指摘されているFixを押してSolve Source and Velocity Moduleを追加した結果と同じに見えます。

マジか!

CGHOW氏も間違える事があるんですね。

これは、renderBucket氏、Good Jobでしょう。

以下に全体のまとめを簡潔にします。

まずViscosityのParameterが無いのでDragで代用してねっとり感を出した。と述べています。

うーん。

成程。

当然ですがNiagara FluidsのPlug-inをEnableする必要があります。

NSを作成します。

Templateは以下に赤線で囲ったNew system from a template or behavior exampleから選びます。

Grid 3D FLIP Hoseを選択しました。

以下のEffectです。

まず、Waterが貯まらないようにします。

System StackのUser Parameter Moduleを選択して

Water Heightの値を0にします。

後、正式な名称が見つかるまでこのSystemやEmitterの塊をStackと呼ぶことにします。

先週の調査ではStacksと呼んでいる例を見つけています。

この英文を読み直したんですが、StacksはSystemとかEmitterのStackが複数あるからStacksとなっていると読めます。

ので以下の塊はこれからはSystem StackとかEmitter Stackと呼びます。

結果です。

うーん。

この時点で、水の高さが0になっているのか。

これやってるように見えたんですが、違うかもしれませんね。

次に横の壁も無くします。

Emitter StackのGrid3D_FLIP_FluidControl_EmitterのEmitter Summaryの

以下のParameterをenableにします。

ここでDownはOffのままです。

やっぱりFixを押してSolve Source and Velocity Moduleを追加した結果、底に水が溜まらなくなってしまった。みたいですね。

Foamを作成するEmitter stackは要らないので消します。

今度はBoundを表示させます。

System StackのUser Parametersを選択して

Show Bounds をEnableにします。

ついでにBoundsのサイズも変更します。

結果です。

今度はParticleの発生位置を調整します。

Emitter StackであるGrid3D_FLIP_FluidControl_EmitterのParticle Spawn SectionにあるSphere Locationの

Sphere Radiusのサイズを20にします。

水が勢いよく飛び出す必要はないので以下の調節を行います。

Particle Spawn SectionのSet:[PARTICLE] Velocityを選択して

Xの値を0にします。

結果です。

Particleが下に落ちるようになりました。

今度は、水の落ちる位置を時間と共に変化させる実装を組みます。

またParticle Spawn SectionのSphere Location Moduleを選択します。

OffsetにMake Vectorをセットします。

Zの値に300をセットします。

これは元々のZの値が300だったからです。

次にXにSineをセットします。

そしてScaleに200をセットします。

結果です。

Screenshotでは良く分かりませんが、水の生成場所が赤の矢印が示した様に左右に動いています。

正し凄い速く動いています。

水の生成場所の移動速度を適切にするために、SineのPeriodの値を10にしました。

結果です。

今度はゆっくり過ぎて生成された水が全くうねりません。

でもTutorialでは、これが適切な速度だったみたいで、今度はYの値を調整しています。

YにXの値をPasteしました。

更にScaleを50に変更しました。

結果です。

うーん。

あんまり違いはない気がします。

今度は水の質感を変更させて粘りを出すそうです。

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

遂に問題の箇所が来ました。

Errorが表示されています。

Fix押してる!!!

しっかりとSolve Forces and Velocity Moduleが追加されています。

あああ。

まあ、一個間違えたからと言ってCGHOW氏の今までの業績が駄目になる訳ではないですが、この人のTutorialを見てれば全部OKと言う訳にはいかない事も判明しました。

しかしrenderBucket氏のTutorialの評価は逆にうなぎ登りですね。

先週は、結構renderBucket氏のTutorialを批判していましたが、これは考えを改める必要がありますね。

うーん。

RenderBucket氏もUE5を製作している人達にかなり近い人からUEの使用方法を直接、教わっている感じがします。

これSmartpoly氏やUnreal Sensei氏のTutorialを見た時もそんな感じがしました。

Drag の値を変更します。

結果です。

これ見る限りはあんまり変わっている感じはしません。

今度は液体に色を付けます。

Render SectionのMesh Renderer Moduleを開きます。

Override MaterialにセットされているMaterial Instanceです。

このMaterial InstanceをDuplicateします。

DuplicateしたMaterial Instanceを代わりにセットして、更に値を変更します。

まずOpacityの値を1にします。

次にBase Colorを茶色にします。

結果です。

もうこれ、うんこにしか見えません。

今度はCollisionを追加します。

まずStatic Meshを追加します。Sphere を追加しました。

Collisionを追加するために、このSphereのTagにColliderを追加します。

ここでCGHOW氏のUE EditorがCrashしたので、SphereのDataが消えてしまいました。

のでUE Editorを再起動してCylinderを追加しました。

このCylinderに回転運動を追加します。

CylinderにRotating Movementを追加します。

Rotation Rateの値を以下に示した値にします。

Cylinderが回転しています。

この後、CGHOW氏は床をChocolateまみれにする為にParticleのLifeをInfiniteにしようとしたが、出来なかったと言っています。

以上です。

2.2 Chocolate Flip Fluid in UE5 Niagara Tutorial | Download Files [2]を実装する

特にCommentもないですし、実装をしてみます。

その後で、Drag ModuleのErrorを正しい方法で直した場合、床にChocolateが貯まるのかどうかを確認します。

そんだけです。

NSを作成します。

まず水がたまらない様にします。

System StackのUser Parameterを選択して

Water Heightを0にしました。

これを0にしたら、Drag ModuleのErrorを正しく直しても、Chocolateは床にたまらないんじゃないのか?と思っています。

後で検証します。

とりあえず今は0にしておきます。

結果です。

うーん。

Water Heightって何を計算するんでしたっけ?

Boundも外します。

Emitter StackのGrid3D_FLIP_FluidControl_EmitterのEmitter Summaryを選択して

BoundaryのCheckを以下の様にします。

結果です。

やっぱり床に何も溜まっていません。

まあ、いいです。先に進みます。

Second Emitterを消しました。

今度はBoundaryを表示します。

System StackのUser Parameterを選択します。

Show BoundsをEnableして、

World Grid Extents の X の値を600にします。

結果です。

うーん。

Zが大きすぎな気がします。

今度はParticleが生成される場所を小さくします。

Emitter StackのParticle Spawn SectionのSphere Location Moduleを選択して

Sphere Radiusを20にします。

結果です。

お。

床に水が流れています。

今度はVelocityを変更します。

0にしました。

結果です。

ここで先程から気になっていたSystem StackのUser Parameter にあるWater  Heightの値を50にしてみました。

結果です。

最初の水面の高さが50㎝になっているみたいです。

横のBoundaryを全部開けているのですぐに溜まっている水はなくなってしまいました。

今度は水の生成される場所を動かします。

Sphere LocationのOffsetの設定を以下の様にしました。

結果です。

Gifを撮ると重くなるので取りませんが、結構綺麗に動いています。

次です。

Drag Moduleを追加しました。

ただし追加した方法は先週、RenderBucket氏のTutorialで説明されたやり方で追加しています。

結果です。

床の水は、横に流れていってから消えています。

CGHOW氏の水は床に触れたとたんに消えています。

ここは間違っていますね。

ただ水の動きが違いますね。

この辺はTutorialを最後までやってから調整します。

今度は色を変えます。

Effect StackのRender SectionのMesh Rendererに使用されているMaterial InstanceをCopyして

以下の値を変更します。

結果です。

成程。

Chocolateなら床にねっとりとくっつくはずなのにサラサラ流れてしまっています。

この辺が流体の計算ではなく水の計算になってしまっているんですね。

この後、Sphereを追加してCollisionを再現しようとしたらCollisionしません。

勿論、SphereのTagにはColliderを追加しています。

分かりました。

ActorのTagに入れる必要がありました。

結果です。

出来ています。

これでViscosityを計算出来たら完璧なのですが。

Chocolateが凄くサラサラしています。

最後にNiagara Fluidとは関係ないですが、このCylinderを回転させる実装を追加します。

CylinderにRotating Movementを追加して

Rotation Rateのxの値を100にします。

結果です。

Cylinderが回転しました。

2.3 Particleの数を増やしてみる

せっかく、新しいPCを買ったので、Particleの数を増やして限界に挑戦してみます。

まずRender SectionのMesh Rendererを切ってSprite Rendererに変更しました。

結果です。

Emitter Update SectionのSpawn Rate 001 Moduleを選択し

Spawn Rateの値を10000から20000に変更します。

結果です。

楽勝でした。

今度は50000にしてみました。

全く問題ないみたいです。

PCは普段と同じ静かさを保っています。

よく考えたらGPUがどれくらい活動しているのかを測定する方法を知らなかったです。

いきなり限界突破したら嫌なので、GPUの限界を試すのは中止します。

2.4 Niagara Fluid SimulationではGrid 3D FLIP Integrated Particle Velocity Moduleを使用してSolve Source and Velocity Moduleは使用してはいけない件について

Render Bucket氏が先週のTutorialでNiagara Fluid SimulationではVelocity関連のModuleを扱った時はSolve Source and Velocity Modulを使用しないでGrid 3D FLIP Integrated Particle Velocity Moduleする。と述べていました。

この事実をCGHOW氏ほどのNiagaraのExportが知らなかった件について考察する必要があります。

これはSmartPoly氏やUnreal Sensei氏のTutorialを勉強した時にも感じたんですが、彼らは何か別な教材で勉強していた感があります。

その別な教材がどうもUEを作成した人達が作った教材の様なんです。

つまり彼らはUEでGameを製作するに当たってUEを作成した人達が考える正しいやり方を最初から教わっているんです。

これは是々非々で、UEを制作した人達が考える正しいGameの作り方が必ず、全てのGame製作者にとって正しいとは限りませんし、また例えそれが正しくてもそれに従う必要もありません。

正し、今回の場合のようにNiagaraでFluid Simulationを行う場合、Solve Source and Velocity Modulを使用しないでGrid 3D FLIP Integrated Particle Velocity Moduleする。という場合は、そう言うのはないです。絶対にこのやり方でやる必要があります。

つまりCGHOW氏のやり方は間違っています。

それはこのTutorialでCGHOW氏自身も気が付いており、何故床にChocolateが溜まらないのか分からない。今回はこのBugの原因が分からないから次のTutorialまでにその原因を解明します。と言っています。

恐らく、CGHOW氏の方がNiagara自体の見識はRender Bucket氏よりも深いし、更にNiagaraの勉強に費やした時間も多いはずです。

しかし、今回の件に関して正しいのはRender Bucket氏の方です。

何故、Render Bucket氏やSmartPoly氏やUnreal Sensei氏はそういう特別な教材で勉強する事が出来たんでしょうか?

彼らはEpic Game社の開発陣と特別なコネがあってそういう人達のために特別な教育システムが秘密に開発されていたりするんでしょうか?

ここからは本題なんですが、彼らは多分、映画のVFXを勉強したんだと思うんです。

UEを使用して映画用のVFXの作成方法を勉強したんだと思います。

だから、GameのTutorialと少し違う内容を知っているんです。

そしてここが大切な所ですが、UE5を使って、映画のVFXを作成するためのTutorialは、UE5を使ってGameを作成するためのTutorialより格段に優れているみたいです。

それが今回の「Velocity関連のModuleを扱った時はSolve Source and Velocity Modulを使用しないでGrid 3D FLIP Integrated Particle Velocity Moduleする。」という大切な情報を知る事が出来たかどうかの違いを生んだと思われます。

これからはUEで作成する映像のためのTutorialも積極的に見る様にしようと思います。

2.5 NiagaraのFluid SimulationでViscosityを変化させる事は出来るのか?

今回のChocolateのSimulationはCylinderに垂れた時、サラサラに流れるので、全くChocolateに見えません。

CGHOW氏もViscosityを変化させるParameterが見つからないので、代わりにDrag Moduleを使用して疑似的に粘りを表現しています。

NiagaraのFluid Simulationに粘りを表現する機能があるのかどうか、調べる簡単な方向を思い付きました。

それはExample ContentsのNiagara Fluid Simulationに粘りを変化した機能が紹介されているかどうかを見る事です。

もし粘りを変化させる事が出来るならこれは凄いAppealに成る訳で、Example Contents内で紹介されない訳ないです。

見てみます。

無かったです。

と言う事は、少なくとも標準の機能を使う限り、ハチミツみたいな粘りのあるFluid Simulationはまだ出来ない。と考えて良いでしょう。

3.Materialの勉強

今週もNoise ノードについて勉強していきます。

調べたらBen Cloward先生のPerlin Noiseに関するTutorialは以下の4つが有る事が分かりました。

これを勉強します。

その後で、先週述べた

についても検証する事にします。

3.1 Snowy Tree Trunk Shader - UE4 Materials 101 - Episode 20 [3] を勉強する

今週はSnowy Tree Trunk Shader - UE4 Materials 101 - Episode 20 [3] を勉強します。

以下にSnowy Treeの幹を示します。

このMaterialをNoise ノードを使用して作成します。

まず全体の内容を掴むために全部を軽く見ます。

11分の動画ですが、本当に基本的な事しかやっていません。

World PositionをNoiseノードのPositionにPassして、Noiseノードの設定を弄って雪がこびりついているようなNoiseを作成します。

後はLerpノードを使用してAに普段のMaterial、Bに雪のMaterialを付けてAlphaにこのNoiseの結果を付けて終わりです。

Noiseノードの設定方法以外は、Tutorialを見る前に推測出来ていました。

これは簡単なので今、ここで実装してしまいます。

まず必要な木の幹をMegaScanからDownloadしました。

まずこのMaterialをDuplicateします。

出来ました。

Duplicateした方のMateialから作成したInstanceを使用した木の幹です。

全く同じです。

LerpのAlphaの部分の実装です。

Noiseノードの設定です。

この設定を見るのはもう何回目かになりますが、ある事が分かりました。

この設定からどんなNoiseになるのかを推測するのは無理です。

逆にこのNoiseの模様は○○に使えそう。となった時にその設定を記録しておく事は出来ます。

この実装でPowerに0~1の間の値を掛けています。これをすると以下のような値の変化をもたらします。

つまり、全体的に白くなるわけです。

先程、DuplicateしたMaterialにこの実装を追加します。

結果です。

微調整しました。

うーん。

これだけでは雪が張り付いているようには見えないです。

もう一工夫は必要みたいです。

幹を何個か配置してみました。

すべての模様が違っています。

雪ではなく砂が付いた場合はどうでしょうか?

おお。

こっちはいけそうです。

3.2 How to make a REALISTIC ICE material in Unreal Engine [4] を勉強する

YouTubeのお勧めに氷のMaterialをBase Colorの実装だけで作成しているTutorialが出てきました。

これを勉強して先程のNoiseのAにつなげてみます。

白いペンキを塗ったような感じからRealな氷の感じが出せるでしょうか?

まずこのTutorialの内容を簡単にまとめます。

以下の様なTextureを使用してIceのMaterialを作成しています。

Textureは以下に示した様に3つあります。

Base Colorの銀とNormal MapのTextureは分かりますが、真ん中の白黒のやつがなんなのか不明です。

Tutorialで説明がありました。Displacement用のTextureだそうです。

これは多分要らないでしょう。

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

TextureのBase ColorとNormal MapをこのMaterialにImportします。

やっぱりDisplacementは使用しないそうです。

Base Color用のTextureをBase Colorに繋ぎます。

この状態の結果です。

奥行がなくてペンキで塗ったみたいです。

ここからが一寸難しいです。

Texture SampleノードのUVsに以下の実装を繋ぎます。

この実装の意味は現時点ではよく分かりません。

結果です。

少し氷らしくなりました。

更にCustom Reflection Vector ノードのCamera Vector(V3)に以下の実装を追加しました。

更に以下の部分の実装を追加します。

結果です。

うーん。

よくわからない。

けど実装してみます。

3.3 How to make a REALISTIC ICE material in Unreal Engine [4] を実装する

まず使用するTextureですが適当なのをMegaScanから持ってきました。

あまりTutorialと似た感じのMaterialが見つからなくて、これになりました。

まず以下の様にBase Colorを繋ぎました。

結果です。

うーん。

TutorialのTextureとはかなり違いますね。

でも一応これで最後までやってみます。

以下の実装を組みました。

この実装の意味が分からないのは、

以下に示したCustom Reflection Vectorノードの機能が分からないからです。

このNodeの機能は後で調べます。

Camera Vector(V3)を追加します。

更に以下の部分まで追加します。

結果です。

ただの白い円柱になってしまいました。

うーん。

別なTextureを探します。

これで試してみます。

結果です。

これは凍っているようには見えないですね。

次はこれです。

結果です。

これは全く氷に見えません。

最後はこれです。

結果です。

これは雪の中に影が見えて少しは透けているように見えなくもないです。

これでやってみます。

3.4 How to make a REALISTIC ICE material in Unreal Engine [4] の実装を Snowy Tree Trunk Shader - UE4 Materials 101 - Episode 20 [3]に追加する。

以下の様にこの実装を先程のNoiseに追加しました。

結果です。

うーん。

もう少し雪の部分を増やしてみます。

うーん。

これ自体は前よりは良いです。

単なる白と比較してみます。

変らないです。

いや、こっちの方が良いかもしれません。

以下の実装をLerpノードのBに繋いでみました。

これだと雪の淵が青くなります。

結果です。

一寸は凍っている感が出てきました。

角度を変えてみました。

これはかなり凍って見えます。

3.5 Custom Reflection Vector ノードについて

折角How to make a REALISTIC ICE material in Unreal Engine [4]を勉強してBase Colorだけ使用して氷のようなReflectionを追加しようとしましたが、Custom Reflection Vector ノードの使用方法が良く分からなくて、自分で調整出来ませんでした。

一寸悔しいのでこのNodeについて勉強します。

まず公式のDocumentであるReflections Material Functions [5]でCustom Reflection Vectorの解説を見つけました。

これ読むとReflection Vector全般の使用方法を理解する必要がありそうです。

Reflection VectorのTutorialを探したらBen Cloward先生のTutorialがありました。

Reflection and Refraction Vectors - Shader Graph Basics - Episode 24 [6]です。

これ前に勉強しているはずなんですが、記憶にないです。

Blogの検索もしたんですが、見つからないです。

うーん。おかしいですね。

詳しく調べたら、2021-12-26のBlogでAdvanced Channel Packing - Shader Graph Basics - Episode 23を勉強しています。

いますがどうもこの回のTutorialはSubstance Designerを使用してTextureを加工しているので、自分でやる事が出来ない。と言っています。

そしてその次の週である2022-01-10のBlogはUsing Position Data - Shader Graph Basics - Episode 26を勉強しています。

ひょっとするとTexture関連で繋がっているReflection and Refraction Vectors - Shader Graph Basics - Episode 24 [6]も実装する事が出来そうにないからSkipしたのかもしれません。

じゃあ。Reflection and Refraction Vectors - Shader Graph Basics - Episode 24 [6]は、今勉強します。

3.6 Reflection and Refraction Vectors - Shader Graph Basics - Episode 24 [6]を勉強する

まずReflectionとRefractionの簡単な説明がありました。

今週は、Reflection Vectorの使い方だけ分かれば良いのでRefraction Vectorは後で勉強する事にします。

まずReflection VectorノードのCustom World NormalにVertex Normal WSノードをつないでいます。

これNormalの座標はWorld Spaceでpassしています。

Custom Reflection Vectorノードの場合は(少なくともHow to make a REALISTIC ICE material in Unreal Engine [4]の例では)Tangent Spaceで計算しています。

うーん。

ひょっとして使い方全然違っていたりして。

その結果をTexture Sampleノードに繋げて、その結果をBase Colorに繋げます。

このTexture SampleノードにはCube Mapがセットされています。

結果です。

Sphereの表面にCube Mapの画像が写り込んでいます。

以上です。

実装もしてみます。

結果です。

普通に出来ましたね。

3.7 Custom Reflection Vectorノードで試してみる

まずCustom Reflection Vectorノードで Reflection and Refraction Vectors - Shader Graph Basics - Episode 24 [6]と同じ結果になる実装を作成します。

ここではWorld Spaceで計算してみました。

結果です。

普通に出来ましたね。

今度はTangent Spaceでやってみます。

結果です。

明らかにオカシイ結果です。

今度はNormal Mapを使用してみます。

座標軸はTangent Spaceです。

結果です。

な、何これ?

今度は座標軸をWorld Spaceに統一してみます。

結果です。

うーん。

分からないですけど、こっちの方が正しい感じがします。

Custom Reflection Vectorノードの使用方法はわかりましたが、逆にHow to make a REALISTIC ICE material in Unreal Engine [4]の実装が何をやっているのか分からなくなりました。

なので、

先程の

の青のColorの代わりにこのCustom Reflection Vectorノードの実装を使ってみました。

結果です。

うん。

これも良い感じです。

近づいてみます。

木が雪で凍っている状態を見た事はないですが、かなり本物っぽいです。

以下に比較のためにCustom Reflection Vectorノードを使用しなかった場合を示します。

こっちはこっちで本物っぽいんですが、どっちが正しいんでしょうか?

Custom Reflection VectorノードのNormalにPassしているNormal Mapを木のNormalと同じにしてみます。

結果です。

木の幹に近づいてみます。

凍った雪が木の凹凸に沿ってくっついています。

こっちの方が本物っぽいです。

もう少し工夫したらかなりPhoto-Realisticな雪で凍ったTreeのTrunckが作成出来そうです。

出来そうですが、もう今週はMaterialの勉強をする時間が無くなってしまいました。

ここでお終いにします。

4.RPGPackagingについて

先週、C++付きのProjectの名前を変更する手順がまとめられたTutorialを勉強しましたが、何か納得出来ません。

C++付きのProjectの名前を変更する方法が書いてある別なサイトを見つけました。

今週は、こっちを勉強して2つのやり方を比較する事にします。

4.1 UE4 – How to Rename an Unreal Engine Project with Sources Files [7] を勉強する

Step 1: Projectを掃除する

以下の赤線を引いたFolderやFileを消します。

TutorialではBuild Folderも消しています。

私のProjectにはBuild Folderがないです。

そう。

先週のTutorialを勉強して感じた違和感がこれでした。

先週のTutorialにはこの作業が無かったんです。

以下のCommentがありました。

これの直し方を明確に教えてほしいです。

<Step 2: .uprojectの名前を新しい名前に変更する>

先週、新しいProject名はCh5_1にすると決めました。

まず以下のuprojectの名前を変更するそうです。

まあ。これは当然です。

次にこの.uprojectをEditorで開いて、

中に書かれているModule内のNameを古い名前から新しい名前に変更します。

これも先週勉強したTutorialと同じです。

<Step 3: DefaultGame.ini内の名前を変更する>

何故か、私のDefaultGame.iniにはこの部分が無いです。

先週のTutorialには、もし無い場合は以下に示した様にしろと書かれていましたが、

このTutorialには、以下に示した様にProjectName=部分に新しい名前を入れろとしか説明していませんでした。

うーん。

このTutorialにも不安がありますね。

Step 4: C++Source Fileの名前を編集する

まず私のSource Fileを開くと以下の様になっています。

<<Step 4_1: Editor.Target.cs Fileを編集する>>

まずFileの名前を編集します。

そしてFileを開いて以下の箇所を全部、直します。

これは先週、勉強したTutorialと全く同じ事を言っています。

<<Step 4_2: Target.cs Fileを編集する>>

Target.cs Fileも編集します。

やる内容なEditor.Target.cs Fileと全く同じですね。

先週のTutorialの内容も確認しましたが全く同じ事を書いています。

<<Module とそれに関連するSourcesの名前を変更>>

まずFolderの名前を変更します。

まず以下に示したFileの名前を直します。

更にこれらのFileを開いてclass names と constructor namesも新しい名前に変更します。

私のCharacter.hの場合は以下の緑の線の部分の変更をします。

今度は全てのSource FileのAPIの名前を変更します。

このTutorialの場合は以下の部分です。

所が私のFileにはAPIを表示している部分がありません。

むー。

良く分かりません。

先週のTutorialと比較してみると、要するに前の名前が残っている箇所は全部、新しい名前に変更しろ。と言う事のようです。

API名は有ったと思うんですが何でないんでしょうか?

後、どっちのTutorialも書いてなかったんですが、以下に示したGenerated.hはどうなんでしょうか?

これって自動的に追加された記憶があります。

これも手動で書き換えるのでしょうか?

Step 5. Visual Studio project files Rebuildprojectを起動

.uproject Fileを右Clickして以下のBoxを表示します。

Generate Visual Studio Project Filesを選択します。

Visual Studio Solutionが新しく生成されます。

その後でLaunch Gameを選択してUE Editorを開きます。

以上です。

4.2  UE4 – How to Rename an Unreal Engine Project with Sources Files [7] を勉強した感想

このTutorialには先週のTutorialに載っていた以下の部分に関しての解説が全く無かったです。

ただ、前に私がProjectの名前を変更した時も、この部分は弄った記憶が無いんです。

自動で直してくれる可能性もありそうです。

要らないFolderやSolutionを消す方法はこっちのTutorialには書かれていました。

両方のTutorialを見た結果、分からない事が何個かあります。

以下にまとめます。

<BPのReferenceの直し方>

2022-10-31のBlogにまとめた時に見つけた以下のCommentです。

このやり方が正しいとは思えません。

もしBPの親をUE4C++で作成したクラスからそのUEC++クラスの親クラスに変更したらUEC++クラスで作成した変数やMember Functionが無くなってしまうでしょう。

更に今まで、何回もProjectの名前を変更しましたが、これをやった事はないです。しなくてもErrorも起きなかったし、その後、何も問題起きなかったです。

ただし、これをやらなくてもBPのReferenceが正しくセットされている事の確認は出来ていません。

<DefaultEngine.iniの設定>

先週のTutorialではDefaultEngine.iniの以下の部分を直すように書かれていましたが、

今週のTutorialにはこの点に関しては全く述べられていません。

更に言うと前にProjectの名前を変更した時、この部分を弄った記憶は無いです。無いですがCodeが追加されていました。

<FileにあるはずのAPIの記載がない>

通常、UE4C++でClassを作成すると、以下に示した様に

Classの次にAPI名が入ります。

何故か、私のFileにはこれがありません。

<Generated.hの名前は直していいのか?>

以下に示した、Generated.hは自動で作成されたはずです。

いつ作成されたのかは覚えていませんが、Classを作成した時は、もしくはBuildした時に自動で追加されました。

これも変えてしまっていいんでしょうか?

この点はどちらのTutorialも何も述べていません。

前にProjectの名前を変更した時、これをどうしたか何ですが、覚えていないです。

4.3 前にProject名を変更した時のやり方を調べる

まずch4_3が作成された時期を調べます。

2020-05-17のBlogで作成していました。

この辺りのBlogを読むと、以下のErrorが頻繁に発生して原因が特定できない事態が続いています。

それでそれまで作成していたch3のProjectを放棄して一から新しいProjectを作成し直す事にしました。

ええ。

Ch3の名前を変更したんじゃなかったの?

それでch4_1を作成したんですが、Pure virtual functionの問題が消えません。

原因を突き詰めるためにch4_2を作成してテストをします。

すると、何と以下の条件でEditorがCrashする事が判明しました。

それでch4_3は急遽4.24にVersionを戻しました。

何故なら4.24ではこの問題は起きてなかったからです。

これがch4_3の作成方法でした。

Ch4_3は前のProjectをDuplicateしてProject名を変更して作成されたわけではなかったです。

最初から作り直したProjectでした。

思い出してきました。

例えば、GitHubとかでVersionの管理をすると、全体の内容を忘れてしまう。もっと大きなProjectになったらそれも仕方ないが、個人で作成しているProject、しかも基礎の部分は教科書に書かれているままに作成したモノで、全体の構成を忘れてしまうのは勉強したとは言えなくなってしまう。

ので、問題が起きて新しいProjectを新たに作成する時は、必ずさらのProjectで一から作成し直すようにします。と宣言していました。

今となってはUE4C++の部分だけなら一から作り直す事も可能かもしれませんが、その後に追加した膨大なBPの部分を一から作り直すのは無理です。

いや、Packagingの勉強が終わったらそれをやるつもりですが、Packagingの前にそれをやるつもりはありません。

話が逸れました。

兎に角、Ch4_3は何処かのProjectをDuplicateしてそれの名前を変更したのではない事は分かりました。

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

5.Open Worldの検証

5.1 建物の作成

階段を作成すると、作成した時はその階段を上るんですが、その後は、階段を上らなくなる現象がおきました。

ので先週の最後で階段をなくしたんですが、今週はその階段を作成します。

勿論、常に使用できる階段を作成します。

階段の幅が狭いから登れないと推測しました。

以下の様に床を一部くりぬいて大きな階段を作成しました。

テストします。

今度は何度試しても階段が登れるようになりました。

所が新たな問題が発生しました。

以下の箇所に透明な壁が発生しています。

ここから先に進む事が出来なくなっています。

これを直します。

先週、この位置に配置しておいたTableが何か悪さをしている気がします。

Table関連のStatic Meshを全部消しました。

違いました。

理由が分かりません。

Collisionを表示する方法がないか調べました。

CmdにShow Collisionと打てば良いそうです。

結果です。

なんと、屋根のCollisionがここまでありました。

これに引っかかっていました。

確認します。

屋根のStatic Meshを開きSimple Collisionを表示すると

屋根にかかる部分全部にCollisionが効いていました。

はあ。

Complex Collisionの方は

空間部分にはCollisionは指定されていません。

こっちを使用するようにします。

調べたらStatic Mesh Editorを開いて以下の箇所でCollision Complexityの設定をUse Complex Collision As Simpleにすると出来るみたいです。

結果です。

見事に無くなりました。

5.2 Naniteの勉強

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

SM_RockのNaniteが効いていませんでした。

Static Mesh Editorを開いてEnable Nanite SupportにCheckを入れてみましたら、Naniteが効きました。

先週はこのやり方ではNaniteが効かなかったんですが、どういう事でしょう。

よくわかりません。

今週は、このNaniteをたくさん表示してみようと思います。

以下の方法でSM_Rockを動的にたくさん生成します。

こんな感じです。

このSM_RockがNaniteで生成されているのかを確認します。

なんと、SM_Rockは動的に生成したのでRuntimeの間しか見ることが出来ないんですが、Runtime中にNaniteが効いているのかを確認する方法が分かりません。

Commad で確認出来ないでしょうか?

関係ありそうなCommandを表示させてみました。

試しにShow NaniteMeshesを打ってみました。

このCommandはNaniteを消したり出したりするみたいです。

動的に生成したSM_Rockが消えました。

静的に生成した他のNaniteも消えています。

Naniteではない建物はそのままあります。

もう一回Show NaniteMeshesを打ちました。

動的に生成したSM_Rockが現れました。

更に

Naniteである岩も現れました。

この結果から、Static Meshを動的に生成する実装で、 Naniteも動的に生成出来ていると考えられそうです。

もう少し視覚化出来る実験結果が欲しいです。来週はその辺を調査する事にします。

6.Gaeaの勉強

日本でGaeaを流行らして、QuadSpinning社からGaeaが売れるたびにMarginを貰うという野望を達成するために、今週もGaeaを勉強します。

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

今週もAndrea Cantelli氏のTutorialを勉強します。今週はGaea Tutorial for Beginners #2 | Node Graph Workflow [8]をやります。

まず軽く全部見ます。

見ました。

Node Graphの本当の基本を教えています。

本当の初心者なら、このTutorialは大助かりですが、今の私には多分何も勉強になる事ないない位の基本的な内容でした。

でも本当の初心者の場合、先週のTutorialを理解する事が出来ない。(今のVersionとTutorialのVersionが違う為、Tutorialで紹介しているUIが違い過ぎる。)ので宝の持ち腐れになっていますね。

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

<INTRO

まず以下の例でNodeを繋げてTerrainを作成する事を説明しています。

そこから説明するのかよ。って位、初心者向けです。

<Toolbox

Toolboxの解説です。

先程の、Node Graph内で使用されたNodeの全種類がここに配置されています。

これらのNodeはNode Graph内で右ClickしてもAccess出来ます。

Toolbox内に表示されているNodeはそれぞれのCategory毎にまとめられています。

<Primitive

Primitiveについてです。

最初のNodeは必ずPrimitiveから選びます。

Mountainノードが入ってないじゃん。と思ったら次のGeo Primitives内にありました。

TutorialのVersionは古いのでGeo PrimitivesというGroupがないです。

ここでNode Graph内の操作について簡単に解説していました。

  • Nodeを選択した状態でMouseの左ButtonHoldNodeを動かせます。
  • MouseMiddle ButtonRollする事でNodeを大きくしたり小さくしたり出来ます。
  • Node以外の場所をCursorで選択した状態でMouseMiddle ButtonHoldすると画面全体を動かせます。

これは知りませんでした。

<Parameters

全てのNodeはParameterを持っています。Nodeを選択すると以下に示した様なParameterが右端に表示されます。

Mountain ノードのそれぞれのParameterについても簡単な解説をしています。

これの使用方法についても簡単に説明していました。

もう私はこれの使用方法は完璧に理解しているのでここには記録しません。

NodeのInputとOutputについてです。

ここでMountainノードのOutputを他のNodeに繋げて見せています。

何故、Swirlノード?

初めて見るNodeです。

Mountainが渦巻き状になっています。

このSwirlノードはInputが2つあるNodeの例として登場したみたいです。

次にErosionノードです。

これはOutputが沢山あるNodeの例として登場したみたいです。

幾つかのNodeにはPresetが準備されています。

Erosionノードの場合、三本線を右クリックすると以下のBoxが表示されます。

この中にPresetがあります。

これを選択する事で適切なParameterの設定をする事が出来ます。

これは知りませんでした。

<Connecting Nodes

Nodeの繋げ方と言っていますが、NodeをGraph上に生成する方法について解説しています。

当然、Toolboxから引っ張ってくる。が一つ目です。

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

Nodeの名前をタイプするのが2つ目です。

3つ目の方法ですが、

NodeのOutputをMouseの右ボタンをHoldした状態で引っ張って

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

これを使用してNodeを生成します。

次はNode Graphの右下にある以下のMarkについてです。

Cursorを乗せたら以下の様な解説が表示されました。

つまりSeedの値をRandomに変更する機能です。

Nodeが選択されている時は選択されているNodeのSeedだけ変更します。選択されていない時は全部のNodeのSeedが変更されます。

Randomizing Nodes

MountainノードとSwirlノードの間にDisplaceノードを繋げる方法を説明していました。

Blogなら兎も角、動画でこんな簡単な操作を一々説明する必要は無いと思います。

操作の仕方が分からなかったらVideoを巻き戻して見れば良いだけですから。

Primitiveノードを最初に使用する必要がありますが、別に一個だけしか使用して行けないと言う訳ではないです。

以下の様に2つのPrimitiveをCombineノードで合体させても良いです。

結果です。

あれ、これ凄くない。

Mountainノードを使用した場合、山以外の場所が完全な平らですが、その欠点をDunesノードがCoverしてくれています。

試しに以下の実装を作成してみました。

結果です。

うーん。凄い気がします。

以上でした。

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

もうやっていて滅茶苦茶つまらなかったです。

これはTutorialの内容が本当の初心者向けであるだけでなく、私自身がGaeaの初心者だから、自分が作りたいモノが作れない苛立ちが更に勉強をつまらないものにしているんだと思います。

後、一年位、今のペースで勉強して行ったらGaeaの機能も大体理解して、自分が作成したいTerrainを作れるようになると思います。そうしたら勉強のペースも上がるし、作りたいものが作れるので面白さも上がるはずです。

今は我慢して勉強するしかないですね。

一応、以下の事を新たに学ぶ事が出来ました。

  • Nodeは必ずPrimitiveから選ぶ
  • Node Graph内の操作
    • Nodeを選択した状態でMouseの左ButtonHoldNodeを動かせます。
    • MouseMiddle ButtonRollする事でNodeを大きくしたり小さくしたり出来ます。
    • Node以外の場所をCursorで選択した状態でMouseMiddle ButtonHoldすると画面全体を動かせます。
  • Swirlノードについて
  • 以下の赤線で囲ったMarkの機能について

  • 2つのPrimitiveをCombineノードで合体させる方法について

こうやって見ると結構勉強になっています。

我慢して勉強を継続しましょう。

6.3 Klaus氏のTutorialがどうなっているのか確認だけしておく

2週間もKlaus氏のTutorialを見ていません。

どういう変化が起きているか確認だけしておきます。

うん。特に増えてはいませんでした。

7.雪山のMapの作成

今週もVolumetric Cloudの勉強をやります。

先週は、M_VolumetricCloud_02_Profiles_PaintClouds_MorningにあるRandom Lighting Strikesについて勉強したので、今週はその続きとしてRandom Lighting Strikesの実装を読む事にします。

ただし、このVolumetric Cloudで名前にPaintと付いているのは、Placeable Cloud用のMaterialだと。と言う事をある人から教わりました。

でそのPlaceable Cloudって奴が何なのかほとんど知りません。最初にそれについて調べます。

7.1 Placeable Cloudについて

2022-07-12のBlogに書いていますが、UE4: Analysis of Volumetric Clouds and How to Use Them [9]で勉強したんですが、Volumetric Cloudにはいつもやっているやり方以外に、以下の2つの作成方法があるそうです。

この2つの作成方法が有る事を知ったのは今年の7月頃なんですが、そこからの進展がありません。

今までこの2つのやり方に関する情報を得る事が全く出来ませんでした。

恐らくですが、このPlaceable Cloudと言うのはここで紹介されている2番目か3番目のやり方で使用されるMaterialなんでしょう。

これはいい機会なのでPlaceable Cloudについて調べてます。

ありました。

Placeable Cloudについて調べていたら、Volumetric Cloud Secrets [Unreal Engine 4 & 5] Works in UE5! [10] にそのやり方が説明されているという情報を得ました。

これをまず勉強します。

7.2 Volumetric Cloud Secrets [Unreal Engine 4 & 5] Works in UE5! [10]を勉強する

まず軽く全部見ます。

見ました。

内容については後で簡単にまとめますが、2022-07-12のBlogに書いてある2番目の方法が解説されていました。

このTutorialでは三番目の方法については全く解説していませんが、Material名にPaintが付いているのは、三番目の方法でVolumetric Cloudを作成する時に使用するMaterialだと思われます。

こっちのやり方も調べる必要があります。これは後でやります。

以下に2番目の方法のやり方についてまとめます。

以下のFolderに行って

BP_CloudMask_ObjectとBP_CloudMaskGeneratorを選択し

Levelに配置します。

BP_CloudMask_Objectのサイズを調整して以下の様にします。

今度は、Materialを変更します。

以下の場所に行って

以下のMaterial Instanceを選びます。

名前が小さくて見えません。

瞬間的にMaterial Instanceの名前が写っている時のScreenshotを取りました。

M_VolumetricCloud_03_Profiles_Billowy_Instと書かれています。

これをVolumetric CloudのMaterialにセットします。

以上です。

後はParameterを調整して雲の見た目を変更したり、BP_CloudMask_Objectの位置を移動して雲の位置を自由に変更したりしています。

7.3 Volumetric Cloud Secrets [Unreal Engine 4 & 5] Works in UE5! [10]を実装する

それでは実際にPlaceable Cloudを作成してみます。

以下のFloderに行きます。

BP_CloudMask_ObjectとBP_CloudMaskGeneratorを選択し

Level上に配置します。

結果です。

サイズを小さくします。

0.1倍にしました。

次にMaterialを選択します。

に行くと

たくさんのMaterialがありますが、

Tutorialで使用した

は無いです。

ただしMaterialはありました。

これからInstanceを作成したら同じでしょうか?

試してみます。

Instanceを作成しました。

これをVolumetric CloudのMaterialにセットします。

結果です。

うーん。

出来ているのか?

BP_CloudMask_Objectを選択して

KeyboardのFを押すと

以下の画面になりました。

ここでBP_CloudMask_Objectを動かすと

確かに雲が動きました。

Floorのある場所にCameraを戻して上を向くと

確かに雲がありました。

雲のサイズを変えて、さらに BP_CloudMask_Objectを増やして以下の形状の雲を作成しました。

Bird Viewから眺めています。

Floorから眺めた状態です。

うーん。

出来てますね。

7.4 Volumetric Cloud Secrets [Unreal Engine 4 & 5] Works in UE5! [10]を勉強して

Volumetric Cloudには今回このTutorialで勉強した内容以外に、Paintして雲を作成する方法があります。

更に、 BP_CloudMask_Objectが配置されていた場所を見ると、

雲をPaintするために必要そうなBPが何個かあります。

この一個前のFolderに戻るとMapがあります。

これを開くと

がありました。

Composite_Cloud_Objectsを開くと以下のMapが現れ

Outlinerには、以下に示した通り

BP_CloudMask_Objectが12個、BP_CloudMaskGeneratorが一個あります。

使用しているMaterialを確認すると

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

つまり、今Tutorialで勉強したやり方で雲を作成しています。

という事は、Map folderにあるもう一個のMapはPaintのやり方で雲を作成しているはずです。

見てみましょう。

Outlinerを見ると以下のObjectが使用されていました。

ここでVolumetric Cloudに関係ありそうなのは、

  • BP_PaintClouds
  • BP_PlanetTest
  • Volumetric Cloud

の3つだけですね。

Volumetric CloudのMaterialを見ると

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

これはどう見てもPaintでCloudを作成していますね。

この辺をヒントに、PaintによるVolumetric Cloudの作成のやり方も解明します。

調べました。

Unreal Engine Volumetric Paint Clouds Tutorial [11] にやり方が載っていました。

7.5 Unreal Engine Volumetric Paint Clouds Tutorial [11] を勉強する

軽く見ました。

Paintを使用してVolumetric Cloudを作成する方法が簡潔に説明されていました。

以下にまとめます。

まずVolumetric CloudのMaterialをPaint Materialに変更します。

Tutorialでは以下に示したM_VolumetricCloud_02_Profiles_Softを使用していました。

このMaterial、名前にPaintが入っていませんがそれでもOKみたいですね。

結果です。

雲が無いです。

これは2022-10-10のBlogで確認済みの事実です。

Tutorialはこの理由を解説していました。

M_VolumetricCloud_02_Profiles_Softを開くと以下のTexture SampleにセットされているTextureが

単なる黒だからだそうです。

これは知っています。

それでこの1カ月位、悩みまくっていました。

そして私の出した結論は、

でした。

ところが、これこのTutorialによるとPaintでVolumetric Cloudを作成するのに必須みたいです。

「えー。」ですよ。

そうだったのか。

今度はこの雲を描くためのBPを追加します。

以下のFloderに行って

BP_PaintCloudsを選択し

Level上に追加します。

Detailの設定を変更します。

Cloud Scales Kmを700にします。

Elevation To Paint At Kmを10にします。

更にTutorialでは以下のShow Grid BoundsにもCheckを入れていましたが、

これは要らないかもしれません。

今度はWorld Settingを変更します。

GameModeにPaint_Gameをセットします。

Paint_Gameは2種類あり上記のAddressにある方を選ぶ必要があります。

正しいPaint_Gameを選択出来た場合、HUD ClassにPaint_HUDがセットされているそうです。

これで準備は終わりだそうです。

Play ModeはSelected Viewportを選択する必要があります。

Playを押すと以下の画面に切り替わります。

これでPaint出来るそうです。

次は作った雲を消す方法です。

まずPlayを終了します。

Volumetric Cloudを選択します。

Materialに別なMaterialをセットします。

雲の形状が変化しました。

これって雲を消す方法じゃないです。雲の形を変える方法です。

そしたら次に本当に雲を消す方法を解説していました。

BP_PaintCloudsを選択します。

Clear Densityを押します。

以下の様になります。

うーん。

PaintでVolumetric Cloudを作成する方法は分かりましたが、これってSaveして別なLevelでも使用出来るんでしょうか?

Game内で使用するためには、Play画面になった時に、以下の画面になっては困ります。

これについては何の説明も無かったです。

7.6 Unreal Engine Volumetric Paint Clouds Tutorial [11] を実装する

それでは実際にPaintによるVolume Cloudの製作を試してみます。

まず、Volumetric CloudのMaterialに

をセットします。

次にBP_PaintCloudをLevel上に配置します。

Cloud Scale Kmを700、Elevation To Paint At Kmを10にセットします。

次はWorld SettingのGameModeにPaint_Gameをセットします。

うーん。

Paint_Gameが一個しかありません。その代りVolumetric Painting GameModeがあります。

多分Volumetric Painting GameModeが正しいんでしょう。

Volumetric Painting GameModeをSetしました。

HUD ClassがPaint_HUDになっています。

Playを押してみます。

結果です。

文字化けしています。

試しに空をMouseの左Buttonを押しながらなぞってみたら、雲が描けました。

うーん。

一応、出来てはいます。

雲を描いた後で、GameModeの設定を普通に戻しても雲はそのまま残っていました。

ただし、Saveした後で一回閉じたら雲は全部消えてしまっていました。

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

8.報酬システムの研究

今週はセリフを表示するためのWidgetを自作します。

8.1 Dialogue用のWidgetを自作する

まず、Dialogueを表しているWidgetのCopyを作成しました。

これを代わりに呼び出します。

細かい実装を直してDemo Diagloue Widgetと同じように動くようにしました。

会話用のImageを作成します。

これをDemo Diagloue Widgetを複製したWidgetに組み込みます。

Dialogueの位置を変更して完成です。

テストします。

Dialogueが望んだ位置に出てきてくれません。

うーん。

これは Demo Diagloue Widgetの実装をしっかり理解する必要がありそうです。

来週やる事にします。

9.Anime Renderingの勉強

9.1 Vroidで作成したModelUEImportするの続き

今週もVRM4U [12]のMaterialを読んで勉強します。

先週の最後にUnlitでも陰影がDirectional Lightの動きに沿って生成されるのはMaterial内で影の計算をしているはずだ。と言って終わっています。

これは先週のBlogには敢えて書かなかったんですが、Material内で影を計算するためには、そのObjectのWorld Spaceにおける位置、Cameraの位置、そしてDirectional Lightの向きの値をPassする必要があります。

Objectの位置の値はWorld Position ノードで知る事が出来ます。

Cameraの位置はCamera Positionノードで知る事が出来ます。

しかしDirectional Lightの向きの値はどうやって得るのでしょうか?

Directional Lightの向きを教えてくれるNodeは、少なくとも私が知っている範囲では無いはずです。

つまりInputか何かでDirectional Lightの向きをパスする実装を自分で作成する必要があるはずなんです。

今週はそれをどこでやっているのかを探します。

ヒントは

  • World PositionノードとCamera Position ノードを必ず使用している
  • Base ColorEmission Colorに最終的には達する

です。

まずWorld Position ノードの回りの実装をみます。

Camera Relative World Position (Excluding Material Offsets)ノードです。

イキナリ何をしているのか不明です。

ただこの実装はOutlineのBlock内にあるので陰影とは関係ないでしょう。

次のAbsolute World Positionノードです。

いきなりCamera PositionからAbsolute World Positionを引いています。

これは怪しい。

この周りの実装をしっかり読んでいきます。

この実装はUTS2:AngelRing(uv2)のBlock内の実装です。

このBlock内でVectorをパス出来るParameterは以下のAngelRingOffsetXYだけです。

ただしこのParameterはXYの値しかPassしていません。

Directional LightのRotationのzの値だけ変化させてみます。

にしました。

になりました。

明らかにVroidの陰影が変化しています。

つまりZの値が陰影の形成に影響していなければならないです。

のでこの部分の実装は影の形成とは関係ないです。

次に行きます。

Custom Depth TestというBlock内で使用されていました。

Custom Depthの値とCameraとWorld Positionの差分を比較しています。

このVroidの部位の何処かにCustom Depthが指定されているんでしょうか?

確認します。

結果です。

何処にもCustom Depthを使用している形跡はないです。

うーん。

これも違いそうです。

更に言うとDirectional Lightの値をPassしている箇所がないです。

このBlockは関係ないと思われます。

次のWorld Positionです。

Material FunctionでFovと言う名前が入っているのが3つも使用されています。

FovってField of viewと言う意味だと思うんですが、なんでこれを計算する必要があるんでしょうか?

何か、怪しい感じがすると見ていたらそのものずばりLight Directionと言う名前のNodeがありました。

Custom ノードですね。

Normal Block内にありました。

他のCustomノードも調べてみます。

Light Directionが2つ、Sky Light Directが一つありました。

今週はここまでにして、来週、このLight DirectionノードのHLSLを勉強します。

9.2 公式のDocumentStylized Rendering [13]の勉強

今週もLandscapeの実装を勉強します。

先週、LandscapeのGrass Layerの実装を勉強しましたが、何をしているのか不明な実装部分が何か所がありました。

今週はそれを検証します。

先週の勉強を読み直しましたが、どこまで細かく理解するかが問題です。

そこを考えた結果、以下の実装部を理解出来れば良いと結論づけました。

ので今週はこの部分を検証します。

新しいMaterialを作成してこの部分の実装をPasteしました。

結果です。

Sphereの位置をCameraから遠ざけます。

結果です。

白い部分が黒の回りに現れました。

更に白い部分に黒い影が追加されています。

でもこの実装はLandscapeに適応されています。Landscapeに丸い部分なんてないでしょう。

有ったとしても以下に示したCylinderの赤線で囲った部分みたいな感じでしょう。

これを遠くに移動させると

真っ白になりました。

はい。

この結果をふまえて、もう一度先週のLerpの部分の実装を見直します。

近い場所では、AとBのBlend、遠い場所はBで表示するようになります。

AはTextureを呼び出しているのでCostが掛かっています。それに比べてBは色を指定しているだけです。遠くのLandscapeははっきり見えないので低コストのBの実装で十分と言う事です。

もう一か所、このFresnel Alphaの値をLerpのAlphaとして使用している箇所があります。

Landscapeの緑色の部分です。

これも近くのLandscapeはAとBの混合で遠くのLandscapeはBで表しています。

近くを表すAはTextureを呼び出していてBに比べると精密な模様を再現出来ますが、Costが掛かっています。茶色の地面と同じ理屈です。

以上です。

先週、Rock and Grass diffuseのBlock外に書かれている実装だったので無視した以下のLerpノードのAlphaの実装も見てみます。

これです。

Controls Height of Rock Offで実装されています。

World Aligned Blend#2ノードの結果を見てみます。

以下に示します。

ある一定の高さ以上は白、それ以下は黒を示す機能を持ったNodeの様です。

あ、Lerp#4とLerp#5ノードの意味が分かりました。

まずLerp#4ですが、ある一定の高さ以下はAになります。

Aの実装は以下の様になっています。

ので茶色になります。

Lerp#4の続きですが、ある一定の高さ以上はBになります。

Bの実装ですが以下に示した様にLerp#5 が繋がっています。

このLerp#5のAlphaもControls Height of Rock Offに繋がっています。

正し別のWorld Aligned Blendノードに繋がっているため

白くなる高さを変える事が出来ます。

ここでAの場合は焦げ茶色、Bの場合は模様入りの緑色になります。

World Aligned Blendノードを使ってどうやって高さを指定するのかについて調べます。

何と、Stylized Rendering Landscape [14] に詳しい解説がありました。

これ、前に何回か勉強していますね。

でも、前回までの勉強で理解したとは言い難いですね。

何故からここでWorld Surface Normalという表現がありますが、これNormal VectorをTangent SpaceからWorld Spaceに変換した値だと思われます。

これと基準になるNormalを比較して(恐らくDot Productをして)垂直だった場合は0、水平だった場合は1を返すそうです。

単純に高度で色を分けているわけでは無かったです。

中を見ると以下の実装になっていました。

一寸だけ見てみます。

軽く読んだだけですが、Explicit Normalの結果だと

Explicit NormalとWorld Vectorの結果をDot Productで掛けているだけです。

このWorld VectorがLandscapeのVectorを表していると思ったんですが、以下に示した様に単なる0,0,1でした。

これだと単に0,0,1に0,0,1をDot Productしているだけになってしまいます。

うーん。

分かりました。

以下に示したWorld Aligned BlendノードのExplicit Normalの値を計算している部分ですが、

Texture Sample#5 ノードにセットされているTextureは単なる青では無くて、以下に示したNormal Mapでした。

この値と先程のWorld Vectorにセットされている0,0,1をDot Productして計算していました。

もう一度まとめます。

以下のLerp#4とLerp#5のAlphaは

Landscapeの高さによって茶色と緑色に分けられているのではなくて、World Aligned BlendノードのExplicit NormalにパスされているNormal Mapの値によって茶色と緑色に分けられていました。

今週のStylized Renderingの勉強はこの辺で終わりにします。

来週は、もう少し詳しくWorld Aligned Blendノードの機能を検証します。

 9.3 法線転写をUEで実装する方法を検証

Historiaさんの[UE4]動的法線転写について[15]を勉強します。

先週で一応、法線転写の実装は完成したんですが、実は、直している途中でMF_NormalWeightModifierを理解しなくても以下の赤丸の部分の値を 1にすれば良い事に気が付いて、MF_NormalWeightModifierを外してテストしていました。

ので、今週はMF_NormalWeightModifierの実装をしっかり理解します。

以下の球を仮定します。

Minは半径2cm、Maxは半径4cmです。

中心から4cm以上に遠い場合です。

例は5cmとします。

まず5cmからMaxの半径である4cmを引きます。1㎝になります。

次にMinの半径からMaxの半径を引きます。2-4 = -2で-2cmになります。

最後に1cmを-2cmで割ります。答えは-0.5cmになります。

Lerpの値は0になります。

次に中心から2cm以内、つまりMinの中にある場合です。

例は1㎝とします。

まず1cmからMaxの半径である4cmを引きます。-3 cmになります。

次にMinの半径からMaxの半径を引きます。2-4 = -2で-2cmになります。

最後に-3 cmを-2cmで割ります。答えは1.5cmになります。

Lerpの値はNormal Modification Weightの値になります。

最後に中心から2cm以上4cm以下の場合です。つまりMinの半径より大きいけどMaxの半径より小さい場合です。

3cmで計算します。

まず3cmからMaxの半径である4cmを引きます。-1 cmになります。

次にMinの半径からMaxの半径を引きます。2-4 = -2で-2cmになります。

最後に-1 cmを-2cmで割ります。答えは0.5cmになります。

Lerpの値はNormal Modification Weightの値次第ですが、0とNormal Modification Weightの値の間の場合はLinear Interpolationに従ってその間の値になります。Normal Modification Weightの値以上の場合はNormal Modification Weightの値になります。

はい。

Historiaさんの図の説明通りの結果になりました。

やっと全部理解しました。

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

来週からは、見た目を良くするための調整をやって行きます。

10.DirectX 12の勉強

今週も C++ DirectX 12 Game Engine - [S01E01] - Creating Our First Window [16]の続きを勉強します。

10.1  先週、勉強した部分を実装する

Creating our Empty Project

WinMain.cppをPrivate Folderに追加しました。

以下の実装を打ち込みました。

自動で表示してくれるのかと思いましたが、してくれないので一個ずつ打ち込みました。

以下の警告が出ています。

Annotationって何だったけ?

色々調べた結果、

Stack Overflowの Code analysis says Inconsistent annotation for 'wWinMain' : this instance has no annotations [17]の回答通りに直しました。

どうもこの場合のAnnotationは、以下の赤い線で囲った部分を指すみたいです。

Understanding SAL [18]によると

以下のCodeにAnnotationを追加して

以下のCodeにしています。

つまり、VoidとかIntの前にあるよくわからない書き込みの事をAnnotationと呼んでいるみたいです。

Understanding SAL [18]によると、これらのAnnotationは、ComplierがCodeを読むときの助けになるそうです。

そのAnnotationを追加した結果、警告も消えました。

突然、Visual StudioをUpdateするとか出てきました。

OKしたらInstallarが開いて結構、大規模なUpdateしています。

終わって再起動しました。

特に問題はないみたいです。

以下のAppがInstallされていました。

NVIDIAのAppはVisual StudioのUpdateをする前にDriverを最新版にしたためです。

InstallするAppは全部、厳格に管理すると宣言しましたが、既に無理になりつつあります。

続きをやります。

<Creating Windows

以下に示した3つを実装します。

まずはWindow Classの作成をします。

WNDCLASSEX型であるwcex変数を宣言します。

ここまでは順調ですね。

ここからこのwcexのPropertiesを指定していきます。

まず4つの絶対変わらないPropertiesを指定します。

入れました。

次にこのTutorial Seriesでは絶対に変更しないParameterを指定します。

これはCursorとBackgroundに関する指定だそうです。

ぱっと見には、Nullを指定しているだけで何か特別な指定をしているようには見えません。

次はIconに関する指定です。

出来ました。

Iconの何を指定しているんでしょうか?

調べたら分かるでしょうが、そこまでのやる気が出ません。

次はClass Nameの指定をします。

ここで色々な解説をTutorialはして最終的に以下の実装になります。

このあたりの内容は先週、簡単にまとめたので今週は、単にこの形を実装するところだけやります。

要するにここでTutorialが説明しているのは数字を直接入れるな。というProgramming

の原則を学術的に説明しているだけです。

今度はWindow Classを初期化します。

うーん。

この方法がもっとも適切な初期化の方法なんでしょうか?

もっとお勧めの方法がありそうですが、面倒なので調べません。

今度はMenu Barの指定をします。

先週、以下の様に述べていますが、

Tutorialに簡単な説明がありました。

Menu Barの作成でMenu Barが要らない場合はnullptrを指定するのだそうです。

後、lpsz Menu NameはwcexのParameterで別にここで新しい変数として宣言している訳でないです。

ので初期化云々は完全に間違った解釈ですね。

次はHInstanceの初期化です。

これが、いろいろ面倒な作業があります。

それでどうやるのが正解なのかよく分からない部分があるので、先に前にDownloadしたSample Codeで確認します。

以下のFileを開きます。

以下のようになっていました。

ただし、この書き方だと、

先程のAnnotationの警告が出ています。

うーん。

どうしようかな?

よし。

まずはTutorialと同じCodeを書くところまでやります。

その後で、Annotationについては考えます。

しました。

しかしやっぱりAnnotationの警告が出てきました。

うーん。

どうしようかな。

試しにSample Codeを実行したら普通に動きました。

警告ですので、実用に問題があるわけではないです。

試しに以下の様にしたら警告が消えました。

うーん。

これで良し。

後、調べないといけないのが、Get Module Handle 関数についてと、このDefineにおける指定のやり方です。

これよく知らないです。

これは後で時間を取ってやります。

次に行きます。

このWindowがどう扱われるかのInstructionを指定するそうです。

Define Window Procedure って事でしょうか?

Tutorialの説明を聞いていると、Default Window Procedureかもしれません。

これでPropertyの指定は終わりだそうです。

このClassを登録します。

先週、勉強した範囲はここまでですね。

今週のDirect Xの勉強はここまでにします。

11.まとめと感想

段々、時間を確保するのが難しくなってきました。

今週のDirect Xの勉強はCancelしようか迷いました。でも何とかやり遂げました。

まあ、無理せず、慌てず、しかししっかりと勉強していきます。

12.参照Reference

[1] In OpenGL vertex shaders, what is w, and why do I divide by it? (2010, March 11). Stack Overflow. https://stackoverflow.com/questions/2422750/in-opengl-vertex-shaders-what-is-w-and-why-do-i-divide-by-it

[2] CGHOW. (2022, August 4). Chocolate Flip Fluid in UE5 Niagara Tutorial | Download Files [Video]. YouTube. https://www.youtube.com/watch?v=11sk4idR-HE

[3] Ben Cloward. (2020, April 2). Snowy Tree Trunk Shader - UE4 Materials 101 - Episode 20 [Video]. YouTube. https://www.youtube.com/watch?v=dco2ra0xAcY

[4] UnrealMatter. (2022, July 5). How to make a REALISTIC ICE material in Unreal Engine [Video]. YouTube. https://www.youtube.com/watch?v=DRXjUNWLW5M

[5] Reflections Material Functions. (n.d.). https://docs.unrealengine.com/5.0/en-US/reflections-material-functions-in-unreal-engine/

[6] Ben Cloward. (2021, November 25). Reflection and Refraction Vectors - Shader Graph Basics - Episode 24 [Video]. YouTube. https://www.youtube.com/watch?v=TNGNtVhCGvs

[7] UE4 – How to Rename an Unreal Engine Project with Sources Files. (2020, September 16). Isara Tech. https://isaratech.com/ue4-how-to-rename-an-unreal-engine-project-with-sources-files/

[8] Andrea Cantelli. (2020, May 24). Gaea Tutorial for Beginners #2 | Node Graph Workflow [Video]. YouTube. https://www.youtube.com/watch?v=lKxw45AoRbU

[9] WorldofLevelDesign. (2021, February 9). UE4: Analysis of Volumetric Clouds and How to Use Them [Video]. YouTube. https://www.youtube.com/watch?v=8XjEk-CP-kQ

[10] William Faucher. (2021, May 25). Volumetric Cloud Secrets  [Unreal Engine 4 & 5] Works in UE5! [Video]. YouTube. https://www.youtube.com/watch?v=yolGEIrhu0s

[11] Zero Conditional. (2021, March 2). Unreal Engine Volumetric Paint Clouds Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=SlR3eDr4jQc

[12] Harube, R. (n.d.). VRM4U. VRM4U. https://ruyo.github.io/VRM4U/

[13] Stylized Rendering. (n.d.). Unreal Engine 4.27 Documentation. https://docs.unrealengine.com/4.27/en-US/Resources/Showcases/Stylized/

[14] Stylized Rendering Landscape. (n.d.). Unreal Engine 4.27 Documentation. https://docs.unrealengine.com/4.27/en-US/Resources/Showcases/Stylized/Landscape/

[15] 株式会社ヒストリア. (2022, June 30). [UE4] 動的法線転写について. Historia Inc - 株式会社ヒストリア. https://historia.co.jp/archives/11921/

[16] OlympusMonsTutorials. (2021, February 17). C++ DirectX 12 Game Engine - [S01E01] - Creating Our First Window. YouTube. C++ DirectX 12 Game Engine - [S01E01] - Creating Our First Window

[17] Code analysis says Inconsistent annotation for ’wWinMain’ : this instance has no annotations. (2012, October 25). Stack Overflow. https://stackoverflow.com/questions/13078953/code-analysis-says-inconsistent-annotation-for-wwinmain-this-instance-has-no

[18] Understanding SAL - Visual Studio 2015. (2016, November 15). Microsoft Learn. https://learn.microsoft.com/ja-jp/previous-versions/visualstudio/visual-studio-2015/code-quality/understanding-sal?view=vs-2015