みつまめ杏仁

アンリアルエンジン(UE4)でGUIを作るためにゴニョゴニョしてます。UIデザイナーの皆様の助けになれば幸いです。

ゆらゆらするマテリアル

 なんとか第11回ぷちコンに応募することができました。今回はギリギリまでかかってしまってキツかった。今使ってるPCではパワー不足だということが思い知らされた感があって寂しくはあるけど、あきらめた表現がたくさんあったのもまた事実で、もう買い替えをためらっている場合ではないのだと強く思った次第です。なんてことを書いてますが、かなりの部分は自分の頭の悪さだったりして・・・すみませんマシンパワーのせいにしました。てへぺろ

 実際シェーダーコンパイルに時間がかかり過ぎたのと、半透明に落とす影の調整に時間がかかり過ぎました。

 

 応募した動画を貼っておきます。


【第11回UE4ぷちコン応募作品】 ちいさなうきわ。

 

 動画編集はいまだに不慣れなので、編集に時間を掛けられないと判断。実際にプレイしたキャプチャをそのままノーカットでアップしました。さすがに前後の黒い余白時間をカットするくらいはしてますが、ほんとそれだけです。

 なので、画面遷移やUI表示は職業柄それなりに頑張って作ったつもりです。

 

まぁそんなこんなで、ブログの更新が止まっていたわけですが、久しぶりに書こうと思います。ネタはぷちコンからで、仕組み自体は過去記事でも紹介したものの応用になります。

f:id:hiyokosabrey:20190403223820g:plain

ゴールした時の誉め言葉表示です。

この水の屈折のような表現。ディストーション(歪み)エフェクトとも呼ばれるようですがマテリアルで簡単に作ることができます。

 

 まずは ゆらゆら させるためにはランダムな2D素材が必要です。Noise ノードを使うとテクスチャが不要にできるのですが、やっぱり滑らかさが欲しいので今回 Photoshopを使ってテクスチャを用意するところから説明していこうと思います。

 

あの有名なフィルタを攻略する

ランダムといっても大きなテクスチャはそのままテクスチャメモリの負担となるのでなるべく小さく、かつタイリングできるように作ります。

そこで登場するのがおなじみのフィルター「雲模様1

f:id:hiyokosabrey:20190403230040p:plain

ちなみに↑これは、 512x512 で作成したものを 50%に縮小した状態です。

このフィルターは、2のべき乗で作成すると上下左右がつながったシームレスな状態になります。

フィルター > その他 > スクロール を使うとつながりが確認できます。

f:id:hiyokosabrey:20190403230611p:plain

2のべき乗というのは、2を何乗かした値で、2、4、8、16、32、64、128、256、512、1024・・・という数字です。縦横をこの数の解像度にすると見事シームレスなテクスチャの完成です。ちなみに他の解像度で雲模様を作ると、つながらなくなります。

f:id:hiyokosabrey:20190403231252p:plain

これは 250x250で作成してスクロールさせた状態。よく見るとつながっていないのが判ります。下の図はニアレストネイバーで400%に拡大した状態。

f:id:hiyokosabrey:20190403231641p:plain

 

これが「雲模様1」の特徴です。

ちなみに、この「雲模様1」は、フィルタを掛ける際に、描画色背景色の2色を使って作られます。なので、今回のようにモノクロでしっかりと階調差を出したい場合は、直前に D キーを押して、白黒にしておくのをお勧めします。

f:id:hiyokosabrey:20190403232223p:plain

 

あと、注意したいのが「解像度」です。雲模様フィルタは、密度の調整ができないので、解像度でコントロールすることになります。

f:id:hiyokosabrey:20190403233518p:plain

ヒストグラムで比較するとさらに差が分かりやすくなります。

という訳で濃淡の散らばり具合を考慮して今回は 1024x1024で進めます。

 

 

素のままだとノイジーなので、ここから加工していきます。

水の揺らめきなので、もっと滑らかな感じが理想。

ボカしたり、明るさの中間値を掛けると速いのですが、この状態でかけると、せっかくシームレスにしたのが台無しになってしまいます。フィルタはドキュメントの上下左右がつながっているなんて気にしないからです。

そこで、面倒ですが一旦 手動でシームレスな状態にします。

 

まず 新規ドキュメントを 1024x1024で作成して「雲模様1」を使用します。

f:id:hiyokosabrey:20190403235506p:plain

この状態で、全選択(Ctrl+A) からの コピー(Ctrl+C)までを実行。クリップボードに入れた状態で、カンバスサイズを変更します。

f:id:hiyokosabrey:20190403235842p:plain

するとこうなります。↓

f:id:hiyokosabrey:20190404000004p:plain

ここからクリップボードに入れたのをペーストしていくのですが、ちょっとだけ時短できるぷちテクニックを紹介しておきます。選択範囲を作ったペースト方法です。

まず左上に貼り付けたい場合、マウスを下図のように外に向かって適当に動かします。

f:id:hiyokosabrey:20190404001021p:plain

すると、

このような選択範囲になるので、ここでペースト(Ctrl+V)します。

f:id:hiyokosabrey:20190404001305g:plain

これを4隅で行います。

f:id:hiyokosabrey:20190404001717p:plain

上下左右も同じ要領で適当に選択範囲を作って、

f:id:hiyokosabrey:20190404203509g:plain

ペースト&ペースト。

f:id:hiyokosabrey:20190404203731p:plain

 

多少ずれても中央揃え機能を使えばビシっと隙間なく並びます。

f:id:hiyokosabrey:20190404002452p:plain

アナログな手操作を確実でブレのない結果にするのが大好きなので紹介しましたが、この時点でピクセルがずれていなければどんな方法でもOK。Photoshopは作業中の表示倍率がキリの悪いときはかなりの確率でピクセルスナップが甘くなるので、こういった倍率に関係なく確実な操作は重要です。

 

 この9枚がビシっと並んでいる状態でようやくフィルタを掛けます。

せっかくタイリングするように並べたので、ランダム系のフィルタはNG。あくまでもピクセルに合わせて均等に掛かるタイプのフィルタを使います。

 

今回は、明るさの中間値 を掛けてから ぼかし(ガウス)を掛けました。

f:id:hiyokosabrey:20190404003607p:plain

ここで解像度を落とします。

最終的に 256x256 のテクスチャにしたいので、256x3 = 768

768x768 に縮小します。もちろん縮小されるときにもピクセルにフィルタが掛かります。

f:id:hiyokosabrey:20190404004304p:plain

ここで、カンバスサイズを使って 周りの 8枚をカット、中央の1枚だけにします。

f:id:hiyokosabrey:20190404004525p:plain

シームレスになっているかどうか、「スクロール」を使って確認してみましょう。

f:id:hiyokosabrey:20190404004917p:plain

つなぎ目が見えなければ完璧です。

 

これをリニアなグレースケールテクスチャとして、UE4に持っていきたいので、ドキュメントをグレースケールに変更します。イメージ > モード > グレースケール を選択。

f:id:hiyokosabrey:20190404005241p:plain

 

おそらくポップアップが表示されるので、カラー情報は破棄します。

f:id:hiyokosabrey:20190404005606p:plain

 

チャンネルが 「グレー」だけになったらOK。

f:id:hiyokosabrey:20190404005812p:plain

 

 あとは、これをTarga フォーマット(拡張子 .tga)で書き出せば UE4 にインポートできます。

 PNG形式はチャンネルが一つだけ(SingleChannel)という仕様を持っていないため、PNGで保存した際にRGBA32ビットに戻されてしまいます。なのでグレースケールテクスチャの場合は、PNGは使っちゃダメです。チャンネルが一つということはそれだけテクスチャのメモリが1/4になるということで節約になります。

 

今回よりランダム感を出したいので、もう一枚用意します。

 

f:id:hiyokosabrey:20190404205000p:plain f:id:hiyokosabrey:20190404205011p:plain

 ↑ Web用にPNG形式になってますが右クリックしてDLしてもらってOK

この2枚をUE4にインポートします。 

 

いざUE4

 インポート設定はこんな感じです。

f:id:hiyokosabrey:20190404213401p:plain

今回 sRGB のチェックは外しているので、リニアグレースケールテクスチャとして扱うという意味になります。これはPhotoshopでのカラー設定によって書き出す際の補正があるか無いかで決めます。特に何も設定をいじっていなければsRGBにチェックが付いていると思いますが、今回は特に問題ありません。

 

 ちょうど一年前の記事ですが一応過去記事を貼っておきます。

limesode.hatenablog.com

これを使ってマテリアルを作ります。

Create Material して中にテクスチャをドロップします。

f:id:hiyokosabrey:20190404220627p:plain

 

あ、揺らすためのテクスチャを忘れていました。せっかくなんで。

 

f:id:hiyokosabrey:20190404223919p:plain

 

これをつなぐとこうなります。

f:id:hiyokosabrey:20190404223544p:plain

 速度は左のPannerノード で調整しつつ、揺れ幅というか揺れの度合いは、TexCoordノードで調整します。

参考までに今回の値。

f:id:hiyokosabrey:20190404224930p:plain

さらに適応する量は、真ん中のScalarParameterValueで調整します。このパラメータノードは、Widgetブループリントから値を受け取って反映する役割のノードです。

雲模様のコントラストや濃淡によりますが、今回の値はこんな感じ。

まず、Amount: 0.15

f:id:hiyokosabrey:20190404225807g:plain

かなり揺らめいてます。

次は Amount: 0.1 だいぶ落ち着いてきました。

f:id:hiyokosabrey:20190404230015g:plain

Amount: 0.025

f:id:hiyokosabrey:20190404230110g:plain

もちろん 0 にすると静止します。

 

ちなみに 0.5 はまったく読めません。

f:id:hiyokosabrey:20190404230555g:plain

これだけで一つミニゲームが作れそうです。

なんて書いてあるでしょうか?さぁ早押しでお答えください! みたいな。

ただあまり揺らすと端の切れてる部分が目につくようになるので注意が必要です。

 

真ん中上の、Subtract(引き算)ノードでは、グレースケールテクスチャからやってきた値を調整しています。

f:id:hiyokosabrey:20190404232821p:plain
ここでいう調整というのは、0~1 という範囲を、幅を変えずに -0.5~+0.5 にすることです。テクスチャの黒は 0.0、白は 1.0なので、このまま足し算して使うと、揺れはしますがプラスの方向にしか揺れないので、結果的にテクスチャ全体がプラス側に寄ってしまいます。それをプラスとマイナスの距離が均等になるようにしているのです。

 

マテリアルはこれで完成です。

 

ちなみに、↓こんなテクスチャだと。

f:id:hiyokosabrey:20190404233848p:plain

こんな感じにできます。

f:id:hiyokosabrey:20190404234059g:plain



 

Widgetでフェード

まずキャンバスに、Imageを配置します。

f:id:hiyokosabrey:20190404234621p:plain

配置したら、Detailタブから、Appearance > Brush > Image の部分に用意したマテリアルをセットします。

f:id:hiyokosabrey:20190405000649p:plain

 

さらにもう一つ、Imageをキャンバスに追加します。

f:id:hiyokosabrey:20190405003508p:plain

これは描画しないのでVisibilityを Collapseにしておきます。

f:id:hiyokosabrey:20190405003342p:plain

ここでアニメーションを用意します。

 

アニメーションさせるのは2つ。

一つは、Collapseにした方の Pivot。もう一つは、表示する方の Render Opacity

f:id:hiyokosabrey:20190405010528p:plain



つぎにブループリントを用意していきます。

 

初めから置かれているイベントノードをそのまま利用することにします。

Event Pre Constructから。

f:id:hiyokosabrey:20190405010744p:plain

Image にセットしているマテリアル(Static)をいじるには、マテリアルを、Material Instance Dynamic型 にする必要があって、Get Dynamic Material ノードを使うと型変換しつつ、置き換えてくれます。この変換処理を頻繁に行いたくなくて、一度きりで十分なので、ReturnValueから Promote to Variable(変数に昇格)させています。

 

Event Construct。

f:id:hiyokosabrey:20190405011947p:plain

アニメーションの再生が終わったら、後片付けしてViewportから姿を消します。後片付けといっても変数を空にしてマテリアルへの参照関係を解消するだけです。

 

最後に、Event Tick。

f:id:hiyokosabrey:20190405013151p:plain

 

Widgetは完成です。

 

テスト用の新規レベルを作ってテストしてみましょう。

レベルブループリントに Create Widget ノード と Add to Viewport ノードをつなぎます。繰り返し確認したいので、Inputノードで何度でもWidgetを呼び出せるようにします。とりあえずスペースキー。

f:id:hiyokosabrey:20190405013900p:plain

 

再生してみます。

f:id:hiyokosabrey:20190405014037g:plain

いい感じです。青い背景を置いたので、マテリアルのBlend Mode は Additive に変更しています。

 

 

シームレステクスチャのパターンを工夫したり、タイリングや揺れ加減を調整したり、まだまだ応用できそうです。

 

ではでは

今回はこの辺で

ステキなゆれゆれマテリアルライフを!