ウーパの手習い

私的開発メモ用途なのでご容赦ください。2020年現在はSwiftとUnityでARのお勉強中。

Unity:ライティングに関する学習資料と覚え書き

f:id:uuupacom:20180523004723p:plain

VRChat用にATL広尾ワールドを作ったことで、VRChat上でフォトリアルな空間作りに興味を持ちました。モデリング・マテリアル・ライティング等の全ての要素が重要ですが、特に私はUnityのライティングについて不勉強でしたので、集中的に学習してみました。

 

Unityでのライティングの勉強にあたり、まず以下の順に資料を読み進めました。

資料A 

unity3d.com

Unity5.5時代の資料ですが、今読んでも通用するノウハウが多いです。この記事のサンプルファイル一式がAssetStoreで無料で入手できますので、記事を読みつつサンプルをさわりながらライティングの勉強ができます。

次に読んだのが、

資料B

Unity3D | Kemal Akay

Unity社のエンジニアさんのブログ。おそらく上の記事を書いたのもこの人ではないでしょうか。ブログのUnityカテゴリの記事が、それほど記事数もないので読み終えました。シリーズ記事になる予定の記事の続きが未執筆だったりもしますが、Unity5.6~Unity2017の頃の記事なのが良いです。
上のUnityチュートリアル記事だけでは私の理解があやふやだった箇所を、こちらのブログでは違う表現で教えてくれるので、改めて理解することができました。

資料C

www.slideshare.net

Unity社の小林様のライティングに関するスライド資料。ここまで英語の記事を読んで、いろいろ新しいことを知ることができた状態で、こちらのスライド(後半はPBRについてなので、特にスライド前半部分)を拝見すると、以前はスルーしてしまっていた箇所も、今回は意味を理解できるようになっていました。
書かれていること全てがすごく重要だったんですね!という感覚。

資料D

そして皆様ご存知の

tsubakit1.hateblo.jp

ここまで勉強したことへの理解を深めようと、関連キーワードで検索すると、どうあってもテラシュール様のブログに行き着きます。仏様の掌の上の孫悟空のような気分です。
以前からすごく有益な記事を書き続けてらっしゃるため、Unityのバージョン変遷によるUIの変化等には読者側で注意する必要がありますが、とにかくUnityのライティングにおけるあらゆる重要キーワードを、かならずどこかの記事で日本語で分かりやすく説明してくださっています。

以上の資料を中心にライティングについて学習したところ、以前の私が知らなかった事項がたくさんありました。主だった事項を順不同でメモしておきます。
※当方VRChat開発用にUnity5.6を、他開発用にUnity2018をインストールしており、以下のメモは両バージョンで通用する事項をメモしているつもりです。

小物オブジェクトはベイク対象にしない

これが一番「え!そうだったの?」と思いました。今まで私は、動かないものはとにかくStaticにしてベイクしておけば、ランタイム時の負荷が少ないと思っていました。

遠景のResolusionは下げる

遠景って大きい山や岩や木々だったりすることが多いと思いますが、それらを精細に描画する必要はないので当然ですね。Projectパネル上で、Create > Lightmap Parametersでライトマップパラメーターを作成して、それをオブジェクトのライティングに適応させることで、プロジェクト全体のライティング設定とは別に、オブジェクト個別のライティング設定を指定することができます。遠景だったらResolution=0.01とかでも大丈夫だったりする。

f:id:uuupacom:20180519233548p:plain

フォトリアルなアセット「ArchVizPRO Vol.5」でも遠景の山のResolustion=0.01

Post Processing StackのTAA(Temporal Anti-aliasing)

現時点で最も高速なアンチエイリアスソリューション。
透過に対してはうまく動作しない点、アンビエントオクルージョンとブレンドする時に問題を起こすのが欠点ではあるが、それ以外は非常に有用である。

使う時はMSAAを無効にする必要がある。Project Settings > Quality のAnti aliasingをDisabledに切り替える。カメラコンポーネントのAllow MSAAオプションをオフにする。これでPost Processing ProfileのTAAを有効にすることができる。値は1.0にはしてはいけない。0.9~0.97の値を設定すること。

f:id:uuupacom:20180517220208p:plain

上の手順を行わないと、画像のように警告文が表示される

VRChat SDKインポート時の設定変更

VRChat SDKをimport Packageすると、それまで作っていたシーンの色合い変わることがある。Unity5.6の初期設定では [Edit>Project Settings>Player] の Other Settings 内にある Color Space は Gamma が設定されているが、VRChat SDKをインポートすると、Color Space が Linear に自動的に変更されるためである。それもあって、VRChatワールドを作るときは最初からVRChatSDKをインポートしておくのが得策だと思います。

f:id:uuupacom:20180518173727p:plain

また、[Edit>Project Settings>Graphics] の Tier settings 内のRendering Path は Forward がUnityの初期設定になっている。画質表現を向上させたい場合、Forward を Deferred に変更することがあるが、VRChat SDKはForwardのみ許可されているので、Deferredに設定していたとしても強制的にForwardに変更される

f:id:uuupacom:20180518173905p:plain

Deferred Shading が使えないということは、VRChatではSSR(Screen Space Reflection)とHDRが使えないということになる。PostProcessingStackの中にあるSSRもDeferred設定必須のため使えません。ひとまずVRChatで鏡面反射は無理(≒できるかもしれませんが結構大変)と覚えておこう。

VRChatでライトを大量に置くために

上の通り、VRChatはRendering PathはForwardに限定される。5年前のテラシュールブログ様の記事によるとDeferredならライトを複数用意してもレンダリングコストが一定らしいのだが、ではForwardしか使えない場合は?→複数ライトはBaked設定することになりますね。
※5年前となるとDeferred/Forward Lightingを指すと思うが、今だとDeferred/Forward Shading設定なので、その違いによってはForward "Shading"なら複数ライトいけ?要調査だけどたぶん怪しいよね。

tsubakit1.hateblo.jp

SSAOとSSRがややこしい

Screen Space Ambient Occlusion と Screen Space Reflection はどちらも Post Processing Stack の設定項目として用意されている。明暗のメリハリを強調するのがSSAO(AO)で、光沢のある床面上にオブジェクトの鏡像を反射させる時に使うのが SSR です。Deferredでしか使えないのがSSR
それぞれ画質とパフォーマンスを天秤にかけつつ、パラメータを設定をすることになりますが、以下の記事が参考になります。qiita.com

Baked GI のCompressed Lightmaps

圧縮処理にすごく時間がかかるので、作業途中段階ではチェックを外しておくとよい。最後の最後にチェックしてライトをベイクすることで、ライトマップの容量を抑えることができる。(おそらく圧縮することで画質も少し下がるけど、容量減らせる魅力が上回るという認識で良いでしょうか?)

f:id:uuupacom:20180519135209p:plain

ちなみに、このパネル内のFinalGatherやAmbientOcclusionも最後にONする開発スタイルが良いそうです。

Directional Mode

Directional(デフォルト値)にしておけば、ライトの陰影とノーマルマップをベイクしてくれます。ベイク時間はかかるものの、Non-Directionalではライトの陰影しかベイクできないので、画質を求める場合はDirectionalを選択しておけばいい。
※Unity5.6未満ではDirect Specularという項目があったが、5.6では無くなった。5.6以降のDirectional設定がSpecularもベイクするのかしないのかは要確認。下のテラシュール様はUnity5.4当時の記事

tsubakit1.hateblo.jp

docs.unity3d.com

Unity5.6でDirectionalを選ぶと、下のような警告が表示されるが、意味は「古いプラットフォームに対しては効かないよ」という内容なので、対応している再生環境を想定しているのであれば気にしなくて良いらしい。(公式フォーラムのコメントより
確かにUnity5.6ではリリース当時のPC環境を案じて表示されているけど、Unity2018では表示されなくなっており、現在そんなに古い再生環境のユーザーはいないだろうと判断しているのだろう。

f:id:uuupacom:20180519142248p:plain

Realtime ResolutionとEmissive

Precomputed Realtime GIのRealtime Resolutionの値を下げることで、画質は落ちるもののベイク時間は短縮できます。画質低下について、とくにEmissiveで発光しているライトマップの品質低下が著しいそうです。そのため、Realtime Resolutionの値を下げたときは、Emissive発光しているオブジェクトだけばライトの品質を個別に上げておくと良いそうです。

また、Baked GIの間接光も、Realtime Resolutionの値を元にベイクしているそうです。

tsubakit1.hateblo.jp

AreaLight

Staticオブジェクトのみを対象とする。非StaticにはLightProbeを使う。
Unity小林様のスライド資料のP25に、Precomputed Realtime GIではエリアライトが使用できないと書かれていた。検証してみたい。

影が出ない!?

これだけ学習して、いざUnityを起動してオブジェクトとライトをいくつか置いてみたのに、影が出せなくって自分にびっくりしました。
GameObjectメニューからCreate>Lightで作成したLightオブジェクトは初期設定でNo Shadow設定になっているので、Soft ShadowなりHard Shadowに変更しましょう。

tsubakit1.hateblo.jp

Lighit Probeの使い方

ここまでの資料を読んできて、いろいろ知らなかったことを知った上で、下の動画を見ると、かなり理解が進みました。Unity2017で作られた最近の動画なのも良いです。

youtu.be

この動画ではRealtimeGIはオフにしてLightProbe使っているのですが、そうなるとRealtimeGIの意味ってなんだったっけ?ということがまだ私は理解できていないようです。