なんとか第11回ぷちコンに応募することができました。今回はギリギリまでかかってしまってキツかった。今使ってるPCではパワー不足だということが思い知らされた感があって寂しくはあるけど、あきらめた表現がたくさんあったのもまた事実で、もう買い替えをためらっている場合ではないのだと強く思った次第です。なんてことを書いてますが、かなりの部分は自分の頭の悪さだったりして・・・すみませんマシンパワーのせいにしました。てへぺろ。
実際シェーダーコンパイルに時間がかかり過ぎたのと、半透明に落とす影の調整に時間がかかり過ぎました。
応募した動画を貼っておきます。
動画編集はいまだに不慣れなので、編集に時間を掛けられないと判断。実際にプレイしたキャプチャをそのままノーカットでアップしました。さすがに前後の黒い余白時間をカットするくらいはしてますが、ほんとそれだけです。
なので、画面遷移やUI表示は職業柄それなりに頑張って作ったつもりです。
まぁそんなこんなで、ブログの更新が止まっていたわけですが、久しぶりに書こうと思います。ネタはぷちコンからで、仕組み自体は過去記事でも紹介したものの応用になります。
ゴールした時の誉め言葉表示です。
この水の屈折のような表現。ディストーション(歪み)エフェクトとも呼ばれるようですがマテリアルで簡単に作ることができます。
まずは ゆらゆら させるためにはランダムな2D素材が必要です。Noise ノードを使うとテクスチャが不要にできるのですが、やっぱり滑らかさが欲しいので今回 Photoshopを使ってテクスチャを用意するところから説明していこうと思います。
あの有名なフィルタを攻略する
ランダムといっても大きなテクスチャはそのままテクスチャメモリの負担となるのでなるべく小さく、かつタイリングできるように作ります。
そこで登場するのがおなじみのフィルター「雲模様1」
ちなみに↑これは、 512x512 で作成したものを 50%に縮小した状態です。
このフィルターは、2のべき乗で作成すると上下左右がつながったシームレスな状態になります。
フィルター > その他 > スクロール を使うとつながりが確認できます。
2のべき乗というのは、2を何乗かした値で、2、4、8、16、32、64、128、256、512、1024・・・という数字です。縦横をこの数の解像度にすると見事シームレスなテクスチャの完成です。ちなみに他の解像度で雲模様を作ると、つながらなくなります。
これは 250x250で作成してスクロールさせた状態。よく見るとつながっていないのが判ります。下の図はニアレストネイバーで400%に拡大した状態。
これが「雲模様1」の特徴です。
ちなみに、この「雲模様1」は、フィルタを掛ける際に、描画色と背景色の2色を使って作られます。なので、今回のようにモノクロでしっかりと階調差を出したい場合は、直前に D キーを押して、白黒にしておくのをお勧めします。
あと、注意したいのが「解像度」です。雲模様フィルタは、密度の調整ができないので、解像度でコントロールすることになります。
ヒストグラムで比較するとさらに差が分かりやすくなります。
という訳で濃淡の散らばり具合を考慮して今回は 1024x1024で進めます。
素のままだとノイジーなので、ここから加工していきます。
水の揺らめきなので、もっと滑らかな感じが理想。
ボカしたり、明るさの中間値を掛けると速いのですが、この状態でかけると、せっかくシームレスにしたのが台無しになってしまいます。フィルタはドキュメントの上下左右がつながっているなんて気にしないからです。
そこで、面倒ですが一旦 手動でシームレスな状態にします。
まず 新規ドキュメントを 1024x1024で作成して「雲模様1」を使用します。
この状態で、全選択(Ctrl+A) からの コピー(Ctrl+C)までを実行。クリップボードに入れた状態で、カンバスサイズを変更します。
するとこうなります。↓
ここからクリップボードに入れたのをペーストしていくのですが、ちょっとだけ時短できるぷちテクニックを紹介しておきます。選択範囲を作ったペースト方法です。
まず左上に貼り付けたい場合、マウスを下図のように外に向かって適当に動かします。
すると、
このような選択範囲になるので、ここでペースト(Ctrl+V)します。
これを4隅で行います。
上下左右も同じ要領で適当に選択範囲を作って、
ペースト&ペースト。
多少ずれても中央揃え機能を使えばビシっと隙間なく並びます。
アナログな手操作を確実でブレのない結果にするのが大好きなので紹介しましたが、この時点でピクセルがずれていなければどんな方法でもOK。Photoshopは作業中の表示倍率がキリの悪いときはかなりの確率でピクセルスナップが甘くなるので、こういった倍率に関係なく確実な操作は重要です。
この9枚がビシっと並んでいる状態でようやくフィルタを掛けます。
せっかくタイリングするように並べたので、ランダム系のフィルタはNG。あくまでもピクセルに合わせて均等に掛かるタイプのフィルタを使います。
今回は、明るさの中間値 を掛けてから ぼかし(ガウス)を掛けました。
ここで解像度を落とします。
最終的に 256x256 のテクスチャにしたいので、256x3 = 768
768x768 に縮小します。もちろん縮小されるときにもピクセルにフィルタが掛かります。
ここで、カンバスサイズを使って 周りの 8枚をカット、中央の1枚だけにします。
シームレスになっているかどうか、「スクロール」を使って確認してみましょう。
つなぎ目が見えなければ完璧です。
これをリニアなグレースケールテクスチャとして、UE4に持っていきたいので、ドキュメントをグレースケールに変更します。イメージ > モード > グレースケール を選択。
おそらくポップアップが表示されるので、カラー情報は破棄します。
チャンネルが 「グレー」だけになったらOK。
あとは、これをTarga フォーマット(拡張子 .tga)で書き出せば UE4 にインポートできます。
PNG形式はチャンネルが一つだけ(SingleChannel)という仕様を持っていないため、PNGで保存した際にRGBA32ビットに戻されてしまいます。なのでグレースケールテクスチャの場合は、PNGは使っちゃダメです。チャンネルが一つということはそれだけテクスチャのメモリが1/4になるということで節約になります。
今回よりランダム感を出したいので、もう一枚用意します。
↑ Web用にPNG形式になってますが右クリックしてDLしてもらってOK
この2枚をUE4にインポートします。
いざUE4へ
インポート設定はこんな感じです。
今回 sRGB のチェックは外しているので、リニアグレースケールテクスチャとして扱うという意味になります。これはPhotoshopでのカラー設定によって書き出す際の補正があるか無いかで決めます。特に何も設定をいじっていなければsRGBにチェックが付いていると思いますが、今回は特に問題ありません。
ちょうど一年前の記事ですが一応過去記事を貼っておきます。
これを使ってマテリアルを作ります。
Create Material して中にテクスチャをドロップします。
あ、揺らすためのテクスチャを忘れていました。せっかくなんで。
これをつなぐとこうなります。
速度は左のPannerノード で調整しつつ、揺れ幅というか揺れの度合いは、TexCoordノードで調整します。
参考までに今回の値。
さらに適応する量は、真ん中のScalarParameterValueで調整します。このパラメータノードは、Widgetブループリントから値を受け取って反映する役割のノードです。
雲模様のコントラストや濃淡によりますが、今回の値はこんな感じ。
まず、Amount: 0.15
かなり揺らめいてます。
次は Amount: 0.1 だいぶ落ち着いてきました。
Amount: 0.025
もちろん 0 にすると静止します。
ちなみに 0.5 はまったく読めません。
これだけで一つミニゲームが作れそうです。
なんて書いてあるでしょうか?さぁ早押しでお答えください! みたいな。
ただあまり揺らすと端の切れてる部分が目につくようになるので注意が必要です。
真ん中上の、Subtract(引き算)ノードでは、グレースケールテクスチャからやってきた値を調整しています。
ここでいう調整というのは、0~1 という範囲を、幅を変えずに -0.5~+0.5 にすることです。テクスチャの黒は 0.0、白は 1.0なので、このまま足し算して使うと、揺れはしますがプラスの方向にしか揺れないので、結果的にテクスチャ全体がプラス側に寄ってしまいます。それをプラスとマイナスの距離が均等になるようにしているのです。
マテリアルはこれで完成です。
ちなみに、↓こんなテクスチャだと。
こんな感じにできます。
Widgetでフェード
まずキャンバスに、Imageを配置します。
配置したら、Detailタブから、Appearance > Brush > Image の部分に用意したマテリアルをセットします。
さらにもう一つ、Imageをキャンバスに追加します。
これは描画しないのでVisibilityを Collapseにしておきます。
ここでアニメーションを用意します。
アニメーションさせるのは2つ。
一つは、Collapseにした方の Pivot。もう一つは、表示する方の Render Opacity 。
つぎにブループリントを用意していきます。
初めから置かれているイベントノードをそのまま利用することにします。
Event Pre Constructから。
Image にセットしているマテリアル(Static)をいじるには、マテリアルを、Material Instance Dynamic型 にする必要があって、Get Dynamic Material ノードを使うと型変換しつつ、置き換えてくれます。この変換処理を頻繁に行いたくなくて、一度きりで十分なので、ReturnValueから Promote to Variable(変数に昇格)させています。
Event Construct。
アニメーションの再生が終わったら、後片付けしてViewportから姿を消します。後片付けといっても変数を空にしてマテリアルへの参照関係を解消するだけです。
最後に、Event Tick。
Widgetは完成です。
テスト用の新規レベルを作ってテストしてみましょう。
レベルブループリントに Create Widget ノード と Add to Viewport ノードをつなぎます。繰り返し確認したいので、Inputノードで何度でもWidgetを呼び出せるようにします。とりあえずスペースキー。
再生してみます。
いい感じです。青い背景を置いたので、マテリアルのBlend Mode は Additive に変更しています。
シームレステクスチャのパターンを工夫したり、タイリングや揺れ加減を調整したり、まだまだ応用できそうです。
ではでは
今回はこの辺で
ステキなゆれゆれマテリアルライフを!