妹でもわかるUnrealEngine4

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

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

ポストプロセスマテリアル製ディフュージョンフィルタ #UE4

この記事は「Unreal Engine 4 (UE4) その2 Advent Calendar 2017」の5日目として書いたものです

qiita.com

「今回はアドベントカレンダー用ということで、先日研究していたディフュージョンフィルタの作り方を、ちょっと忘れたので思い出しながら、改良したものを紹介します」

妹「ディフュージョンフィルタが何かっていう説明とかはしなくてもいいの?」

「それまだよくわかってないんけど、明るい部分の光がぼわっと広がる感じらしい。そこらへんの話や試作品については、関係ありそうなリンクをこの記事の末尾に並べたので、それを見てもらう感じで」

f:id:una_unagi:20171204031403p:plain

「それでディフュージョンフィルタの話だけど、この画像がそう。ラーニングにあるサンテンプルを使ってる。このマップはカッコイイわりに軽量で、光の表現もあるから試すのにはうってつけ」

f:id:una_unagi:20171204032005p:plain

「同じ場面でフィルタがかかってないのがコレ」

妹「ちょっと窓枠のところが違うのかな」

「窓のところに光があたって明るくなってるから、その光が周囲に拡散して、窓の輪郭がふわっとした感じになる。あと火のところとかも」

UE4.18.1で制作・確認しています

f:id:una_unagi:20171204032439p:plain
f:id:una_unagi:20171204032503p:plain
マテリアルの仕組み

カスタムノードの中身


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

/* ループ開始。表示中のピクセルから縦横に調べる */
/* 範囲が広い方が光を綺麗に広げられるけど、その分重くなる */
for(int y_loop = -radius; y_loop <= radius; y_loop++){
for(int x_loop = -radius; x_loop <= radius; x_loop++){

/* ピクセルの色を取得 */
/* 2を掛けるのは処理を重くせずボカシの範囲を広げるため。数字が大きいと光る範囲が狭い時に違和感大 */
float4 col = SceneTextureLookup(uv + float2(x_loop, y_loop)*invSize*mul, 14, true);

/* RGBの数字を元に、明るさを0.0~1.0の数字で表す */
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));

/* 距離が遠くなるほど影響力を弱くする */
/* 距離を変換して、中心が1.0で、遠ざかるほど0に近づく数字にする */
float d2 = (((radius+1) - d) / (radius+1));

/* 距離と全体の明るさを計算して、どの程度の影響力をもたせるか決める */
float alpha = light * d2 * blightness;

/* 円の範囲内で、かつlimitより明るい場合にだけ色を混ぜる */
if ((light >= limit)&&(d <= radius)){
total += col * alpha;
total_alpha += alpha;
}
}
}

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

f:id:una_unagi:20171204035719p:plain
f:id:una_unagi:20171204035734p:plain
設置場所(サンテンプル プロジェクトの場合)

「カスタムノードの中身がちょっとややこしいけど、マテリアル自体はシンプル。パラメータのノードはScalerParameter、LerpはLinearInterporateって、ノード検索の欄に入れれば作れる」

妹「パラメータがだいぶ増えたね」

「11/14版ではカスタムノードの中に全部書いてたけど、それだと変更がしにくい。パラメータになってれば、マテリアルインスタンスで色々バリエーションも作れるんで、好みや処理速度に合わせた調節が出来るように改良した」

妹「このパラメータ変えたらどうなるの?」

「なんというか、色々変わる。例えばボカシ半径を広げるとこんな感じにもなる」

f:id:una_unagi:20171204034437p:plain

「だいたいの説明は書いてある通り。適当に変えて遊んでも大丈夫だけど、Radiusパラメータだけは大きすぎるとフリーズしかねないので危ない。SliderMaxのところに10.0ぐらいって設定しとけば、バーを動かしてもそれ以上にならないので安心。Mulパラメータを増やすと、粗くなるけどあまり負荷をかけずに範囲を広げられる」

妹「Limitってやつを変えれば、もっと色んなとこが光るようになるの? 柱とか」

「そうなんだけど、実際そこを下げすぎると、明るいのも暗いのも全部拡散するから、単に画面全体をボカシたのとあまり変わらなくて、面白みがなくなってしまう。0.6~0.9ぐらいが実用的な範囲だと思う」

妹「面白みに欠ける」

「画面全体を明るくするポストプロセスとかもあるから、そういうのと組み合わせるともう少し色々できる。もちろんカスタムノードの中身を改造してもいいし。とにかくポストプロセス次第で見た目が大きく変わるから、同じグレーマンのはずなのにかっこよさが全然ちがってくるというのが面白い」