<前文>
<いわゆるネトウヨと言われる人達に共通する西洋的な規律>
Totalで10年程アメリカに住んでいた私は、アメリカ社会がキリスト教的な思想に基づいて構成されているのを肌感覚で知っています。その社会の中には日本人が全く想像する事すら出来ない仕組みもありました。
驚いたのはロシアを含めてEuropeから来る人達にはアメリカ人と全く同じかほとんど同じ社会構成を持っているので、彼等はアメリカ人がキリスト教的な思想に基づいて何かの規律を強制する時に、直ぐに理解、対応出来るんです。
更に言うと、元欧米の植民地だった国から来た人達も、植民地時代の経験から、アメリカ人がキリスト教的な思想に基づいて何かの規律を強制する時に、直ぐに理解、対応出来きていました。
一番、アメリカ人がキリスト教的な思想に基づいて何かの規律を強制する時に対応出来ないのが、日本人、韓国人、台湾人を含む中国人のアジア人で、そもそもキリスト教的な思想自体が存在していないので、アメリカ人が本当は何を言いたいのかも理解出来ないし、それに対しての対応も頓珍漢なものになってしまいます。
日本に帰って来て所謂ネトウヨと呼ばれる人達とその影響下にある人達の行動の中に、その日本文化にないがアメリカを含むキリスト教的な思想に基づいて作られている社会には必ずある構造が存在している事に気が付きました。
今週の前文はそれについてです。
アメリカ人は自分達をよく羊に例えます。これは聖書から来ています。聖書が書かれた時代と地域は放牧、特に羊の養殖が盛んで、羊に例えて話すと、誰でも理解できたからです。
この羊に例えて話すのが、そもそも日本人には理解出来ないんです。ほとんどの日本人には放牧は身近な存在では有りません。日本人の知らない概念を羊に例えて説明されても更に困惑してしまいます。
その中でかなり今のアメリカ社会(特に田舎)でも強く残っている文化にSheep Dogと言うのが有ります。
Sheep Dogとは牧羊犬の事で、羊を放牧する時に、やんちゃな羊は群れから離れて一人でどっかに行ってしまうんです。それを牧羊犬、つまりSheep Dogが追いかけて群れに戻します。
更にSheep Dogは事前に羊が群れから出ないように威圧的に群れの回りを吠えながら走ったりもします。
これと全く同じ仕組みがアメリカの社会にはあります。
地元の教会が、その地域の日本で言う自治会みたいな役割をしています。
しかし日本と違うのはほぼほぼその地域の人が全員参加する事です。家族から一人だけ参加とかじゃなくて家族全員が参加します。そしてその中で今週の連絡みたいな話があります。日本だったら回覧板で説明するような内容をみんなの前で説明します。
これで感心した事が一つあります。
それは若い女性が引っ越しする時には必ず、トラックと引っ越しの手伝いをする若い男性を数人、準備するんです。開拓時代の相互援助の精神が現代にも存続しているのを垣間見ました。
で、その教会の仕事にSheep Dogがあるんです。これは若い男性のみが担当します。
仕事の内容は、まさしく牧羊犬と同じで群れから外れる羊を群れに戻す事なんです。ただし、この場合の群れは羊ではなく人です。そして群れから外れると言う意味は、キリスト教の倫理観から外れると言う意味になります。
例えば若い女性が、キリスト教的な価値観に相応しくない服装をしてたら呼び出して注意したりします。
しかし注意するのは相手がか弱い女性の場合のみで、群れから外れた人が男性の場合はボコボコにします。文字通りボコボコに殴って止めさせます。
まあ、実際は本当にボコボコに殴る前に、相手も降伏してSheep Dogの言う事に従うのでボコボコに殴るまでに発展はしませんが、社会的にはSheep Dogの立場の人達が、違反した人をボコボコに殴るのは許容範囲なんです。
そうしないとアメリカ社会、特に田舎の地域は文明化した社会を維持する事が出来ないんです。
このSheep Dog的な役割を担当する人なんですが、これ本当に簡単に決められます。日本の町内会の役員の決定より簡単に決められます。
明日から貴方やってね。って感じです。
それで明日から教会のモラルに違反した人をボコボコにする権利が与えれる訳です。
このSheep Dogという仕組みは、アメリカ社会、特に地方で田舎である社会を存続させるためには非常に重要な仕組みではありますが、その権力が強大であるため、Sheep Dogになる人には優れた判断力と見識が必要となるはずです。しかし実際は脳筋の若い男性たちが担当しています。
ので、本当に本能的な判断に基づいてボコボコにするかどうかが決められます。例えばGayの男性なんかが女装して町を歩いていたら直ぐにボコボコの対象です。
このSheep Dogとしての役割と行動と全く同じものが、所謂、ネトウヨと呼ばれる人達とその影響下にある人達の行動に見られます。
例えば、先程の国葬で半旗を上げなかった沖縄県をとことん叩いたりする行動は、私の目にはSheep Dogそのものに見えました。
ここには何故、沖縄県が半旗を上げなかったのか?についての人間的な考察や推測、そして自分以外の人達に対する思いやりが全くないです。半旗を上げないヤツはルールを違反したやつだから、反省するまでとことん殴る。の精神しか見えないです。
そしてこの、ルールを違反したやつだから、反省するまでとことん殴る。は、私がアメリカで見たSheep Dogの文化そのものです。
何故、ネトウヨと呼ばれる人達とその影響下の人達が、アメリカ文化で言うSheep Dogと全く同じ行動をするのでしょうか?
非常に興味のある現象です。
それは、偶発的にそうなったのか、あるいか誰かが指示して意図的にそうなったのでしょうか?
もし誰かが指示して意図的にそうなっているとしたらその指示を出している人、もしくは組織はどこなんでしょうか?
とても気になります。
気になりますが、ここからの詮索は完全な想像になるので、やっても時間の無駄になりそうです。ここで止めておきます。
それでは今週の勉強を始めます。
<本文>
1.今週の勉強について
今週も以下の内容についてやって行きます。
UE5を使用するものは新しいPCを使用します。UE4で作成しているものは今のPCでやります。
- Niagara: CGHOW氏のTutorialをやる
- Materialの勉強
- RPGのEventの作成
- Open Worldの検証
- Gaeaの勉強
- 雪山のMapの作成
- 報酬システムの研究
- Anime Renderingの勉強
2.Niagara: CGHOW氏のTutorialをやる
先週は Collision Query | UE5 Niagara #ScratchPad Module #9 [1] の途中でイスがぶっ壊れてしまい中止しました。
今週はその続きからやって行きます。
2.1 先週までの復習
流石にここまで日が空いてしまうと、前に何をやっていたのか忘れてしまいました。
2022-09-26のBlogを見ると何やっていたのか思い出しました。
Collision Query | UE5 Niagara #ScratchPad Module #9 [1]のScratch Padの部分の勉強は終わったんですが、その後にEffectの見栄えを良くするためのTutorialが続いています。Scratch Padそのものの勉強にはなりませんが、Niagaraの勉強にはなるので最後までこのTutorialをやる事にしたんです。
それで以下のEmitterの作成方法を勉強した所でイスが壊れて勉強どころじゃなくなったんでした。
今週はその続きからやって行きます。
2.2 Collision Query | UE5 Niagara #ScratchPad Module #9 [1] の続きを勉強する
Particle Update SectionのUpdate Mesh Orientation ModuleのRotation Rateを以下の様にセットします。
Alpha にセットした[Particle] Depth Outputがどんな機能を司るParameterなのか分かりません。
調べます。
2022-09-19のBlogに載っていました。
このTutorialで作成したScratch Pad内で作成した新しいParameterでした。
うーん。
確かに3週間も間が空くと前に勉強した内容ほとんど覚えていないですね。
回転にばらつきを追加するためにParticle Update SectionのUpdate Mesh Orientation Module のRotation RateのAにRandom Range Floatを追加します。
Render SectionのMesh Rendererの
Materialを以下の様にセットします。
この辺はもう見た目の調整ですね。
結果です。
回転してる白い小石みたいなMeshのMaterialが代わっています。
陰が出来てるのは確認出来ましたがそれだけです。
別にCubeじゃなくてもStatic Meshならなんでも衝突部分のEffectが表示されます。
以下の例では人形型のStatic Meshで試してます。
これだと先程の白い小石みたいなEffectが確認出来ません。
のでもう少し観察しました。
こっちは小石みたいなEffectが発生しているのが確認出来ました。
この球のMaterialに背景を写し込む機能を追加します。
最初のEmitterのRender SectionのMesh Renderer Moduleの
Materialを開きます。
前に作成した背景が写り込むMaterialの実装をPasteします。
このMaterialは作った記憶がありますね。
Main ノードのLighting ModeにSurface Forward Shadingをセットします。
Metallic とSpecularに1をセットします。
Roughnessに0.2をセットします。
結果です。
これだとまだ反射した景色が球に写っていないですね。
Particle Spawn SectionのInitialize Particle Moduleの
ColorのRの値を10にします。
CGHOW氏はこういうModuleのParameterをちょくちょく変更するんですが、これが単なる微調整なのかそれとも明確な目的があって変更しているのか、勉強している側からすると分かりにくいです。
結果です。
これ見ると、Static Meshとの衝突部分の色が光っているだけですね。
この部分の変更は、微調整だったみたいです。
Fresnelノードの計算結果にPowerしていますが、そのPowerノードのExpにDynamic ParameterノードのInput Dataの値をパスします。
これは単にContrastを上げているだけですね。
更にEmissive Colorの計算にも先程のFresnelの結果を追加します。
更にSpecularとMetallicの値もDynamic ParameterノードのInputからパスするようにします。
結果です。
うっすらと背景が反射して球に写っています。
最後にPost Process Effectを追加します。
Post Process Volumeを追加します。
Infinite Extent (Unboun… にCheckを入れます。
これはまあ、当然ですが、CGHOW氏、0.1秒位の早業でこれをやっているので、確認するのにコマ送りでTutorialを観察する必要がありました。
Image EffectsのVignette Intensityの値を0.4から1にします。
結果です。
画面の端は黒くなりました。
マジか!
Ben Cloward先生のTutorialでVignette IntensityをPost ProcessのMaterialを使用して実装するのを習いましたが、Post ProcessのParameterに元々あるとは。
今、勉強中のStylized RenderingのPost Processの解説(公式のDocumentのStylized Rendering Post Processing [2])に
と書かれています。
つまり実際に、Vignette Intensityを実装する時は、もし可能ならMaterialで実装するよりParameterを使った方が計算Costが掛からないです。
Ben Cloward先生のTutorialはMaterialの仕組みを本当に理解するためには非常に大切ですが、それをそのまま盲目的に実装してしまうと余計に計算Costが掛かってしまう場合もあるみたいですね。
これは勉強になりました。
更にBloomの値も以下の様に変化させています。
結果です。
うーん。
良く分かりません。
Bloomってどんな効果でしたっけ。
調べます。
Googleで検索したら以下の結果が出て来ました。
うーん。カメラの手法で撮影物の反射光を減らすために行うもののようです。
もっと調べたら、沢山のCG関係のサイトでBloomについてかなり詳しい解説をしているのが見つかりました。
それらを読むと光源の回りがボヤっとする現象をBloomと言っているみたいです。
一番、分かり易い説明していたカメラの話をしよう!・番外編映像で見るあの現象? [3]を引用しておきます。
うーん。
確かに夜の公園とかの電灯がボヤっと見える事がありますね。これをBloomと言うみたいです。
ここでUE5の公式のDocumentであるBloom [4]を見てみます。
光源や明るい物にGlow 効果を起こすためにHaloをする。と書かれています。
ここで言うHaloをするとは、天使の輪っかを表示する事を指しているのではなくて、対象物の回りが輝いて見える事を指していると思われます。
つまり、先程のBloomの解説と全く同じ事を言っています。
実は、一番最初に、この公式のDocumentであるBloom [4]を見たんですが、何を言っているのか全く意味が分からなかったんです。それで一端、Skipして別なSiteの情報を探したんです。
今なら完璧に何を言っているのか理解出来ます。
光源の様な光ってるモノにGlow効果を生じるために、対象物(この場合は光源)の回りを光らせます。
と言っていたんです。
うーん。
これで完璧にBloomについては理解しました。
UE5の公式のDocumentであるBloom [4]に以下のImageがありました。
Bloomが全くない時です。
Lightとその回りはくっきりと分かれています。
Bloomが非常に強い状態です。
Lightの回りがボヤっと光っています。
Tutorialでは、BloomのMethodにConvolutionを選択していますが、公式のDocumentであるBloom [4]によると
と解説されています。
そして以下のような星型の例が紹介されています。
TutorialではBloomのMethodにConvolutionを選択していますが、Textureに何も指定していません。
これでConvolutionの効果が出るのかどうかは良く分かりません。実装する時に確認します。
最後にChromatic AberrationのIntensityの値を調整しています。
これで終わりです。
量的には大した事ありませんが、久しぶりに勉強したので結構疲れました。
2.3 Collision Query | UE5 Niagara #ScratchPad Module #9 [1] を実装する
実装ですが、これは前のPCで途中まで実装しているので前のPCでやります。
うーん。前に途中まで作成したはずのNiagaraが見つかりません。
新しいPCで最初から実装する事にします。
まずTutorial通りにEmpty のLevelを作成します。
名前はCollision Queryとしました。
Exponential Height Fogを追加しました。
Fog Inscattering Colorを灰色にします。
次に球用のMaterialを作成します。
うーん。
これ作成した記憶があります。
もう一回、前のPCを探してみます。
無かったです。
Main ノードのShading ModelをUnlitにします。
Blend ModeをTranslucentにします。
更に、Two SideにもCheckを入れます。
MainノードのPinが以下の様に変化します。
Opacityに以下の実装を追加します。
Previewの結果です。
更に球に色をつけるために
Shading Modelの設定をDefault Litに戻し、
Particle Colorノードの値をBase ColorとEmissive Colorにつなげます。
Previewの結果です。
これでMaterialの設定は一端終わりです。
Niagara Systemの実装に移ります。
いつも通り、NSを作成してFountainを追加します。
名前はNS_Collision Queryとしました。
NSを開きます。
まずRender SectionのSprite Render Moduleを消し、Mesh Render Moduleを代わりに追加します。
Mesh RendererのMeshにSphereをセットし、Enable Material OverrideにCheckを入れます。
Override Materialsに先程作成したMaterial、M_Sphereをセットします。
Previewの結果です。
要らないModuleを全部消します。
更にEmitter Update SectionにSpawn Burst Instantaneous Moduleを追加します。
ここでいつものParticleを一個だけ生成して永遠に存在させる設定をします。
Emitter Update SectionのSpawn Burst Instantaneous Moduleの
Spawn Countの設定を1にして
Particle Update SectionのParticle State Moduleの
Kill Particle When Lifetime Has ElapsedのCheckを外します。
結果です。
一個のMeshがずっと存在しています。
全然、話は変わりますが、以下に示した様に球体のRenderingっていつになってもVertexを直線で結んだカクカクした多角形です。
Vertex同士を繋ぐときに直線でなく曲線にするとか、Geometry Shaderで更なるVertexを追加するとかで、元々のMeshがカクカクでもRenderingする時にはSmoothにすることは簡単なはずです。
その辺にこだわる技術者はいないんでしょうか?
というかUEの場合は、私が自分でMaterialの実装でやるべき事なんでしょうか?
ちなみにこのMeshのWireframeを見たら
こんなに細かいMeshで作成されていました。
これで何で、以下のようなカクカクが生じるんでしょうか?
気になったので記録に残しておきます。
Meshのサイズを10倍にします。
Particle Spawn SectionのInitialize Particle Moduleの
Mesh Scale ModeをUniformにして
Mesh Uniform Scaleの値を10にします。
結果です。
よく分かりませんが、サイズが10倍になっているはずです。
EmitterのProperties Moduleの
Local SpaceにCheckを入れて
NSをLevel上に配置します。
Tutorialでは、配置した後で、NSのMeshのサイズが10だと大きすぎるので2に変更していました。
Level上にSphereとCollisionするためのCubeを追加します。
Tutorialでは追加したCubeが白いのでMaterialを交換して黒くしていますが、なぜか私のは最初から黒いのでそのままで行きます。
Directional Lightを追加します。
Cubeが白くなってしまいました。
うーん。
急遽、Cube用のMaterialを作成しました。
取りあえずこれでやってみます。
今の時点ではCubeとNSのSphereがCollisionしても何も起きません。
今度は CubeとNSのSphereがCollisionしている箇所をくっきりさせます。
Depth Fadeノードを以下の位置に追加します。
TutorialによるとDepth FadeノードはMaterialとCollisionしている箇所を検知しその部分をFadeするそうです。
今回はCollisionしている箇所を強調したいので、Depth Fadeノードの結果をOne MinusしてAddします。
これだとMaterialの一部は1以上の値になりそうですが、それでも問題ないんでしょうね。
結果です。
Collisionしている箇所が白く強調されています。
Depth FadeノードのFade Distance Defaultの値を100から10に変更します。
結果です。
Collisionしている箇所で白くなっている部分の幅が短くなりました。
Cubeを移動させてみましたが、Cubeの移動に伴ってNSの白い部分も変化しました。
今度はNiagaraの実装です。
今までSphereを作成していたEmitterの名前をSphereに変更します。
そして新たにFountain TemplateのEmitterを追加します。
そしていつものように要らないModuleを消します。
Particle Spawn SectionのShape Location Moduleの
Tutorialではこれを100にすると前のEmitterで作成したSphereの表面と同じ大きさになると言っていますが、これは前のEmitterで使用してるMeshのサイズ次第だろうと思います。
Shape Location ModuleのSphere Surface Distributionの値を1にします。
これで生成されるParticleは全部、半径100㎝の球の表面になります。
ああ、わかりました。
最初のEmitterで生成するSphereのサイズは直径1mです。サイズを2倍にしているので半径1mになります。
なので2番目のEmitterがSpriteを生成する位置を Shape Location Moduleで半径100㎝に指定すると、最初のEmitterで生成されるSphereの表面に2番目のEmitterで生成されるSpriteが発生する訳です。
更にEmitter Update SectionのSpawn Rate Moduleを外して、Spawn Burst Instantaneous Modulewを追加します。
Spawn Bust Instantaneous ModuleのSpawn Countの値を1000にします。
そしてProperties Moduleから
Sim Targetの設定をGPUに変更します。
Fixed BoundsにCheckを入れます。
おお、やっとGPUを使用しますね。
新しいGPUの能力が垣間見れますね。
結果です。
当然ですが、何回もSpawnする必要はないので、
Emitter Update SectionのEmitter State Moduleの
Loop Behaviorの設定をOnceに変更して
Particle Update SectionのParticle State Moduleの
Kill Particle When Lifetime Has ElapsedのCheckを外します。
いつもやっているやつです。
今度はこの生成したSpriteに色をつけます。
Particle Update SectionにColor Moduleを追加します。
Color ModuleのColorに赤をセットします。
結果です。
CGHOW氏のTutorialはこれに限りませんが、あるEffectを生成するためのProgramming的な実装と単に見栄えをよくするためのデザイン的な実装をごちゃ混ぜで実装していきます。
これ慣れるまでかなり混乱します。
ここは単に生成するSpriteに色をつけて見栄えを良くするための実装です。
と思ったら、Color ModuleのColorにLerp Colorを追加して以下の様にセットしました。
これはCollisionしている箇所に発生するSpriteの色を変化させるための設定でした。
このLerp FactorにScratch Padで指定したParameterをセットしてCollisionしている箇所の値は1、それ以外は0の様にして色分けするんです。
ここまでやって思い出しました。
これ絶対前に実装しています。
どうして前に作成したNSが見つからないんでしょうか?
うーん。
まあしょうがない。ここでもう一回実装します。
新しいScratch Pad ModuleをParticle Update Sectionに追加します。
名前をCollision Queryとします。
Map Get ノードに[Input] New Collision Queryを追加します。
ここにきて今までずっとCollisionをCollusionってタイプしている事に気が付きました。
全部直します。
直ったはずです。
Query Mesh Distance Field GPUノードを追加します。
ただしこのNodeを使用するためにはProject Settingの設定を変更する必要があります。
Project SettingのGenerate Mesh Distance FieldsにCheckを入れます。
見たら最初からCheckが入っていました。
Query Mesh Distance Field GPUノードのField Sampling For World に[Particle] Positionの値をパスします。
次に Query Mesh Distance Field GPUノードのDistance To Nearist Surfaceの値をDistanceで引きます。
もうここまでやって完全に思い出しました。
これは一回実装しています。
さらにその後でこの部分の実装の意味もしっかり検証したはずです。
後で、もう一回実装したNSを探してみます。
今度はFadeで割ります。
その結果をSaturateしてMap Setノードの新しいParameter、[Particle] Depth Outputにパスします。
この辺のLogicは前にじっくりやったので後でその時のBlogを見直します。
これでParticle Update SectionのColor Moduleの
Lerp Factorに[Particle] Depth Outputを使用できるようになりました。
Collision Queryの値を以下の様にセットしました。
結果です。
最初、全く変化しませんでした。
後で、NSとCubeをWorld Spaceの0,0,0に置く必要がある事を思い出して位置を変更したら、出来ました。
今週の実装はここまでにして一寸前に勉強した内容を復習する事にします。
2.4 Collision Query | UE5 Niagara #ScratchPad Module #9 [1] の過去の勉強を復習する
過去のBlogを見直したんですが、実装はしてませんでした。Tutorialの内容を勉強しただけでした。ので今週の実装が初めてです。
なんで前に実装した気になっていたんでしょう?
不思議です。
今週は2週間ぶりの勉強なのであんまり無理しない事にします。
ここでNiagaraの勉強はお終いにします。
3.Materialの勉強
今週はBen Cloward先生のBloom & Glow Post Process Effect - Shader Graph Basics - Episode 56 [5]を勉強します。
久しぶりのBen Cloward先生のTutorialです。慌てずにしっかり勉強して行く事にします。
3.1 Bloom & Glow Post Process Effect - Shader Graph Basics - Episode 56 [5] を軽く見る
まずどんな内容なのかを知るためにTutorialを軽く見ます。
と思ったら何と先程、Niagaraの所で勉強したBloomの実装方法についてでした。
こんな偶然ってある。
もう今週はBloomについて勉強しろ!って天から指令が来ているようです。
何と、UEのMaterialではLower Resolutionの画面のSampleを得る方法がないので、結局MaterialからBloomを実装する事は出来なかったそうです。
と言う訳で今回はUnityのMaterialメインでBloomの実装のための理論を勉強するのがメインになります。
前の節で述べたように、UEで実際にPost ProcessでBloomの効果を追加する場合は、Post Process用のMaterialに実装しないで、Post ProcessのParameterであるBloomを使用します。
ここで大切なのはBloomをUEのPost Processで使用出来る様になる事ではなく、Bloomの実装方法を理解する事です。
それではいつも通りに以下に簡単にTutorialの内容をまとめます。
まずBloomの作成方法についてPhotoshopを使用して簡単に説明しています。
まず普通の写真があります。
このImageを2枚作成してAddすると
明るくなります。
黒が0、白が255もしくは1で管理されているので、同じImageを足すと白くなる訳です。
次に2つのImageのうちの一枚のLevelを変更してある明るさ以下は全部黒くします。
こんな機能は知らない。
いつも絵を描くのに利用しているMediBang Paintで確認したら
Level補正って言う機能がありました。
多分同じ機能でしよう。
入力に三角が3つありますし、出力がPhotoshopのOutput Levelの0から255と対応してそうです。
このLevelを使用して本当にある明るさ以下の部分を真っ黒に出来るのか確認します。
以下のImageに対してLevel補正を行います。
以下の条件でLevel補正してみます。
結果です。
確かに一定の明るさ以下の箇所が真っ黒くなりました。
Tutorialに戻ります。
今度はLevel補正したImageにGaussian Blurを掛けます。
結果です。
ボヤっと光った感じがします。
このImageを元のImageに加算します。
結果です。
Bloom効果が追加されました。
うーん。
これは自分でも試してみたい。
以下の写真で試してみます。
http://www.chichibuji.gr.jp/event/yomatsuri/より
まずCopyを作成します。
Copyした写真にLevel補正を掛けます。
結果です。
このImageにGaussian Blurを掛けます。
何とMediBang にはそのものずばりのガウスぼかしがありました。
あんまりぼかすと訳わからなくなります。一寸だけ掛ける事にしました。
このImageと元の写真を可算します。
結果です。
おお、比較のために元の写真も以下に示します。
うーん。
明るくなっている事自体は確認出来ましたが、Bloomが掛かっているのかと言われると微妙です。
でもBloom効果の基本的な実装方法は理解出来ました。
ここからの説明はUnityのMaterialになります。
うーん。理解出来るんだろうか。
出来るだけ頑張りますが、出来ない時はきっぱり諦めます。
今回のPost Processでは画面のBufferを沢山作成するので、簡単に実装するためにSub Graphを使用するそうです。
まずSub Graphを作成してその実装をします。
うーん。
これはUEで言うMaterial Functionみたいなものなんでしょうか?
以下の実装をしています。
このScreen PositionがUEでいう所のTexCoord[0]に当たるみたいですね。HD Scene Colorノードはその位置の色を返すみたいです。
今度はUEにおけるPostprocess用のMaterialを作成しているみたいです。
名前はTest Full Screen Bloomにしていました。
そこに先程作成したSub GraphであるSampleScreenを追加しています。
これを以下の箇所にセットします。
これはUEでいう所のPostprocessのMaterialですね。
ただこの実装だと実際の画面と全く同じになる気がします。
結果です。
やっぱりBloom効果はこれから追加するんですね。
一応、Tutorialの内容を理解出来ている様です。
先程作成したSub GraphであるSample Screenに以下のInputを追加しました。
OffsetとWeightはそのままの意味です。
LODですがScreenの精度がLODによって変化するそうです。UnityのMaterialでは、それぞれのLODにAccess出来るのでどのLODにAccessするのかをここで指定するそうです。
このTutorialの最後の方で、結局UEのMaterialではこの機能にAccessするNodeが無かったのでBloom効果を作り出す事が出来なかったと言っていました。ので、結構重要なInputになるみたいです。
でもそれだったらScene Texel Sizeノードでも使用して
そのPixelの回りのPixelの値の平均値でも計算して疑似LODを作成してそれを使用したら良い気がします。
それやっても駄目だったんでしょうか?
この辺は最後までじっくり見たら判明するでしょう。
Offsetの実装です。
1Pixelのサイズを掛けています。
Offsetを取るときに正確にPixel毎にOffsetをとる為の実装です。
その結果をScreen Positionに追加しています。
この辺の計算はUEのMaterialを理解出来ていれば直ぐに何をやっているのか分かりますね。
次はWeightの計算です。
HD Scene Colorの結果にWeightの値を掛けているだけです。
LODはHD Scene Colorノードのlod(f)に繋げるだけです。
はい。
これでScreenのそれぞれのLODを取ってる事が出来るそうです。
ここでCut Offの実装をする前に前に作成したTest Full Screen Bloomを見てみます。
Test Full Screen BloomはUEにおけるPostprocess用のMaterialに当たります。
先程、Sample Screenに追加したInputがこのGraph内のSample Screenノードにも追加されているのが確認出来ます。
ここでTutorialではそれぞれのInputによる変化を説明していますが、LOD以外は自明なのでLODだけ以下に示します。
LOD=1
LOD=3
LOD=6
これ見る限りUEでも作れそうだけど。
後で試してみましょう。
Sample Screenに戻って最後のInputであるCut offを繋げます。
その前にScreenのLODが変わってもOffsetの値が正しく反映されるように以下の変更を追加しました。
LODの値が変わる毎にScreenのPixel量も変化する事への対応だそうです。
これ見るとLODは番号が1上がる事にサイズが2の2乗分だけ小さくなるみたいです。
となるとLODを疑似的に作成するのもそれなりに考える必要がありますね。
うーん。
自分で一から作成するのは面倒ですね。
取りあえず最後までTutorialを見る事にします。
Cut Offです。
Cut Offの機能は先程のPhotoshopを使用したBloomの説明でやったLevel補正のある一定の強さの光より低い光は全部黒くする所を担当するそうです。
Cutoffの値を引いてSaturateするのは分かりますが、その後のCutoffの値をOne minusした値で割るのは何をしているんでしょう。
あ、分かりました。
Saturateした値の最大値が1(もしくは255)である保証はありません。
それがCutoffの値をOne minusした値で割ると最大値が1に成る訳です。
Cutoffの値を0.2にした結果です。
黒い部分が生成されています。このScreenの中で色の値が0.2以下が真っ黒になったわけです。
Cutoffの値を0.8にした結果です。
画面のほとんどが黒くなりました。
これをそれぞれの4方向にOffsetします。
ここでOffsetに0.5を入れているのが良く分かりません。Offsetは1で1Pixelになるように設定したはずです。何で0.5を入れるんでしょうか?
ここは後で考える事にします。
結果です。
比較のための元のImageです。
僅かにぼやけているのが分かります。
ここで新たなConceptの紹介です。
ここで作成するBloomには3つのStageを追加するそうです。Core、Glow、そしてHaze Stageです。
Core Stageはあんまりぼやけません。
Glow StageはCore Stageに比べてぼんやりしています。
最後のHaze Stageでは非常にぼんやりします。
CoreのためのInputを作成します。
それぞれのInputのDefault値などを以下のBoxから指定しています。
UnityのこういうデザインはUEより精錬されていて見ていて羨ましいです。
でもUnityからUEに移った人達は、Unityはちょっと複雑な機能(UEでは普通に使用されている機能)を使うと説明通りの性能を示さない。もしくは完全に使用出来ないと言います。
のでまあ、見た目だけで判断するのは危険ですね。
更に最近のUnityの大量のProgrammerの解雇、しかも最後は抵抗している人を引きずり出して会社から放り出した話や、Malwareを開発していた会社との合併などの黒い話を聞くと、とてもじゃないですがUnityをUEの代わりにする気にはなりませんが。
これらのInputを以下に示した様に繋げます。
この後、UEでいうMaterial Instanceみたいなのを作成してCoreのInputの値をLevel上から調整しています。
結果です。
これに元の画像を足します。
ここでMaterialを勉強する時間が無くなってしまいました。
残りは来週勉強します。
4.RPGのEventの作成
4.1 先週までの復習
久しぶりにやるので今まで何を勉強していたのか覚えていません。その復習から始めます。
2022-09-05のBlogと2022-09-12のBlogでEventの勉強をしています。
2022-09-05のBlogではEventの完了を宣言する実装をする箇所を特定しています。
以下の2か所です。
2022-09-12のBlogでは、以下の事をどうやって実装するのかについて検討しています。
思い出してきました。
Eventが完了した瞬間って、別なWidgetが開いている時なんです。なのでEventの完了を知らせるWidgetを表示するには、
- 開いているWidgetを一時的に消して、Eventの完了を知らせるWidgetを表示する。
- 開いているWidgetを閉じた後に、Eventの完了を知らせるWidgetを表示する。
- 開いているWidgetの上から、Eventの完了を知らせるWidgetを表示する。
の3つの方法の内のどれかを採用する必要があります。
3番目の方法が一番簡単ですが、これをやるにはEventの完了を知らせるWidgetが不透明であり、かつ開いているWidgetより大きい必要があります。
Event完了を知らせるWidgetは以下に示した通り。透明かつ開いているWidgetより小さいです。
ので3番目の方法を採用するためにはこのEventの完了を知らせるWidgetを作り直す必要が出て来ます。
これだけ綺麗なデザインを奇跡的に作成出来たのにそれを作り直すのは手間と運が必要になります。更にこの解決方法はProgrammingの勉強と全く関係ないので、私のUEの勉強する目的にも反します。
3番目の方法を採用するのは前2つの方法で出来なかった場合の最後の手段です。
1番と2番の方法ですが、2番はEventが完了してから、そのEventの完了を知らせるまで一定の空白時間があります。これが私は嫌でした。
犬を躾ける時に、犬が悪い事をした瞬間に叱る必要があるそうです。そうしないと犬は何で怒られてのか分からないからだそうです。
Eventの完了だって同じだと思います。
Eventが完了した、少し後でEventの完了を伝えるWidgetが表示されたって、Userは今更。と思うでしょう。
ので出来れば1番の方法でやってみたかったんです。
そして2022-09-12のBlogの検証で、1番の方法で実装出来る事が判明しました。
4.2 実際のRPGにEventの完了を知らせる実装をする
それでは実際のRPGにEventを実装してみます。
何と、
またSave出来なくなっています。
うーん。
調べたらSub Levelの大半がSave出来ないです。
うーん。
今週はこっちを直す事にします。
<Sub LevelがSave出来るように直す>
一回、再起動します。
さっき開いたときは普通にSave出来たはずです。理由が分かりません。もしかしたら再起動したら直っているかもしれません。
もし原因が分からなかったらMap1だけ作成し直します。
こんなにSub Levelが有る事自体がLandscapeそのものの作成方法に反しているので、Map1は設計思想が間違っています。
ただこれを作成した当時はまだWorld Compositionについて良く知らなかったのでそれを勉強した記録としての意味はあると考えて、敢えて残しているだけです。のでこのErrorが直らない場合は、全部作り直すのもありと考えています。
幾ら調べても原因が分からん。
と諦めかけた時、一応Googleで検索してみたらEditorが2個以上開いていない?
って書かれているのを見つけました。
ああ。
何て最も大切な原因をCheckするのを忘れていたんでしょうか?
Taskを開いて見たら確かに、Editorがもう一個裏で開いていました。
閉じました。
でも、幾つかのSub LevelはそれでもSave出来たんですよ。
今度はこのSave出来たSub Levelが何か悪さをしないか心配です。
試しにSub LevelのSaveを押したら鉛筆にマークに変わりません。
変わりませんが、Error表示は出てこないのでSave出来てるはずです。
Weaponに先程の実装を追加しました。
Saveしました。
これでSave出来ているはずです。
Projectを再起動して確認します。
Save出来ていました。
何故か裏でEditorが開いている状態でSave出来たSub Level 2_7が他のSub Levelの4倍位の大きさになっています。
これが正しいサイズなのか先程のSaveのせいでこんなになってしまったのか分かりません。これは来週直す事にします。
<>
実際のRPGにEventの完了を知らせる実装をする。の続きをやります。
今度は、W_EventEndScreenの実装をします。
VariableにWidgetを追加します。
以下の設定をする事で初期化する時にこのParameterをPass出来る様にします。
以下の様になりました。
Widget CollapsedにWeapon Widgetをパスします。
End Screen Widgetの方の実装です。
このWidgetを閉じる時、先程CollpsedしたWidget(Weapon Widget)をVisibleに戻します。
End Screen Widgetの方の実装は昔の設定で実装しています。
これを直します。
色々考えたんですがこれだけで出来るはずです。
これで武器屋で武器を買った時にEventの完了が表示されるはずです。
テストしてみます。
何も起きません。
あれ?
Break pointで確認しましたが問題なくこのNodeに来ています。
あ、分かりました。
Weapon Widgetは単なるButtonでした。このWeapon Widgetの親WidgetをCollapsedする必要がありました。
後、Add to Viewportノードを追加するのも忘れていました。
もう一回、テストします。
武器屋で短剣を購入した瞬間に以下のWidgetが表示されました。
閉じるButtonを押します。
元のWidgetが表示されました。
出来てますね。
もう一方の武器を拾った場合の実装は来週やります。
今週はここまでにします。
5.Open Worldの検証
前に何をやっていたのか完全に忘れてしまいました。
2022-09-19のBlogを見るとModular Fantasy Houseを使用して建物を作っています。
そして
と言っていました。
今週はこの小屋の中身を作成していきます。
5.1 小屋の中身を作成する
以下の様にTableと椅子を配置しました。
更にTableには食器とロウソクを配置しました。
暖炉も追加しました。
ここにEffectでロウソクと暖炉の炎を追加します。
ロウソクの炎を追加しました。
使用したEffectはEnvironment Pack 3のP_Candle Flameです。
これはCascadeで作成してありました。
暖炉に炎をEffectを追加します。
Starter KitにあるP_Fireを追加しました。
うーん。
火が暖炉からはみ出しています。
小屋の外から見ると火事状態です。
P_Fireのサイズを小さくしてみました。
Effect全体では小さくなったんですが、炎の発生する位置が暖炉からはみ出しています。
しかも小屋の外側に炎がはみ出しています。
これはEffect自体を直す必要があります。
5.2 暖炉用の炎を作成する
Starter KitにあるP_Fireを改良して暖炉用の炎のVFXを作成します。
まず、こんだけNiagaraを勉強しているのに敢えて古いCascadeのままP_fireを改良するのもアレなんで、Niagaraに変換します。
調べたらgameDev Outpost 氏のUE4 - Cascade to Niagara Converter [6]にやり方が載っていました。
これを参考にやってみます。
やり方は簡単でした。
まずPluginを開いて以下に示したCascade To Niagra ConverterのEnabledをCheckします。
Projectを再起動します。
Cascade で作成したParticleを右クリックすると以下のBoxが表示されます。
ここからConvert to Niagara Systemを選択します。
以下に示した様にNiagara Systemで実装したP_Fireが作成されました。
実装を見てみます。
おお。
結構複雑ですね。
最初のEmitterです。
Errorや警告があります。
直します。
直しました。
2番目のEmitterの以下のModuleの警告だけ直せませんでした。
以下の警告が出て来ます。
うーん。Normalized Angle to Degreesがどこに使用されているのかをキッチリ調べたら直せそうですが、このFunction、どうせUE5のNiagaraには無いんでしょう。
そこまでこの部分にEnegyを使う必要ない気がします。
これを修正して使用します。
まずこのNSを暖炉に配置しました。
火が漏れています。
まず生成されるParticleの範囲を小さくします。
全てのEmitterのSphere Location ModuleのSphere Radiusの値を30から10にしました。
元々の値が5のモノはそのままにしています。
結果です。
暖炉の中の炎なのに強烈な風が左に向かって吹いています。
外側から見た場合です。
火の粉が飛び散っています。
速度から直します。
Add Velocity ModuleのXの値を0に変更しました。
Acceleration Force Moduleのxの値も0に変更しました。
結果です。
炎の位置を微調整しました。
良い感じです。
外側から見てみます。
Flare(火の粉)が壁を超えています。
これを直すにはParticleが壁にCollisionするように設定すれば良いんです。
良いんですがそれのやり方を忘れてしまいました。
調べます。
Particle Update SectionにCollision Moduleを追加すれば良いみたいです。
Ember(火の粉)のEmitterに追加しました。
結果です。
基本的には火の粉がもれなくなりましたが、偶に一粒だけ飛び出す時が有ります。
調べたら隣のEmitterのSparkが漏れていました。
このEffectはあまり必要性を感じないので外しました。
結果です。
炎が暖炉内に収まるようになりました。
全体のScreen Shotです。
良い感じです。
ここで夕方や夜の場合の小屋の内部の様子を見ようと思ったんですが、以下の様に太陽光の向きを変えてもUE4ではUE5とは違って暗くなりません。
はい。残りはUE5に新しいProjectを作って作成し直す事にします。
今週はここまでとします。
6.Gaeaの勉強
Gaeaもどこまで勉強したのかすっかり忘れてしまいました。
6.1 先週までの復習
最後にGaeaを勉強したのは2022-09-19のBlogなのでそれをまず復習します。
だいたい読んで何をやっていたのか思い出しました。
基本的にはHow To Create An Open World Snow Landscape | Unreal Engine 5 Tutorial [7]を勉強していたんですが、2022-09-19のBlogの時点で、Gaeaの作成の部分は終わって残りはUEにImportしてUE内でLandscapeを作成する内容に移る所でした。
そしてTutorialではここからは前のTutorialで作成したLandscape用のMaterialとかPatreonの会員のみに提供している別のLandscape用のHeight Mapとかを使用しているので、残りは実装しないで見るだけにしようか迷っていました。
出来るところまではやってその後は見るだけにすると言って、取りあえずMega Scanから草のMaterialをDownloadしています。
その後で、Landscape用のMaterialを作成していますが、Tutorial通りの作成方法だとLayerの区別が出来ないので、来週、新しく作り直すと書いて終わっています。
それで一個問題が発生しました。
どのProjectでこれをやったのか分からないんです。
滅茶苦茶、一生懸命探したんですが、分かりません。
GaeaからExportしたDataは見つかりました。
ここで思い出したんですが、Mega Scanから直接Import出来るのは、私の今の設定だと4.24だけなんです。でも今更、4.24でLandscape作成したとは思えないです。
UE5は勿論、DefaultでImport出来る様になっていますから、ひょっとしたらUE5で作成したのかもしれないと思いもう一回調べ直しました。
そしたらありました。
UE5のProjectであるMyProject2にありました。
これからはProject名も必ず記録に残すようにします。
6.2 これからどうするのか?
まず、UE5は新しいPCでやる。の原則に従って新しいPCで残りはやる事にします。
Gaeaも新しいPCにInstallする事にします。
Height Map等のDataはUSBか何かで新しいPCに移します。
新しいPCを起動させました。
今週は、2週間前の勉強を思い出しながら勉強する必要があるので、古いPCを中心に勉強しましたが、これからはUE5の勉強に関しては、全部新しいPCでやるようにします。
新しいPCといえば、今度こそC Driveには必要最低限のProgrammingだけしか保存しないようにしていたのに、もう同じようなProgrammingが2個入っていました。
消したれ、と思ったんですが、念のために調べたらVersion違いで動かないSoftとかあるそうです。
それで消すのをためらっているんですが、どのSoftがどっちのVersionを必要としているのかが、既にわからないです。
古いVersionのRuntimeのInstall日は22日です。つまり私がPCを受け取る前の日です。なの元々Installされていたと考えるのが自然です。
となると新しいVersionのRuntimeは、Epic Game のLauncher、UE5、そしてValley of the AncientのどれかをInstallした時に同時にInstallされたはずです。
そういえばValley of the AncientをDownloadしたときに、なんか聞かれた記憶があります。
うーん。
消すのは止めます。
MyTestProject1でこのTutorialの続きをやることにします。
LandscapeのMaterialを作成します。
まずLandscapeLayerBlendを追加します。
たった2週間空いただけでこのNodeの名前を思い出す事も出来なくなっていました。
4つのLayerを追加しました。
Main ノードのUse Material AttributeにCheckを入れて
Mainノードの形状を以下の様に変更します。
Grass Layerから作っていきます。
Make Material AttributeノードをLayer Grassにつなぎました。
結構、思い出してきました。
これを、2022-09-19のBlogで実装したんです。
ここでTutorialではMegaScanからDownloadしたGrassのMaterialを使用しています。
新しいPCからMegaScanをDownloadした事はありませので、試してみます。
あっけなく出来ました。
こんなに簡単に出来るなんて。
やっぱりEpic GameのProgrammerの優秀さは半端じゃないです。
DownloadしたMaterialを使用してGrass LayerのMaterialを組みました。
ここが2022-09-19のBlogの最後の部分です。やっとこれまでのやっていた事の続きが出来る所まで戻りました。
ここで2022-09-19のBlogでは、このままTutorialの通りの作成するとLayer毎の違いがよく分からないからこれとは別なMaterialを作成しようとして終わっています。
それをこれからやります。
6.3 Layer確認用のMaterialの作成とLandscapeの作成
Layer確認用のMaterialが出来ました。
要は色でLayerを分けて本当にLandscapeのLayerが出来ているのか確認したいだけです。
新しいLandscapeを作成して以下の設定を追加します。
それぞれのLayerは適当に選びました。
このTutorialではこの部分の設定はあんまり詳しく解説していません。のでかなり適当にやりました。
この後、TutorialではScalingの値の計算方法についてかなり詳しく解説しています。
XとYについては理解していますが、zについても詳しい解説をしています。
これは大切なのでここでまとめ直します。
TutorialによるとZが100というのは512mの事を指します。
Unral UnitはDefautでは1 unitが1cmなので、その100倍は1mになります。
Height Mapに使用されているPngは確か24 bitsか32 bitsです。色の濃さを表すRGB、もしくはRGBAにこのBits数を割り振ると、それぞれに8bitsになります。2^8は256です。
2^8はあくまで数字のBit数で、これに+と‐を示すBitがついたはずです。だから2倍にします。512になりました。
512cmに100を掛けています。
このような理屈で512mになると言っていると推測しています。
ここからTutorialの解説に戻ります。
まずGaeaで作成されたHeight Mapの高さが512m以下の場合はこのままで良いそうです。
うーん。正確に高さもGaeaの設計と同じにするためには、512m以下の場合も計算した方が良い気がします。
Gaeaで作成したHeight Mapの高さが512m以上の場合のUEのzのScaleの計算方法です。
(Gaeaで作成したHeight Mapの高さ)x 100 /512
だそうです。
もしGaeaで作成したHeight Mapの高さが800mならば、
800 x 100 / 512 = 156.25
になるそうです。
この計算を導くためには、Zの基準値が512である事を知っている必要がありますね。
Landscapeの作成に関しては、今週はここまでにして残りは来週やる事にします。
6.4 Height Mapとz軸のScalingとLandscapeの歪みについての考察
この2週間の休み中に、ZのScalingとHeight Mapの高さとLandscapeの歪みの関係について新しい考察を思いついたのでそれをここに記録しておきます。
今まではLandscapeのZ方向の歪みを無くすためにはHeight Map全体の高さが問題と考えていました。
しかしこの2週間の休みでそれは違うんじゃないのかと言う事に気が付きました。
歪みは急激な変化によって生じます。
つまり全体の高さが512m以上であっても、それぞれのLandscapeの隣接するマス同士の差が僅かなモノであった場合、地形は歪みません。逆に全体の高さが512m以下であっても、あるマスの高さが0mであってそのマスに隣接するマスの高さが512m出会った場合、凄い歪んだLandscapeが出来るはずです。
つまり、ここで大切なのは隣接するマスとの高低差であり、それが何m以下である場合は歪みが出ない。という事になります。
この観点からLandscapeの歪みについて考える必要があります。
7.雪山のMapの作成
もうこれも雪山のMapは一個作成してしまって、Volumetric Cloudは別枠で勉強したいです。
7.1 先週までの復習
取りあえず、これも休むまで何をやっていたのかを判明するために2022-09-19のBlogを読み直します。
以下の手順でVolumetric Cloudについて勉強しようと2022-09-05のBlogで決めたみたいです。
そして2022-09-19のBlogでは2のUnreal Engine 5 Beginner Tutorial | Sky And Clouds [8] を勉強しました。
Unreal Engine 5 Beginner Tutorial | Sky And Clouds [8]はVolumetric CloudのMaterialの作成そのものについてはほとんど触れられていなかったんですが、Empty Levelからの空の自作方法について非常に詳しい解説がされていました。
今週はPluginのVolumetric Cloudで使用されているMaterialの実装を見て行こうと思います。
7.2 Volumetric ContentのMaterial
以下のMaterialがありました。
今週はここにあるそれぞれのMaterialの実装を一寸だけ見ていきます。
それで来週からのこれらのMaterialの勉強方法に対しての指針を考えます。
<M_Cloud_LightFunction>
このMaterial、名前はFunctionとなっていますが実際はMaterialです。
Main ノードの設定が以下の様になっています。
その結果MainノードのInputはEmissive Colorのみになっています。
Material DomainにLight Functionを選択した事は今までないですね。
ただこれはVolumetric CloudのMaterial用ではない気がします。
<M_CloudLightFunction>
これもM_Cloud_LightFunctionと同じです。
<M_Sky_CustomNode_Prototype>
これはVolumetric Cloud用のMaterialなんでしょうか?
Main ノードの設定です。
Material DomainがSurface(Volumetric Cloud用のMaterialはVolume)、Blend ModeがAlpha Composite (Pre-multiplied Alpha) (Volumetric Cloud用のMaterialはAdditive)になっています。
Main ノードのInputを見るとVolumetric Cloud用のMaterialに使用出来そうな雰囲気はあります。
以下の説明がありました。
別のMaterialで勉強する事にします。
<M_VolumetricCloud_01_FalloffFunction>
これはMain ノードの設定を見る限りVolumetric Cloud用のMaterialです。
Albedoは簡単にして
Extinctionは複雑なやつでした。
Volumetric Advanced Outputです。
Conservative Densityは使用していませんね。
Volumetric Textureも2か所で使用されていました。
Cloud Sample Attribute ノードは2か所で使用されていました。
雲の上部に近づく程、青くなる実装ですね。
こっちは雲の厚さを調整するための実装です。
これだけ見ると少なくともこの実装は理解出来そうです。
来週はこの実装を勉強する事にします。
Volumetric Sky Prototype Mapを開いて
このMaterialをVolumetric Cloudに使用しました。
結果です。
値はDefault値のままです。
うっすらと雲がかかっています。
<M_VolumetricCloud_02_Profiles_PaintClouds>
Main ノードの設定です。
この設定を見るとこれもVolumetric CloudのMaterialです。
実装部分です。
これはかなり複雑です。解説が無いと理解出来ないかもしれませんね。
このMaterialをVolumetric Sky Prototype MapのVolumetric Cloudに使用しました。
複雑な実装だけあって雲が本物そっくりです。
<M_VolumetricCloud_02_Profiles_PaintClouds_Morning>
こっちは前の実装に比べても更に複雑です。
しかし実装の機能毎に整理されているので、こっちの方が理解しやすいかもしれません。
何と雲の一部が稲光していました。
雲の形状も本物そっくりですね。
<M_VolumetricCloud_02_Profiles_PaintClouds_Small>
実装です。
これも実際に読んでみないと難しいかどうか分からないですね。
今週は軽く流しておきます。
雲がないですね。
<M_VolumetricCloud_02_Profiles_Soft>
実装部です。
これは結構単純な実装ですね。
これも雲がないですね。
<M_VolumetricCloud_03_Profiles_Billowy>
実装部です。
最後のMaterialで一番複雑なのかと思ったら一番単純な実装でした。
最後の3つはパッと見る限りでは違いが分かりませんね。
以上です。
8.報酬システムの研究と追加
2022-09-19のBlogを見たら
と書かれていました。
ので今週から報酬システムを今のGameに追加した新しいGameシステムを考える事にします。
8.1 2022-09-19のBlogでまとめたIdeaをもう一回復習する
色々なIdeaが書かれていますが、ごった煮状態です。
以下にIdeaだけを抜き出します。
- ルーレット券
- 報酬にMonsterを配る
- 経験値が増えると使用出来る魔法が増える
- 回復薬
- 金貨
- Monsterに色をつけて黒は攻撃が2倍、白は防御が2倍
ここで回復薬に価値を与える為には、MonsterのHPが戦闘が終わった後も回復しないようにする必要があります。
使用出来る魔法を増やすには魔法をもっと考える必要もあります。
金貨はどんなモノが買えるのかを考える必要があり、考えるのは最後になりそうです。
8.2 今まで作成したMonster Systemに新たなRuleを追加する
まず大前提として戦闘でHPが減ったMonsterは自動では回復しないようにします。
これで、戦闘後に報酬で貰える回復薬に価値が出ます。
次にMPの導入をします。魔術師は魔法を使用するとそれぞれの魔法に応じてMPを消費し、MPが十分にないと魔法を唱える事が出来ません。
これで、戦闘後に報酬で貰える魔法回復薬に価値が出ます。
経験値は、戦闘終了時に貰えます。経験値を積むと魔術師のLevelが上がり、基礎魔力が上がります。更にLevelが上がる事で強力な魔法を覚えていきます。
Monsterはジャンケン属性に色属性を追加します。黒は攻撃力が2倍、白は防御力が2倍になります。
この攻撃力、防御力についてはもう少し検討が必要です。
黒はジャンケンに買った時は攻撃力が3倍、負けた時のダメージも3倍、逆に白はジャンケンに買った時の攻撃力は1倍ですが、ジャンケンに負けた時のダメージも1倍とかの方が面白いかもしれません。
これまでの条件を新たにこのGameに追加する事で、回復薬、魔法回復薬、経験値、そしてMonsterを貰う事が報酬になるはずです。
となると経験値以外を購入出来る金貨も報酬になりえます。
更に、それらをルーレットで購入出来るルーレット券にも価値が出ます。
8.3 報酬画面とPause画面、そして待機画面について
<報酬画面>
戦闘が終了した時にPlayer側が勝利した場合、報酬画面が表示されます。
以下に前に作成した報酬画面を示します。
Monster復活薬は要りませんね。
一体でもMonsterが死んだ場合、それでGame Overですので。
ここにルーレット券を追加します。
<Pause画面>
今まではPlayerが操作する魔術師が何かのItemを保持すると言う事はなかったのでPause画面は存在しませんでした。これからはPause画面が必要になります。
Pause画面内にどんな情報を表示するのかはまだ決めていません。
これは来週考える事にします。
最低でも、魔術師と魔術師が召喚できるMonsterたちのParameterを表示する画面と、魔術師が現在保持しているItemを表示する画面が必要になります。
<待機画面>
ここはPlayerが戦闘以外に何かをするLevelの事です。
最低でも金貨を使用出来る商店と、ルーレット券を使用出来るギャンブル店が必要です。
8.4 来週以降の予定
2週間時間が空いたせいか、報酬システムを追加したGameについてそれなりに構想が固まって来ました。
来週まで更に1週間時間をかけて、このIdeaを熟成させます。
またこのGameも一から作り直す予定ですので、新しいPCでUE5を使用して作成し直します。
8.5 待機画面の作成に使用出来そうなAssetの検証
今までDownloadしたAssetから使用出来そうなのをPickupしておきます。
<Cave>
意外に使えそうです。
これ見て思ったのが、待機画面用のLevelを室内にするのか室外にするのかを決める必要があります。
もし待機画面用のLevelが室内ならこのAssetは有りです。
<City_of_Brass_Enviroment>
こっちはCaveとは逆で待機画面用のLevelが室外ならこのAssetは有りです。
正しこのAsset、建物の作成は出来ません。
以下に示した様に、通路や階段、そして門などしかありません。その辺をどうするのか考える必要があります。
<EnvironmentPack1>
これも待機画面が室内なら有です。
<LowPolyMedievalConstructions>
非常に美しいAssetですが、以下に示した様に室内しかありません。
このAssetを使用する場合、室外は別なAssetで作成して、建物の前でこのAssetがある別なLevelに移動させて建物の内部に入るなどの工夫が必要になります。
<GreenwoodFantasyVillage>
こっちはLowPolyMedievalConstructionsとは逆に建物の中身がありません。
<待機画面用のLevelの作成について>
City_of_Brass_Enviromentで街を作成して、GreenwoodFantasyVillageの建物を使用して、建物のドアの前に立ったらEventでLowPolyMedievalConstructionsで作成した建物の中身のLevelに飛ばすのが一番現実的な案と思います。
9.Anime Renderingの勉強
これも今まで何をやって来たのかすっかり忘れています。
2022-09-19のBlogを読み直して復習します。
9.1 今までの復習
以下の3つをやっていました。
ので今週もその続きをやる事にします。
9.2 Vroidで作成したModelをUEにImportする
<2022-09-19のBlogの復習>
2022-09-19のBlogを見ると以下のMaterial Functionの実装を読んでいる途中でした。
このMaterial Functionの実装は非常に複雑でその中のUV Scrollと言うBlockの実装を読んでいました。
Panに関連していると思われる部分の計算方法が納得出来なくて悩んでいます。
来週、また検討する。と言って終わっています。
<Panningの実装の確認>
確認も何も今みたらこのBlockの名前がUV Scrollになっています。
つまりこれPanningするって事です。
Ben先生のTutorialは探したんですが見つかりませんでした。でもこれ実装とBlockの名前からPanningしているのは間違いないです。
でもその後でCustom Rotator ノードに繋がっているので実際は回転しているんでしょうね。
と言う事でUV Scrollの勉強は終わりにして次に行きます。
<Customized UV 0>
2022-09-19のBlogは結局の所、Customized UV 0にどんな値を送っているのかを確認するためでした。
Customized UV0にPassされる値を計算するための実装は、MF_VrmMToonBase関数内のUV Scrollで作成されていました。
この実装はUVを時間経過に伴って回転させるための機能のようでした。
更に以下のParameterでその回転を調節しているみたいです。
2022-09-19のBlogで最初に開いたMaterial Instanceである以下の3つの内
一番、Materialに近いInstanceであるMI_VrmMToonBaseUnlitOpaqueを見ると
これらのParameterは使用していません(Default値のままでDefault値は3つとも0)。
つまりこの機能は最初のMaterial Instanceでは使用されていないっぽいです。
のでScroll UVの実装を読むのはこれ位にして次に行きます。
<Outline( WorldPositionは scale(-1)なので注意)>
Customized UV0の値を指定するNodeの前のNodeです。BUseOutlineOnlyノードです。
当然、Outlineのみを使用する実装の方が簡単なのでそちらを追います。
Outline( WorldPositionは scale(-1)なので注意)に繋がっていました。
こっちはUV Scrollと比較するとかなり複雑です。
PostprocessのMaterialならOutlineの作成方法についてはそれなりに理解してるんですが、こっちは普通のMaterialです。どうやってOutlineを出しているんでしょうか?
とても興味があります。
勉強していきましょう。
まず最初のCommentであるWorld PositionはScale(-1)なので注意。の意味が分かりません。
まあ、分かる所から読んでいきましょう。
Make Material Attributes ノードです。
これのBase Color、Metallic、Specular、そしてRoughnessの値は
0です。
Outlineだけ表示するのだから、まあ納得です。でもそれだとOutlineは白で表現するんでしょうか?
Emissive Colorです。
まずDivideしています。
何を何で割っているんでしょうか?
まずBを追います。
以下の実装がありました。
1で割っています。ほとんど機種の場合は。
何かの要素を考慮しているのは分かりますが、それ以上は分かりません。でも1で割っている時が大半なので分からなくても大筋を追うのには問題ないでしょう。
今度はAを追います。
Lerpノードです。
AlphaとBの値は以下のOutlineColorScaleノードで決定されています。
OutlineColorScaleノードのAlpha値がLerpのAlpha値、そしてRGB値がB値になっています。
Aの値はかなり複雑です。
一つ一つ追っていきます。
まずMultiplyノードです。
このMultiplyノードのBの値は先程のOutlineColorScaleノードのRGB値でした。
つまりLerpノードのAとBは、BがOutlineColorScaleノードのRGB値であるのに対して、Aは何かxOutlineColorScaleノードのRGB値でした。
次のNodeです。
又、Multiplyノードです。
今度は実装が簡単なAの方を追います。
MF_LinearColorConvert関数の実装を見ていないので簡単には言えませんが、Mtoon_OutlineColorノードの色をパスしているだけみたいです。
このMultiplyノードのBの方ですが、別なBlockに飛んでずっとそのBlock内で計算されています。これはパッと見で判断すると光の強さや光の色を計算している実装のようです。今週はこの実装を追うのは止めておきます。
この事から推測するとOutline BlockではEmissive Colorには単なる色をパスしているだけです。
OpacityとOpacity Maskです。
Minノードに繋がっていました。
MinノードはAとBの内低い値をパスするはずです。
MinノードのBは先程のMtoon_OutlineColorのAlphaに繋がっていました。
MinノードのAの方は更にMinノードに繋がっていました。
このMinノードのBの値ですが、以下の実装に繋がっています。
Ray Traceの場合は値が0になるように設定されています。そしてBoxの解説にRay Traceには輪郭なし。と書かれています。
と言う事は、このOpacityの値でOutlineの太さを調節していると言う事です。
今週のVroidのMaterialの調査はここまでにします。
久しぶりにMaterialを読んだので結構疲れました。
流石にこのLevelのMaterialは全部を理解するのは無理だと思いますが、出来るだけはやってみます。
9.3 公式のDocumentのStylized Rendering [9]の勉強
2週間空いたので今まで何を勉強したのか忘れてしまったので、今週は今まで勉強した内容を復習します。
公式のDocumentであるStylized Rendering [9]のStylized Rendering Materialsを読んだ感想をまとめています。
この回、凄い重要な事を言おうとしてたんですが、今読み直すと言いたい事が上手くまとまっていません。
のでここでまとめ直します。
Stylized Renderingにおいては絵を3Dで再現するのが目的です。
なのでどの絵を再現するのかが大切なんです。ゴッホやピカソの絵を3Dで再現したら、みんな「オオー。」と思います。しかしその辺の一寸絵の上手いおばさんが描いたような絵を3Dで再現したって誰も感動しません。
なのでどの絵を3Dで再現するんだ。と言う事を最初に明確にする必要があるんです。
それをしなかったからこのStylized Rendering [9]のProjectは正当な評価を得る事が出来ずに、結果として中止になってしまったんだ。と言いたかったんです。
公式のDocumentであるStylized Rendering [9]のStylized Rendering Landscapeを読んだ感想が書かれています。
Landscape用のMaterialの実装についてですが、結構詳しく勉強しています。
Layerについてとか、
以下に示した様なPaintした感じのLayerをどうやって実装するかなどがそれなりに細かくまとめられています。
ここで勉強していないのが、以下に示したLandscape Splinesです。
これは後で勉強すると書いています。
公式のDocumentであるStylized Rendering [9]のStylized Rendering Post Processingを勉強しています。
Postprocessに直にあるParameterはPostprocess用のMaterial内に実装するより最適化されているので、ParameterがあるのはMaterial内に実装するな。と書かれていました。
これは非常にためになる教えで、勉強した事を直ぐに忘れてる私でも、これだけはしっかり覚えています。
Landscape用のMaterialの実装についてOutlineとPaper Effectについてまとめてあります。
OutlineはPPLineDrawingでもPostprocessで作成しています。
元々、現実にはOutlineは存在しません。しかし人間が3D空間を2Dとして認識し易くするために脳が勝手に加えたのがOutlineです。
人間がどうやって空間を認識しているのかを模擬してOutlineを生成するのなら、OutlineはPostprocessで生成するのが自然と言う事です。
でもVroidは輪郭線はModelのMaterialで作成していますね。
これは面白い点で、その理由に興味があります。
この週から実際のMaterialの実装を見て勉強しています。
この週は、以下に示した木のMaterialの実装を勉強しています。
実装を見て思ったより簡単で全部理解出来たと喜んでいます。
いや、大切なのはそこじゃないだろ。って、その時の自分に言いたいです。
この実装で大切なのは、なんでこの木が絵本に描かれている木のように見えるかです。
例えば、木の幹の部分にはOutlineがはっきり見えます。
更に荒く絵具かペンキで塗ったような部分がはっきり見えます。この部分をどうやって作成したのかについて調べるのが大切なんです。
そしてそれを記録しておく必要があります。
うーん。
この辺に関してはもう一回勉強し直す必要がありますね。
この週は、先週の木のMaterialの実装の続きを解説しています。
木の幹の端の部分には、ペンキで塗ったような部分が出ないようにするための実装方法が詳しく解説されています。
これ自体は凄く重要ですね。
以下のObjectに使用されているMaterialの実装についてです。
以下の2つのMaterialで実装されています。
この週は上のMaterialの実装を見ています。
これも実装を単に読んで、理解出来たうれしいで終わっています。
この実装、真ん中が暗い緑で、端は黄色んです。更に真ん中の暗い緑の部分には黒い点々があります。
これらをどうやって実装しているのかを調べるのが大切でした。
まあ、それらについてはこれからやります。
Materialを一個見て終りにしていたと思ったらもう一個のMaterialも見ていました。
ここではBlend ModeをModulateにセットしたら1つまり白が透明になる事を発見しています。
これはすっかり忘れていました。
結構、大切な発見でした。
以下の柵のMaterialについて勉強しています。
この柵のMaterialには以下の2つが使用されていますが、この週は上のMaterialの実装だけみています。
ここで実際のMaterialの実装をノードを一個一個、遡って説明しています。
しかし後から読むと何を言っているのか良く分かりません。
まずBlogを読んだだけなのでこのMaterialの実装の全体像が分かりません。
まあ、それはこの部分を読むときは、このMaterialを開いて見ながら読めば良いだけかもしれませんが。
この柵に使用されている木には年輪の後がはっきりと見えます。傷も見えます。これらの特徴がこの柵を柵らしくしている訳です。
この辺をどうやって作成しているのかについての検証があると良かったと思いました。
以下の部分のMaterialの実装について勉強するのかと思ったら
実装の仕方は前の週に勉強したやつと同じだからやりません。とありました。
それだと何故、柵の木の年輪が木の向きに対して正しく出ているのかの理由が分かりません。
これは今度勉強する時に調査します。
それでこの週は何をやったのかと言うと以下のMeshのMaterialについて勉強しました。
実はこのMesh色々な意味で面白く、このMeshに注目した事はGood Jobです。
まずこのMesh、Foliageに使用されています。
次にこのMesh、常にカメラに向かって正面を向いています。
ただしこの週はこのMeshのMaterialの通常の部分を読むので時間を費やしてしまい、この常にCameraを向いている部分の実装は読む事は出来ませんでした。
常にCameraを向いている部分の実装を解読しています。
文字通り解読という感じで、知らないNodeの機能を一々実験して確認して理解しながら、読んでいます。
読み直してかなり勉強になりました。
正し、一寸しか進んでいません。
残りの解読は次の週に持ち越しとなりました。
一寸しか進んでいないとはいえ、この週の検証は、後から読んでもかなり勉強になりました。
自分のBlogに自分で評価するのもおかしいですが、検証する話は読んでいてかなり面白かったです。
前の週の続きです。
しかしそれならWorld Position ノードの値をそのまま使用したら良いのではないのか。またObject Positionノードの値を代わりに使用した場合はどうなのか。などの疑問が出て来ました。
この週はそれについて検証しています。
更にこの実装ではTexCoord[2]とTexCoord[3]が使用されていますが、それがTexCoord[0]とどう違うのかについての検証も行っています。
結論に関してですが、全く覚えていなかったんですが、Object Positionノードを使用した場合が最も良いと言う結果になりました。
今、読み直しても驚きです。
しかしその結論に至るまでの検証がかなりしっかりしていて、自分で書いているのに読んでいて納得してしまいました。
又、TexCoord[2]とTexCoord[3]とTexCoord[0]の違いについても検証しています。
ある実験を通してこの3つの違いを比較して、全く差がない事を示しています。
読んでいて非常に勉強になりました。
他のFoliageのMaterialについても勉強しようとしたのですが、使用されているMaterialは全部同じでした。
ここで、同じMaterialを使用していたとしても、全てのFoliageに使用されているMeshが全く同じ挙動をするのか、例えば全部のMeshがカメラに向かって正対するのか、を確認して、もし違うならそれがどこから生じているのかを調査すべきですが、この時は、そんな事は思いもしませんでした。
それで急遽、城に使用されている以下のMeshのMaterialについて勉強する事にしました。
Materialの実装を読んで終わりにしています。
<復習した感想>
結構だらだらやっていたので、大した成果が出ていないと思っていましたが、読み直してみると、思っていたのより3倍位しっかりやっていました。
自分で言うのもあれですが、非常に優秀だと思いました。
読み直して一番勉強になるのが検証の時です。仮説の立て方から、検証方法の設定、実験結果、それに対しての考察など読み応えがありました。
それに対してMaterialを読んで理解しました。という話はつまらなかったです。
まずNodeを一個一個紹介していますが、これだけだと全体像が見えないので全体としてどんな実装なのか分かりません。そしてそのせいで実装がどんな目的を持って組まれているのか、どんな機能を持っているのかも不明です。
その結果、話が断片的で何を目的にしているのかが不明瞭になっています。
最後にこの実装が何をやっているのか理解しました。と書かれていても読んだこっちは何も理解出来ないので、読んでいてストレスも溜まります。
そうは言ってもこれも必要な工程ですので、まあこの部分に関しては、Blogの書き方をもう少し工夫する必要はあるかもしれません。
9.4 法線転写をUEで実装する方法を検証
Historiaさんの[UE4] 動的法線転写について[10]を勉強します。
今週は、実践の準備とNormal 出力の部分を勉強します。
<準備>
Tangent Space NormalのCheckを外します。
これについては知っています。
確かUnreal Sensei氏のHow to Blend Objects with Your Landscape - UE4 Runtime Virtual Texturing (RVT) Tutorial [11]で勉強したはずです。
MainノードのNormalはDefaultではTangent Spaceで管理されているのでWorld Spaceの値をパスする時は、このCheckを外すか
を使用する必要があります。
Tangent Space Normalの解説を見ると以下の様に書かれていました。
私が理解しているのはここまでで、この変換に伴うsRGBからRGBの変換方法については良く分かりません。
通常のNormal MapはsRGBは使用していません。
それに対してWorld Spaceで通常使用されているTextureはsRGBを使用しています。
他にもMain ノードのNormalにWorld Spaceの座標軸の値をPassする時に気を付ける必要がある事があるかもしれません。
一寸調べてみます。
うーん。調べたけどあんまり参考になるものは見つかりませんでした。
今週の勉強はこの変換がMainではないので先に進みます。
<Normal出力>
まずはTutorialに書かれている通りに実装しました。
MF_ Normal Weight Modifierに関してはまだ実装が良く分かっていないので以下のMFで代用しています。
まずVertexNormalWSのみだったら今までと同じNormalが適用されるはずです。
試してみます。
上記の実装でDirectional Lightを以下に示した条件で固定しました。
結果です。
今度はNormalを外して見ました。
結果です。
全く同じです。
ここまでは理解出来ました。
その次の部分です。
ここが良く分かりません。
理屈で言えば、この部分に別に作成した球のNormalをパスするはずです。
ParameterであるNormal Modifier Parameterがそれを担当しているんでしょうか?
もしそうならなんでその値をAbsolute World Positionから引くのか分かりません。
しかもNormal Modifier ParameterはVector4です。Vector3じゃないんです。
World PositionってVector 3じゃなかったけ?
いや、quaternionだからVector 4なのか?
でもquaternionだったら、最後の値はVectorだったら1でPositionだったら0みたいに使用してたはず。それを引いたらオカシクなる気がします。
うーん。
良く分からん。と思っていたらその下に解説されていました。
はい。
分かりました。
私は、前に法線転写を勉強した 夏森轄(なつもりかつ)先生の【Blender】 セルルック講座 ~ノード、輪郭線、法線転写、RGB分離~[12]のやり方しか知らなかったので球の表面のNormalをパスするものだと思っていました。
確かに球の中心をパスしてそこからNormal Vectorを計算しても結果は同じです。というかこっちの方が精錬されています。
でもそれだと、その後にNormalizeしないといけないんじゃ、と思ったらしてました。
これ勝手に頭の中でClampしてると思っていました。自分で作成した実装でもしっかりNormalizeノードを使用していましたが、何故か頭の中ではClampノードを繋げた気になっていました。
こっちのNormalは正規化の方のNormalで法線のNormalとは違います。
日本語だと、法線を正規化します。で終わりですが、英語だとNormalをNormalします。って一見、変な言葉になります。
Vector3 とVector4については、良く分かりません。
もう時間が無いので今週はここまでとします。
10.まとめと感想
2週間ぶりに勉強を再開したので、あんまり深く集中は出来ませんでした。結構考えないと解けない部分はSkipしています。
あんまり無理はしないでやって行こうと思います。
12.参照(Reference)
[1] CGHOW. (2022, June 12). Unreal Engine 5 Niagara Beginner Tutorial - UE5 Niagara Starter Course! [Video]. YouTube. https://www.youtube.com/watch?v=NcJ1ZP7tFUk
[2] Stylized Rendering Post Processing. (n.d.). Unreal Engine 4.27 Documentation. https://docs.unrealengine.com/4.27/en-US/Resources/Showcases/Stylized/PostProcessing/
[3] CGcompo カメラの話をしよう!・番外編映像で見るあの現象?(n.d.). http://cgcompo.blog134.fc2.com/blog-entry-56.html
[4] Bloom. (n.d.). https://docs.unrealengine.com/5.0/en-US/bloom-in-unreal-engine/
[5] Ben Cloward. (2022, August 11). Bloom & Glow Post Process Effect - Shader Graph Basics - Episode 56 [Video]. https://www.youtube.com/watch?v=kRIUsIO16yI
[6] gameDev Outpost. (2020, September 29). UE4 - Cascade to Niagara Converter [Video]. YouTube. https://www.youtube.com/watch?v=Dy_oJ23UH1A
[7] Klaus. (2022, July 6). How To Create An Open World Snow Landscape | Unreal Engine 5 Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=ej2b-zWoYiM
[8] pinkpocketTV. (2022, January 14). Unreal Engine 5 Beginner Tutorial | Sky And Clouds [Video]. YouTube. https://www.youtube.com/watch?v=lYZoR3ZLD-o
[9] Stylized Rendering. (n.d.). Unreal Engine 4.27 Documentation. https://docs.unrealengine.com/4.27/en-US/Resources/Showcases/Stylized/
[10] 株式会社ヒストリア. (2022, June 30). [UE4] 動的法線転写について. Historia Inc - 株式会社ヒストリア. https://historia.co.jp/archives/11921/
[11] Unreal Sensei. (2021, April 23). How to Blend Objects with Your Landscape - UE4 Runtime Virtual Texturing (RVT) Tutorial. YouTube. https://www.youtube.com/watch?v=xYuIDFzKaF4
[12] 夏森轄(なつもり かつ). (2022, May 21). 【Blender】セルルック講座 ~ノード、輪郭線、法線転写、RGB分離~ [Video]. YouTube. https://www.youtube.com/watch?v=e1tFq5OoSY0