【Unity】Post Processing Stackをモバイルで使う - 全エフェクトの説明と処理負荷を考察

Post Processing Stackについての簡単な説明と、モバイルデバイスで使う上での注意点をまとめました。
Post Processing StackについてはPreview版であり、なおかつあくまで現時点での情報となります。

Unity2018.1.4
Post-processing 2.0.11 Preview

基本的な使い方はこちら

Post Processing Stackの概要の説明と基本的な使い方については以下の記事で説明しています。

light11.hatenadiary.com

必要に応じて参照してください。

Ambient Occulusion

f:id:halya_11:20180905233919p:plain

ある点に入射する光を考えるとき、周辺に障害物があると入射光が遮られてその点は暗くなります。
これをポストエフェクトで行うのがScreen Space Ambient Occulusion(SSAO)です。
UnityのSSAOはScalable Ambient ObscuranceとMulti-scale Volumetric Occlusionの2種類が用意されています。

Scalable Ambient Obscuranceは幅広いプラットフォームで動くものの処理負荷は大きいです(モバイル想定されてないレベル)。
Multi-scale Volumetric Occlusionは処理負荷もクオリティも優れていますがCompute Shaderが必要です。

つまりPCやコンソール機ではMulti-scale Volumetric Occlusionを使うべきで、モバイルではSSAOを使うべきではない、ということになりそうです。
下のドキュメントにもそんなようなことが書かれています。
ただAOは確実にクオリティが上がるので、Occulusion Mapを用意するなど考えたいところです。

github.com

ちなみにですが、Scalable Ambient Obscuranceの原理はこちらの論文に書かれています。
Scalable Ambient Obscuranceの元になったAlchemy Ambient Obscuranceや、Volumetric Occlusionについてはこちらで紹介されています。

Anti-aliasing

f:id:halya_11:20180905234606p:plain

Anti-aliasは、オブジェクトのエッジなどに生じるジャギーを軽減するためのポストエフェクトです。

アルゴリズムについては下の記事で紹介しています。

light11.hatenadiary.com

PostprocessingではFXAAとTemporalAAが用意されています。
これらのうち、TemporalAAは処理負荷が大きくモバイル向けではなさそうです。

Forward RenderingであればGPUサポートのあるMSAA(Cameraで設定)を、
Deferred RenderingであればFXAAを使うのがいいのかなと思います。

ただいずれも軽い処理では無いので費用対効果を考えながら適用していくべきです。

Bloom

f:id:halya_11:20180905235107p:plain

Bloomは、暗い場所で明るい物を見たときに光がフワッと漏れ出すように見える効果のことを指します。

アルゴリズムの基本的な考え方は下の記事で紹介している通りです。

light11.hatenadiary.com

要は、明度の高い部分だけを抽出してぼかし、元の画像に合成します。
ただし、ブルームはぼかす際のアルゴリズムによってクオリティと処理負荷が大きく変わるので注意が必要です。

処理負荷についてはPostProcessingのWikiに記述があるので要約してみます。

  • Diffusionが大きいほど処理負荷が大きくなる
  • Anamorphic Ratioが0から離れるほど処理負荷が大きくなる
  • Fast Modeにすると処理負荷は小さくなる / モバイルはこれを推奨
  • Dirt Textureのサイズは小さくなるほど処理負荷が小さくなる

モバイルではAnamorphic RatioをOFF、Fast ModeをONにしたうえでDiffusionを許容できる値まで下げるのがよさそうです。
ただ、ブルームはアルゴリズム次第で処理効率を稼ぎやすいポストエフェクトだと思うので、自前での実装を検討するのもアリかと思います。

Chromatic Abberation

f:id:halya_11:20180905235718p:plain

Chromatic Abberationは、カメラのレンズにより波長がずれることで発生する色ずれのことです。
この効果は画面の端に行けば行くほど、またコントラストが大きい部分ほど強く現れます。

また、Chromatic Abberationについては以前の記事で簡単な説明と実装をしています。

light11.hatenadiary.com

PostprocessingのChromatic Abberationは上の記事のものよりも高機能で効果が綺麗にかかります。
その代わり、Intensityを大きくすればするほどサンプリング回数が増えて処理負荷がます性質があります。

Fast ModeをONにすると効果が綺麗にはかからなくなりますが、とても軽くなるようです。
おそらくこのモードが上の記事の実装に近いのではないかと思います(コードをしっかり見てはいませんが)。

モバイルで使う場合はFast Modeにしておくのが無難で、通常モードにする場合は要検証です。

Color Grading

f:id:halya_11:20180906000320p:plain

Color Gradingは色を補正するためのエフェクトです。
Photoshopのようにいろんな補正が掛けられます。

設定値が多いエフェクトですが、設定された情報は全てLUTと呼ばれるテクスチャに焼き込まれます。
ランタイムではこのテクスチャがサンプリングされるため、どれだけ複雑な設定をしても処理負荷は変わりません。
モバイルでも使用可能なポストエフェクトです。

Depth of Field

f:id:halya_11:20180906002631p:plain

Depth of Fieldは望遠カメラなどで撮影を行った時に焦点が合っていない部分がぼける現象を再現したポストエフェクトです。
ぼけるという点ではBloomと似ていますが、Bloomのように光が明るく漏れ出すような効果はありません。

また、現実のボケの形はカメラの絞りの形によって六角形になったりしますが、現状では円形のみ対応しているようです。
(どちらにしろ六角形のボケは処理負荷が高くてモバイルでは実用的ではないと思われます)

処理負荷については、モバイルではMax Blur SizeをSmallにするようにWikiに書かれています。
ただし、Max Blur SizeをSmallにしたところで処理負荷は決して小さくないはずなので、使用する際は検証が必要です。

最近ではぼかし方をかなり荒くすること(多分縮小バッファに焼いて戻しただけのぼかし)で軽量化を図って実装しているモバイルアプリもあったので、
より軽量な実装を自前で行うことを検討してもいいかもしれません。

ちなみに対応シェーダモデルは3.5です。
これはOpenGL ES3.0相当なので、シェーダーモデル的には(ほぼ)対応してると言っていいかと思います。

Unity - Manual: Shader Compilation Target Levels

Grain

f:id:halya_11:20180906002943p:plain

Grainはフィルムで撮影した映像に見られるノイズを再現するためのポストエフェクトです。
フィルム映像の再現や、ホラー演出に用いられます。

参考の節に載せた動画によれば、処理負荷としてはノイズを動的生成しているものの、
気にするほどの負荷ではなくモバイルでも使用可能とのことです。

また、ColoredをOFFにする(グレースケールにする)ことでさらに処理負荷は下がるようです。

Lens Distortion

f:id:halya_11:20180906003455p:plain

レンダリング結果を変形させることでレンズによる歪みを再現します。
シェーダもシンプルで処理負荷は小さいです。

Motion Blur

f:id:halya_11:20180905233259p:plain

Motion Blurはカメラに高速で動く物体を映したときにブレて映る様子を再現したものです。

Motion Blurの実装は、まずMotion Vector Textureによって各ピクセルにおける速度ベクトルを求めます。
次にそのベクトルの方向に少しずつずらしながら複数回サンプリングを行います。
そしてこれらの平均を結果とします。

処理負荷はMotion Vector Textureを使うため大きいです。
モーションブラーを相当重要視していない限り、モバイルでの実用化はもう少し先かなと思います。

Screen-space reflections

f:id:halya_11:20180820135234p:plain

SSRは映り込みを表現するためのポストエフェクトです。

Reflection Probe使った映り込みでは映り込みがズレてしまったりするケースでもうまく映り込みます。
ただし、ポストプロセスなので反射先のオブジェクトがレンダリングされていないと映り込みません。

処理負荷はレイトレースするので非常に高そうです(特にきれいな反射をさせる場合)。
また、Deferred Renderingにのみ対応しています。

これらのことから、モバイルで実用的になるのはまだ先の話と言えそうです。

Vignette

f:id:halya_11:20180906004050p:plain

ビネットは画面の端ほど暗くなる効果を掛けるためのものです。
カメラのレンズにより発生する光学現象を再現するためのポストエフェクトであるといえます。

シェーダはシンプルで処理負荷は小さいのでモバイルでも使用可能です。

参考

github.com

https://www.youtube.com/watch?v=r5mNmH68KPQ