今回は所謂「光りもの」の作り方について紹介します。Unity 4まではProでないと使用できなかったせいで光りものを使っている人が少なかったのですが、Unity 5 (personal)になりその辺りが自由に使えるようになったので、どんどん使っていきたい所です(但しモバイルとVRは除く)
目次
「光る」材質の設定
光ものを表現するのは幾つかアプローチがありますが、とりあえず光らせたい場合はstandardshaderのEmission(発光)を使用すると楽に光らせる事ができます。
正しくはStandardShaderのEmissionの項目を設定すると、その材質が適応されているオブジェクトは、暗闇でも暗くならず色を失いません。
またEmissionを持つオブジェクトがstaticの場合は自身の色を保持するだけでなく周囲のstaticオブジェクトに対して光源として機能するようになります。
Emissionに白黒マスクを設定すると、モデルの中で光る部分を制限する事ができます。白はそのままの光を通し、黒は光を通しません。また輝度が強ければ強いほどマスクから光が滲み出ます。
動的に輝度・色を変更する
Unity 4ではEmissionはLightmapに焼いていたので変更することが出来ませんでしたが、Unity 5はGIに光源情報のみ焼いているらしく、ダイナミックに色を変更する事が可能みたいです。*1
輝度が変化する事で、光の影響範囲も変化します。但し、座標の移動や変形は出来ません。それしたければ普通にLightを使うが吉です。
スクリプトで制御したい場合は、以下の様な形で設定します。Emissionを切りたい場合はmaterial.DisableKeywordでOffにしないと無駄です。
var color = new Color(2, 0, 0);
material.EnableKeyword("_EMISSION");
material.SetColor("_EmissionColor", color);
Unity5のStandardシェーダのパラメタをスクリプトからいじろうとして丸一日潰れた話 - D.N.A.のおぼえがき
また変更した色をステージのライトとして反映させるには、 DynamicGIのupdatematerialsを使用します。もしくはDynamicGI.updateThresholdでしょうか。
DynamicGI.UpdateMaterials(GetComponent<Renderer>());
ただ本メソッドではmaterialがinstantateだと上手く動作しないらしく、instantateマテリアルを使用してマテリアルの輝度を変更する場合は注意が必要です。マテリアルにマスクを使用していない場合はDynamicGI.SetEmissiveを使用すると良いです。
GIの反映には若干のタイムラグがあります。
Emissionをダイナミックな物体にも影響を与える
Emissionで光の表現を行う場合、基本的にキャラクターや動体オブジェクトといったDynamicなオブジェクトに対して影響を与えません。そんな時はLightのBakeと同じようにLightprobeを使用します。
DynamicGI.UpdateMaterialsでEmissionやマテリアルの色を変更するとLightProbeも影響を受けるため、ちゃんと光の輝度変更に応じて色も変化します。
但し他のstaticオブジェクトやdynamic lightと異なり、影が表現されないので、Lightを使用せずコレだけで表現する場合はSSAOで接点表現するとかShadow Projectorで影を投影するといった工夫が必要になります。
光のにじみとHDR
目や眼鏡の効果で、光が滲んで見えるケースがあります。他にもネオンの光など、現実空間において発光している物体は直接見ると、うっすらと物体の周囲に滲みがあったりします。ビーム兵器は基本的に光ってます。このように滲む表現がある物は、お約束的に光って見えます。
光が滲む表現はBloomを使用します。
Bloomで重要な役割を持つのが、HDRの設定です。
色は0~1の範囲で表現します。RGB全部0なら黒、1ならば白な訳ですが、実際には光が強くて白く飛んでいるケースもあったりします。左のキューブは一見白ですが、実は赤が超白飛びした状態です。
HDRはこの本来表現されない部分を利用可能にするオプションです。この範囲外の色を滲ませる事で、輝度の高い部分のみを抽出し光として滲ませる事が出来る訳です。
なので、輝度が高い(通常表現されない部分だけ)を滲ませたい場合は、Bloomが判定する輝度の閾値(Threshold)を1以上に設定しておきます。
要するに輝度が1以上のモノならBloom的に光らせる事ができます。例えばパーティクルに設定したり(ビルボードならテクスチャでやるが吉な気もしますが)、Trailに設定したり(テクスチャでやるが吉な気もしますが)。
ここで厄介だったのが、「輝度を上げると色が白飛びするが、何処から白飛びするか分からない」問題でした。これはUnity 5.1でCurrent Brightnessが追加された事でかなり楽になりました。
Current Brightnessが1以上の場合は色にHDRが表示され、Thresholdで1に設定しているBloomで光るようになっています。また、色が更新され白飛びする範囲もわかり易く表現されます。
Bloomの種類
一言にBloomと言っても、色々とあります。大体はThreshold(閾値)とIntensity(輝度)を調整して何とかするのですが、表現範囲や負荷、フレアサポートの有無で色々と異なる点があるみたいです。
Video Bloom
UnityのテクデモUnity Labに付いてくるBloomです。中間と広範囲の2種類に対してのBloomを設定できるので、一番自然なBloomが設定できる(と噂)です。
負荷が高いです。
Bloom
Video Bloomより軽いBloomです。フレアも合わせて使用できるので、少しカッコ良い感じの表現が期待出来ます。
StandardAssetsのEffectに含まれます。
Bloom Optimized
どちらかと言えば軽量なBloomです。FastBloomと言われたらコレ。
モバイルじゃ動かないっぽいです。ちゃんと動きます。むしろモバイル用なのでモバイルで動かないのはおかしい(該当デバイスで動かせない場合は自動的に無効化されるみたいです)
Cinematic EffectsのBloom
新しいUnity標準(予定)Bloomです。
使用するポイントは範囲を広く薄く。
Bloom Pro
モバイル向けらしいBloomです。レンズエフェクト付き。Bloomにしては珍しくガンマかつforwardレンダリング向け。
無料になったり$5になったりします。
https://kharma.unity3d.com/jp/#!/content/22217
SE Natural Bloom & Dirty Lens
レンズ内部のサブサーフェススキャッタリングをシミュレートし、ピクセルごとのダーティレンズ効果をレンダリングする…だそうです。
割と高速で動作しますが、モバイルでは動かない気がします。
https://kharma.unity3d.com/en/#!/content/17324
SE Natural Bloom & Dirty Lens 本当に眩しいほど綺麗なBloom効果 2015/06/09 - Unity AssetStoreまとめ
Ultimate Bloom
フレアにレンズ汚れにと、グレア表現てんこ盛りのUltimateに恥じぬ派手なBloomです。個人的には一番コレが好きです。ゴージャス。
https://kharma.unity3d.com/en/#!/content/31396
VRやモバイルでの光りもの表現
VRやモバイルでやる場合、解像度に対するパフォーマンスが足りないので、古き良きLensFlareで表現するのが良いんじゃないかなーって気がします。あれ意外な事にVR立体視でも綺麗に見えます。
Unite2015で公開されたRépublique Tech Demoをチェック!Unity5向けのライティングやプロジェクト構造を読む - テラシュールブログ
もしくは古き良き、ノーマル反転アウトライン表現による擬似Bloomエフェクト。
ImageEffectによるBloomも動くには動きますが、モバイルでHDRが動作しなかったと思うので、調整が面倒ってのもあります。
関連
Unity5のStandardシェーダのパラメタをスクリプトからいじろうとして丸一日潰れた話 - D.N.A.のおぼえがき
[Unity5] Bloomで光らせる | Unity | Zabaglioneのさもありなん
【Unite2015】Unity5グラフィックガイド実践編メモ #unite2015tokyo | Develog.VR
Unity - Unity 5 - Lighting and Rendering
3Dグラフィックス・マニアックス (50) HDRレンダリング(10)~HDRブルーム/グレア処理 | マイナビニュース
*1:GlobalIlluminationをBakeに変更するとライトマップに焼かれ変更できなくなります