!!! GI表現を行う ここに書いている内容は、Unity 5.5.1f1で確認しています。 Unity5でのGI(Global Illumination)で間接照明を考慮したリアルにする表現は、 Enlightenというエンジンが使われています。 忘れないようにGI表現を覚え書き。 VRでも90fps出てそれなりにリアルっぽく見える、を目標としてます。 GitHubに参考のシーンをアップしてます。 https://github.com/ft-lab/UnityProjects !! 必要な要素 先にざっと列挙します。後で細かい指定方法などを記載します。 ! シーン全体の指定 * Color Spaceを「Linear」にする * Anti Aliasingを「Dsiabled」にする ! カメラの指定 * CameraのRendering Pathを「Deferred」にする * Cameraの「HDR」をOnにする ! オブジェクトの指定 * ジオメトリをfbxなどでインポート後、staticな形状は「Generate Lightmap UVs」をOnにする。 ** 2つめのUVがlightmap用に使用される ** 重ならないUVが自動で計算されます * dynamicな形状は、うっすらと頂点AOかAOマップを与えたほうがそれらしくなりそうです。 ** 建物の場合はテクスチャを繰り返して使うことが多いと思うので、2つめのUVにlightmapで使うような重ならない展開を行い、AOマップを割り当てる。 ** 木などの込み入ったものは、頂点AOで十分(SpeedTreeで割り当てできます)← AOマップ用のテクスチャの節約のため ! ライトの指定 * ライトのシャドウマップの解像度(Resolution)はシーンに合ったものを指定 * Biasの指定が大きすぎると建物の角部分が明るくなる。小さすぎるとモアレが出る。 ! Lighting/Lightmapの指定 * staticなGameObjectについては、lightmap(事前計算)が行われる (デフォルトは自動計算) * Lightingの設定で「Ambient Intensity」は0かすごく小さい値にする * Lightingの設定で「Reflection Intensity」を0にする * Lightingの設定の「Baked GI」で「Ambient Occlusion」をOnにする * 「Light Probe Group」を配置する。これがすごく重要。 ** 壁際に配置しないと、光漏れの状態になる。 * 鏡やメタル調のマテリアルに映り込むような効果を出す場合は「Reflection Probe」を配置する。 ** 影響を与える位置とBox Sizeを適切に与えないと、不要な明るい部分が出てしまう ! ポストエフェクトの指定 * Image Effectとして「PostProcessing」を使用 ** 「Eye Adaptation」で目がスクリーンの輝度に適応するような自動露出が行われる。室内と室外を行き来する場合は必須。 ** 「Color Grading」でTonemapの指定を行う。必須。 ** 「Ambient Occlusion」でSSAOの指定を行う。接地感を出す、特に光が入らない間接照明がほとんどを占める室内では必要。 !! リアル表現を目指す場合の注意点 オフラインレンダリングでもそうですがフォトリアルっぽい表現をする際に、これをやると泥沼にはまると思われることを列挙します。 ! Lightingの「Ambient Intensity」と「Reflection Intensity」を上げすぎないこと Ambient表現は間接照明の底上げになりますので、与えないほうがよさそうです。 (GI計算/lightmap計算は、その間接照明を計算して与えるものであるので) また、室内と室外を行き来する場合は、 「Ambient Intensity」の値を上げてしまうと閉じられた室内が明るくなってしまいます。 UnityでのSkyboxのLightingは、室外はSkybox使用でもいいのですが、 室内も考慮するとDirectional Lightだけで太陽光を模索したほうがいいかも。 ! ニセ光源は極力与えない 全体的に暗いので仮の光源を与えるというのはよくする手段になりますが、 GIのエンジン(ここではEnlighten)が間接照明計算してくれてるわけですので、 過度なニセ光源追加で逆に嘘っぽいというか、CG臭い表現になっていく感じでした。 全体的な暗がりを明るくするには、ポストエフェクトの露出(Exposure)で調整するほうがいいと思われます。 !!! それぞれの指定 個々のパラメータ指定の詳細です。 !! シーン全体の指定 ! Color Spaceを「Linear」にする メインメニューの「Edit」-「Player Settings」-「Player」を選択し、Inspectorウィンドウの「Other Settings」より、「Color Space」を「Linear」にします。 {{ref_image unity5_lighting_00.png}} これは、テクスチャや色をリニアに変換し、照明計算自身はリニア空間で計算、最終的にレンダリングとして表示する際にガンマ補正して出力するためのパラメータになります。 ! Anti Aliasingを「Dsiabled」にする メインメニューの「Edit」-「Player Settings」-「Quality」を選択し、Inspectorウィンドウの「Anti Aliasing」を「Disabled」にします。 {{ref_image unity5_lighting_01.png}} Cameraで「HDR」を指定するために必要。 Rendering Pathが「Deferred」の場合は、「Anti Aliasing」自身はかからない模様。 !! カメラの指定 ! CameraのRendering Pathを「Deferred」にする、「HDR」をOnにする HierarchyウィンドウでCameraを選択し、Inspectorウィンドウの 「Rendering Path」を「Deferred」、 「HDR」をOnにします。 {{ref_image unity5_lighting_02.png}} 「Rendering Path」が「Deferred」でない場合(Forward)は、光源による計算が端折られて正しく表現しない箇所が出てきます。 {{ref_image unity5_lighting_04.jpg}} ただし「Deferred」はハードウェア依存が高いため、 スマホなどではパフォーマンスもある「Forward」が好まれます。 「HDR」がOffだと、ImageEffectで露出調整などを行った場合に小さな精度が足りず、不正な段階が出てきます。 {{ref_image unity5_lighting_03.jpg}} !! オブジェクトの指定 ! staticな形状は「Generate Lightmap UVs」をOn * 大きな建物(特に、自キャラが建物内に入る場合など) * 影を生成し、その影が周りに影響を大きく与えそうな静的物体 * 地面 などは、staticにすることでlightmap計算に参加し、lightmapを生成することができるようになります。 {{ref_image unity5_lighting_06.png}} その際に、形状のAssetのInspectorウィンドウで「Generate Lightmap UVs」をOnにします。 こうすることで、2つめのUVとして面が重ならないように展開されたUVが自動生成されます。 これをlightmapが使用します。 {{ref_image unity5_lighting_05.png}} static形状 + Lightmapの欠点は、static形状が多くなればなるほど事前計算の時間がかかることと、それだけlightmap用のメモリを消費する点です。 ! dynamicな形状は、うっすらと頂点AOかAOマップを与える 自キャラが入ることができない建物の場合はテクスチャを繰り返して使うことが多いと思うので、2つめのUVにlightmapで使うような重ならない展開を行い、AOマップを割り当てるのがよさそうです。 ここのサンプルシーンの場合は、井戸や社、灯篭などがdynamicです。 椅子や机などもdyamic。 木などの込み入ったものは、頂点AOで十分(SpeedTreeで割り当てできます)。 頂点AOを使うかAOマップを使うかは、メモリと遮蔽の精度を比べてみてどちらがいいかで選択します。 AOマップのテクスチャを使用すると遮蔽がきれいには出ますが、テクスチャのリソースを消費します。 頂点AOはジオメトリにデータを保存する必要があるのと、頂点ごとなので粗いです。が、リソースの消費は少ないです。 {{ref_image unity5_lighting_07.jpg}} 上記の灯篭にAOマップを割り当てています。 UV1は石のテクスチャを繰り返しで利用してますので、AOマップには向きません。 そこで、面が重ならないようにAOマップ用のUV2を設けています。 Shaderも書いています。 !! ライトの指定 ! ライトのシャドウマップの解像度(Resolution) 光源のシャドウマップのResolutionは、シーンの大きさに合わせて適切なものを選択します。 {{ref_image unity5_lighting_08.png}} 以下、LowとHighの違いです。Highのほうがよりきれいな影になってます。 {{ref_image unity5_lighting_09.jpg}} ただ、シャドウマップの影の精度については求めると際限がないので、 精度を確保したい場合はImageEffectとしての「SE Screen-Space Shadows」(有料Asset)なども併用して補間するほうがいいと思います。 ! Biasの調整 光源(Directional Lightなど)のBiasが大きすぎると建物の角部分が明るくなります。小さすぎるとモアレが出ます。 {{ref_image unity5_lighting_10.png}} {{ref_image unity5_lighting_11.jpg}} 適切な値を指定するようにします(シーンにより適切な値は変わります)。 !! Lighting/Lightmapの指定 ! Lightingウィンドウ メインメニューの「Window」-「Lighting」を選択し、Lightingウィンドウを出します。 よく使うので、Inspectorの横にタブとしてドッキングしておくのがよいと思います。 {{ref_image unity5_lighting_12.png}} 「Ambient Intensity」を0かすごく小さい値にします。 0にせずに小さな値を入れてるのは、 チェックしてたときに0にするとテクスチャの表示が不正になることがあったため。 でも、再現できなくなりました、、、。 「Ambient Intensity」がデフォルトのままだと室内の本来真っ暗になる箇所に光が入り、 ポストエフェクトで露出調整したらかなり変になるため。 「環境光(Ambient)」はEnlightenが計算してくれるわけなので、0でいいかと思います。 {{ref_image unity5_lighting_13.jpg}} 上記はImageEffect(PostProcessing)ありですが、ImageEffect無しで真っ暗になるのが正しいです。 {{ref_image unity5_lighting_14.jpg}} これの底上げに必要なのがCameraでの「HDR」指定で、ImageEffectの露出(Exposure)となります。 「Reflection Intensity」もAmbientと同じ理由で0にします。 「Baked GI」の「Ambient Occlusion」は遮蔽を少し入れる効果。これはOnにしておきます。 一番下で「Auto」Onがデフォルトですが、たまにLightmap計算を放棄することがありました。 その場合は、AutoをOffにしてClearしてからBuildなどでlightmap計算を復帰させます。 ! Light Probe Group Light Probe Groupは新規作成時は8点ですが、Inspectorで複製して増やすことができます。 この「Light Probe」が非常に重要です。 これは、 * static形状を衝突する形状として、周りの光をキャッシュしてくれる * その光のキャッシュを元に、dynamic形状の間接的な照明を再現する となります。 {{ref_image unity5_lighting_15.jpg}} 上記は、上がLight Probeを無効化したもの。下が有効化したもの。 奥の大きな建物と地面がstaticです。左端の井戸や右の社、中央の灯篭はdynamic形状です。 影になる部分の「環境光(Ambient)」に相当する部分に光が回り込んでいるのを確認できます。 結構数があっても、速度低下はおきませんでした。 static形状のlightmap対象を増やすよりも、 Light Probeを多用するほうが メモリ的にもdynamicとして動けることを考慮しても よさげかもしれません。 注意点として、壁際には壁ギリギリのところにLight Probeを設けること(内側と外側の両方)。 そうしないと、光漏れ状態になります。 {{ref_image unity5_lighting_16.jpg}} ! Reflection Probe 鏡やメタル調などの反射がある物体用。 static形状のみがReflection Probeのテクスチャとして自動生成されます。 {{ref_image unity5_lighting_17.jpg}} この場合は、部屋内に収まるようにReflection Probeの「Box Size」を調整しています。 この調整をしないと、 * 部屋の外にある形状のマテリアルに反射要素がある場合、室内の情報が映り込んでしまう * Box Sizeが小さいと、室内なのに映り込みがない状態が出てしまう などが起きます。 また、Intensityが大きすぎると(光が強く当たる場所をベイクした場合など)白く飛ぶ箇所が出るので、少し下げておくのも手です。 !! ポストエフェクトの指定 「PostProcessing」( https://github.com/Unity-Technologies/PostProcessing )を使用しました。 Cameraに「Add Component」で「Post Processing Behaviour」を追加。 メインメニューの「Assets」-「Create」-「Post-Processing Profile」を選択。 Profileを「Post Processing Behaviour」の「Profile」にドラッグして割り当てます。 {{ref_image unity5_lighting_18.png}} 後は、Profileを選択して各種Image Effectを調整します。 ここでは、3つの要素を使用しました。 ! Ambient Occlusion {{ref_image unity5_lighting_20.png}} SSAO。VR使用を考えてLowに。 ! Eye Adaptation {{ref_image unity5_lighting_21.png}} 暗いところから明るいところに出た場合など、自動的に目を適応させるように露出調整。超大事。 ! Color Grading {{ref_image unity5_lighting_22.png}} いい感じの色合いに調節。 このポストエフェクト処理は非常に大事です。 太陽光を基準に見ると、室内や室内光源は非常に弱い光です。 なので、外から室内を見ると、目は全体の露出を落として室内が暗くなるように調整されます。 室内の場合は室内が見えるように露出は上げられて、外の世界は白く飛んだような表現になります。 露出は固定でなくて自動調整される必要がある、というのが分かりますね。 これをやっているのは光源の明るさではなくて、目の自動調整の効果となります。 以下、左がPostProcessingなし、右がありです。 {{ref_image unity5_lighting_23.jpg}} {{ref_image unity5_lighting_24.jpg}} {{ref_image unity5_lighting_25.jpg}} 建物(static)内のdynamic形状は、頂点AOやAOマップを使っても接地感が出ません。 この部分は、SSAOでそれらしく影を設けてなんとかそれっぽくします。 左がSSAOなし、右があり。うっすらと影がついてます。 {{ref_image unity5_lighting_26.jpg}} ---- {{lastmodified}}