Unreal Engine 4 (UE4) Advent Calendar 2014 - Qiitaの九日目です。
記事名の通り、UE4のポストプロセスマテリアルについて雑多に色々書きます
前回の基本編では以下の項目について説明しました
UE4のポストプロセスマテリアルで色々してみた 基本編 - Unreal Engine 4 (UE4) Advent Calendar 2014 - ぼっちプログラマのメモ
- レンダリング結果・デプスマップの取得
- 隣り合う画素情報の取得
- フィルター処理
今回は基本編で説明した内容+αで
作ってみたものを紹介・解説していきます
漫画風フィルターを作ってみた
数年前に流行っていた漫画風フィルタをUE4で実装してみました
↓こんな感じ
アルゴリズムは↓のサイトで紹介されているものを使用します
OpenCVで写真を漫画風に加工してみよう 〜手法編〜 | Developers.IO
必要な要素は以下の3つです。輪郭に関しては前回解説した
エッジ検出が使えるので、残り2つを実装します
- 輪郭検出
- 3値化
- スクリーントーン
3値化
よくあるフィルター処理に2値化というものがあります。幾つか手法はありますが、
「画素のRGBの平均値を算出し任意のしきい値より大きければ白、小さければ黒」
という手法が最もイメージしやすいかと思います
今回は3値化ということで、しきい値は2つ、画素情報はグレースケール化したもの
を使用します
グレースケール
グレースケールは以下のサイトで紹介されている「NTSC 係数による加重平均法」を
使用します
osakana.factory - グレースケールのひみつ
結果画像
※記事公開後
グレースケールを求める場合、各要素を積算、加算するよりDotProductを使った方が命令数を減らせたりする。
— もんしょ (@monsho1977) 2014年12月8日
DotProductは2つのベクトルの各要素ごとに積算して、それから全ての要素を加算して1つの要素にまとめるので、結構使い道があって面白かったりする。
— もんしょ (@monsho1977) 2014年12月8日
/(^o^)\
⊂(^ω^)⊃ セフセフ!!
(@monsho1977さん、ありがとうございました!)
3値化
グレースケール化した値に対して3値化処理を書けます
if文で実装するのも可能ですが、処理速度的に不安な面があるので
しきい値に応じてRGB3色に分けたテクスチャを使って実装します
結果
テクスチャから値取得した後の謎処理をしている理由は、
↑のテクスチャがペイントで作成したてきとーなものだからです
(赤の場合だと(1,0,0)ではなくGB成分に微妙に値があるため、補正処理かけてます)
キチンと正しい値が設定されているテクスチャを用意出来る人なら不要な処理です
(UE4側の設定で何とか出来そうな気がするけど…)
あと、テクスチャアセットは以下の設定をして下さい
デフォルトだと色の境界付近にフィルターがかかり、キチンと3値化されません
スクリーントーン
3値化が無事出来たので、次は赤色部分は黒、緑はスクリーントーン、青は白で
描画する処理を実装します。Lerpノードで簡単実装です
スクリーントーンのテクスチャはお好みの物をどうぞ
結果
漫画風フィルター完成!
あとは前回解説したエッジ検出を追加するだけです
前回紹介したノードを丸ごと引っ張ってくればいいのですが、
さらに簡単に重ねがけで実装してしまいます
結果
2回処理が走ってしまうと思うので、今回の実装範囲では完全にダメ実装ですが
こういうやり方もある事を覚えていると、後々役立つ…かもしれません
か○いたちの夜フィルターを作ってみた
かま○たちの夜っぽい表現をポストプロセスマテリアルで実装します
かまいたちの○って何?という人はググッて下さい。名作です
CustomDepthを使ってキャラクターを抽出
○まいたちの夜的表現をする上で必要なのは、人物の抽出です
今回はCustomDepthという機能を使って抽出します。で、解説しようと思ったら
既にありました
もんしょの巣穴blog [UE4] CustomDepthを使ってみる
まずは、抽出したいキャラクターのRenderCustomDepthにチェックをいれます
そして、こんな感じでBPを作ります。CustomDepthに値が入っていれば赤、
なければ通常のレンダリング結果を出力します
結果
それっぽいのが出来ましたが、単なる塗りつぶしで微妙です
LerpのAlphaに渡す値を0か1ではなく、0か0.8にします(0.2引いてclampするだけ)
塗りつぶしでは無くなりましたが、ブルーマン先生が帰ってきました…
そもそも欲しいのはCustomDepthだけなので、ブルーマン先生は描画しないように設定
しましょう。「Render In Main Pass」のチェックを外すだけです