【Unity】PostProcessingStackのBloomで「特定の物体だけ」を光らせる方法

この記事はUnityアドベントカレンダー2020、2日目の記事です。 qiita.com

Unityについての質問で、次のような質問をよく見かけます。

「特定の物体にだけポストエフェクトを掛けることはできますか?」

これは一応可能ですが、UnityのレイヤーはPhotoshopのレイヤーとは全くの別物で、めちゃくちゃめんどくさいため初心者にはおすすめしません。

どうしてそんなことがしたくなったのかを聞いてみると、「特定の物体だけをBloomで光らせたい」という目的が出てくることが多いです。 これは結構簡単にできるので、やり方をまとめてみました!

そもそもBloomってなんだ?

現実世界のカメラや人間の目は、レンズを通して入ってきた光をセンサーで検知して「色」を判別します。 f:id:notargs:20201130230926p:plain

ですが、この光は全てがまっすぐ目に届くわけではありません。

ごくわずかな光がカメラの内部構造・レンズ・空気など(!)によって屈折、乱反射し、減衰・拡散してから光センサーに届きます。 (ちなみに、「フォグ」も空気による散乱をシミュレーションするための効果です。)

f:id:notargs:20201130230825p:plain

これを真面目にシミュレーションするととても重いので、真面目に計算せず、それっぽく表現するためのエフェクトがBloomです。

Bloomは、厳密に光をシミュレーションしたものではありません

「物体を光らせる」ためのエフェクトではなく、あくまで「光っているように見せる」エフェクトという点に注意しましょう。

Bloomの仕組み

Bloomは、基本的に次の3つのステップで実装されています。

まず、元画像の色彩を調整し、一定より明るい部分だけを取り出します。

f:id:notargs:20201201013712p:plain
元画像

f:id:notargs:20201201013948p:plain
明るい部分だけ取り出したもの

続いて、明るい部分だけを取り出したものをぼかします。 処理を高速にするため、一旦縮小を掛けてからぼかすこともあります。

f:id:notargs:20201201014021p:plain
ぼかしたもの

最後に、ぼかした画像の色を、元画像の画像の色にそれぞれ足し合わせます。

f:id:notargs:20201201014205p:plain
ぼかしたものを元画像に加算合成したもの

PostProcessingStackのBloomのパラメーターを見てみる

PostProcessingStackのBloomのパラメーターを見てみましょう。 f:id:notargs:20201201014348p:plain

ここで重要な値は、次の2つのパラメーターです。

  • Threshold
    • いくつ以上の明るさの箇所を取り出すか?
  • Scatter
    • ぼかしの大きさ

「Threshold」は、基本的には「黒」を0、「白」を1としたときの明るさで表されます。 パッと見0~1の範囲で入力すればいいように見えますが、ここで、Thresholdに1以上の値が入力できることに気づけます。

f:id:notargs:20201201015022p:plain

HDRについて

Unityには「HDR(High Dynamic Range)」という機能があります。 「HDR」は、白(0)~黒(1)の範囲を超えた、「とても明るい色」を表現するための機能です。 逆に、白(0)~黒(1)の範囲の中の色のみを使っている状態を「LDR(Low Dynamic Range)」と言います。

HDRはデフォルトでは無効になっており、設定から有効化する必要があります。 ここでは一例として、UniversalRenderPipelineでのHDRの有効化方法を紹介します。

URPでは、Renderer AssetのQualityセクション内に「HDR」のチェックボックスがあります。

f:id:notargs:20201201015600p:plain

マテリアルのEmissionについて

Unityのマテリアルには、「Emission」というパラメーターがあります。

f:id:notargs:20201201020057p:plain

通常の物体は入ってきた光を減衰・拡散させて反射させます。 入ってきた光より多い量の光が出ていくことはありません。

Emissionはそれに加えて、「物体自身が放出している色」を設定するパラメーターです。 Emissionの設定された物体は、「発光している物体」とみなせます。

EmissionのカラーピッカーはHDRに対応しており、Intencityを上げることで、白(1)より明るい色を設定することができます。 白より明るい色が設定されている場合、インスペクタ上での色の表示も少し特殊な見た目になります。

f:id:notargs:20201201020214p:plain

で、どうすればいいの?

以上を踏まえて、Bloomを利用して「特定の物体だけを光らせる」方法は次の通りになります。

  • RenderPipelineの設定からHDRを有効化する
  • Emissionを1以上の値に設定したマテリアルを作成し、オブジェクトにアタッチする
  • Bloomの設定から、Thresholdを1以上、Emissionで設定した明るさ以下の値に設定する

これらの作業をすることで、特定の物体に対してのみ、しっかりBloomがかかった絵を作ることができます。

まずBloomの事は考えずに「この物体は太陽光の2倍の明るさだ」といった基準でEmissionを決めてあげ、あとからBloomを調整してあげるのがおすすめです。

f:id:notargs:20201201020934p:plain
うおっまぶしっ

それでは、よきBloomライフを!