妹でもわかるUnrealEngine4

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

ディフュージョンフィルタを作る(2) 輪郭が丸くなるように調整

「昨日作ってたポストプロセスマテリアルの……というか、ポストプロセスマテリアルで作ってるって書いてなかった気がしてきたけど、とにかくそれを改良した」


f:id:una_unagi:20171107234914p:plain
100%

f:id:una_unagi:20171107234936p:plain
50%

f:id:una_unagi:20171107234956p:plain
元の状態

カスタムノードの中身


/* 初期値。ループの中で増やしていく */
float4 total = SceneTextureLookup(uv, 14, true);
float total_alpha = 1;

/* ループ開始。表示中のピクセルから縦横に調べる */
for(int y_loop = -6; y_loop <= 6; y_loop++){
for(int x_loop = -6; x_loop <= 6; x_loop++){

/* ピクセルの色を取得 */
float4 col = SceneTextureLookup(uv + float2(x_loop, y_loop)*invSize*2, 14, true);

/* RGBの数字を元に明るさを算出 */
float light = col.x * 0.3 + col.y * 0.6 + col.z * 0.1;

/* 距離を調べる(ここはもっと高速化できそう) */
float d = distance(float2(0,0),float2(x_loop, y_loop));

/* 距離が遠くなるほど影響力を弱くする */
float alpha = light / 7 * (7 - d);

if ((light > 0.7)&&(d <= 6)){
total += col * alpha;
total_alpha += alpha;
}
}
}

/* 足しに足したRGBを最後に割って、色を混ぜ合わせた状態にしたものを返り値にする */
return total / total_alpha;

「修正して、一応それらしい感じになってきた気がする。コメントを入れてもカスタムノードは動くみたいなので、少し説明を入れて」

妹「意味はよくわからないけど、四角ではなくなったみたい」

「周囲ピクセルを縦横のループで調べるから、その範囲は四角になるんだけど、調査中のピクセルとの距離を計って、一定の距離より遠いとスキップするようにして、丸くなるようにしてる」

妹「これで完成?」

「ちょっと強すぎる気がする。影響度が中心からの距離に比例してるから、あんまりふわっとしてない気がする。まだ調整が必要」

ディフュージョンフィルタを作る(1)

「AnswerHubでディフュージョンフィルタを作る方法はないか? という質問を見かけたんだけど、ディフュージョンフィルタが何かわからなくて調べていた」

妹「なんだったの?」

「それがよくわからないというか、細かい実装方法自体がバラバラで。基本的には明るい部分の色だけが周囲に広がるぼかしフィルタのようなものかな、と思ってるんだけど。でもグローみたいに輝かせるというものでもないらしい」

妹「それをやるとどうなるの?」

「明暗の差がなくなって、全体的に明るめに、でも色が白くなったりはせず、ふわっとした感じに仕上がるらしい」

妹「洗濯物かな……これが昨日言ってた、今作ろうとしてるやつ?」

「そうそう。とりあえず原理的には前に作ったぼかしフィルタと同じで、明るい部分だけそれをやれば作れるんじゃないかなあと思って、ちょっとやってみた」

f:id:una_unagi:20171106232405p:plain

f:id:una_unagi:20171106232415p:plain

f:id:una_unagi:20171106232440p:plain


float4 total = SceneTextureLookup(uv, 14, true);
float total_alpha = 1.0;

for(int y_loop = -4; y_loop <= 4; y_loop++){
for(int x_loop = -4; x_loop <= 4; x_loop++){
float4 col = SceneTextureLookup(uv + float2(x_loop, y_loop)*invSize, 14, true);
float light = col.x * 0.3 + col.y * 0.6 + col.z * 0.1;
if (light > 0.7){
total += col * light;
total_alpha += light;
}
}
}
return total / total_alpha;

「マテリアルの仕組みは、ぼかしの時と全く同じ。ただカスタムノードの中身を少し変えた」

妹「カスタムノード全然わかんないんだよね……」

「マテリアルにループさえあれば、マテリアルブループリントで書いてもいいんだけど。とりあえず理屈としては」

(1)・周囲のピクセルの色を調べる
(2)・(1)の色が明るかった時はその色のRGBを足す
(3)・(2)を周囲81ピクセルに対してやる
(4)・最後に足しまくったRGBを割って、このピクセルの色とする

「ぼかしと違うのは2の部分。RGBから明るさを計算して、あと明るいほど多めに足すとかもあるけど」

妹「それでこれはディフュージョンとかいうやつになったの?」

「なってない気がするなあ……なってるんだけど、四角になっちゃうというか。これはぼかしフィルタの時点で適当に作ってたせいなんだけど、近くのピクセルほど多く色を足す、つまり影響力を強くする必要があるんだけど、それをやってないから、明るいとこの周囲が均等に明るくなってしまった」

妹「ぜんぜんふわっとしてない」

「だいたいの原理としてはいけそうだから、ぼかしの部分をもっと丁寧にぼかすようにすれば大丈夫なはず」

UE4アドベントカレンダー 2017が開催。参加者を募集中

www.unrealengine.com

「12月に毎日交代で記事を書いていくという、アドベントカレンダーUE4版の募集が始まってた」

妹「去年もそんな話をしてたような」

「去年だけじゃなくてもっと前からあるんだけど、ここ最近は枠が足りなくて、二個作るようになってる」

qiita.com
qiita.com

「今回も募集は3日前ぐらいのはずなんだけど、すでにひとつ埋まってて、ふたつ目も空きが少なくなってきてる状況」

妹「そんなに」

「というわけで、今年はその2の方の、12月5日の枠を確保してきた

妹「えっ! だ、大丈夫なの?」

「してきたというか、してしまったというのが正しいんだけど。試しにボタン押したら、最終確認とか出なかったので、そのまま登録されちゃったので」

妹「なんて適当な」

「もちろん"参加を取り消す"ってボタンはあるんだけど、折角だから書こうかと。登録はQiitaってサイトのアカウントがあればよくて、タイトルと記事のアドレスの2つの欄に書くだけ。アドレスは空欄で登録できた。記事が出来てからそのアドレスを書けばよさそう」

妹「でも何の話書くの?」

「一応ネタとしては春頃に作って、今作ろうとしてるやつが上手くいったらそれの話を、上手くいかなかった場合でも自作のアウトライン表示用マテリアルの記事の要点まとめたやつは書けそうだったから。間接ライティングの記事も結構興味ある人多そうだったから、そっち路線でもいいんだけど」

妹「変えてもいいんだ」

UE4に関連してればOK。タイトルはいつでも編集出来るし、記事を出す段階でも変えられるから」

妹「間に合わなかった場合は?」

「なるべくその日のうちに記事を出した方がいいんだけど、急なトラブルとかは起こるから。後から記事を出すこともできるみたい」