Unity のライトは、あるオブジェクトからそれ自体の一部や近くにある他のゲームオブジェクトに 影 (シャドウ) を作ることができます。シャドウによって、ゲームオブジェクトのスケールや位置が明確になるため、シーンに奥行きと現実感が生まれます。シャドウがないと、オブジェクトは 「平坦」に見えてしまいます。
光源が1つしかない単純なシーンを想像してください。光源から発せられたレイ(光線)は、光源から直線的に進み、やがてシーン内にあるゲームオブジェクトにぶつかります。レイがオブジェクトにぶつかると、それ以上は進めなくなるので、その先を照らすことはありません (つまり、レイは最初にぶつかったオブジェクトで跳ね返り、通過しません)。ゲームオブジェクトが作りだすシャドウは、単にライトが届かないために照らされない領域のことなのです。
別の見方として、ライトと同位置にあるカメラをイメージしてください。影になるシーンの領域は、カメラで見ることのできない領域と正確に同じになります。
実際、まさにこれが、Unity がライトによるシャドウの位置を決定する方法なのです。ライトはカメラと同じ原理を使って、その視点からシーンを内部的に「レンダリング」します。シーンカメラによって使用されているように、深度バッファーシステムがライトに最も近いサーフェスを追跡します。視点の直線上にあるサーフェスは照らされますが、他のすべては影になります。この場合の深度マップは シャドウマップ と呼ばれています(シャドウマッピングの詳細は Wikipedia Page を参照してください)。
インスペクターの Shadow Type プロパティを使って個々のライトに対するシャドウを有効にし定義します。
プロパティ | 機能 |
---|---|
Shadow Type | Hard Shadows を選ぶと、エッジのくっきりしたシャドウを生成します。Hard shadows は Soft Shadows に比べて特に現実的なわけではありませんが、処理が少なく多くの場合で許容できます。Soft shadows は、シャドウマップからギザギザのエイリアシングを減少させる傾向もあります。 |
Strength | シャドウの濃さを決定します。一般に、ライトは大気によって拡散され、他のゲームオブジェクトに反射します。そのため通常は、シャドウの Strength を最高に設定することはありません。 |
Resolution | 前出のシャドウマップの「カメラ」のレンダリング解像度を設定します。シャドウのエッジがとてもはっきり見える場合は、この値を上げるとよい場合があります。 |
Bias | シャドウの位置と鮮明さの微調整を行います。詳しくは後述の シャドウマップと Bias プロパティ を参照してください。 |
Normal Bias | シャドウの位置と鮮明さの微調整を行います。詳しくは後述の シャドウマップと Bias プロパティ を参照してください。 |
Shadow Near Plane | シャドウをレンダリングするときに、ニアクリップ面の値を選択できます。ライトとの距離がこの距離より短いオブジェクトはシャドウを作りません。 |
シーンの各 メッシュレンダラー も Cast Shadows と Receive Shadows プロパティを持ち、必要に応じて有効にする必要があります。
Cast Shadows のドロップダウンで On を選択すると、メッシュからのシャドウの投影を有効にします。Two Sided を選択すると、メッシュのどちらのサーフェスからでもシャドウを投影することができます (そのため、バックフェースカリングは投影目的では無視されます)。Shadows Only は非表示のゲームオブジェクトからシャドウを投影できます。
指定されたライトのシャドウはシーンの最終的なレンダリング中に決定されます。シーンがメインカメラのビューにレンダリングされるとき、ビュー内の各ピクセル位置はライトの座標システムに変換されます。それから、ライトからのピクセル距離がシャドウマップの対応するピクセルと比較されます。ピクセルがシャドウマップのピクセルよりも離れている場合、別のゲームオブジェクトによってライトから隠されると推測され、そのピクセルは照らされません。
ライトが直接照らすサーフェスに、部分的に影があるように見えることがあります。正確にシャドウマップで指定された距離でなければならないピクセルが、ずっと遠くにあるように計算されてしまう場合があるためです(シャドウフィルタリングやシャドウマップに低解像度画像を使用した結果)。その結果として、実際には照らされるべきピクセルが影になって模様を作る、「シャドウアクネ」と言われる現象が発生します。
シャドウアクネを避けるために、シャドウマップの距離に Bias 値を加え、数値の境目にあるピクセルが確実に比較にとおるようにします。または、シャドウマップにレンダリングする間に、ゲームオブジェクトが法線に沿って少し差し込まれるようにします。これらの値は、シャドウが有効の時に Light インスペクターウィンドウの Bias と Normal Bias プロパティによって設定されます。
Bias 値をあまり高く設定しないでください。なぜなら、ゲームオブジェクトが作るシャドウ近くの領域は時々誤って照らされることがあるからです。この結果、オブジェクトから離れたシャドウとなり、ゲームオブジェクトがまるで空中に浮かんでいるように見えます。
同様に、Normal Bias 値をあまり高く設定すると、ゲームオブジェクトに対し、影の幅が狭くなりすぎてしまいます。
ある状況では、Normal Bias が “ライトのにじみ” と呼ばれる、望ましくない効果の原因になることがあります。ライトのにじみとは、ライトが近くのジオメトリから影になる領域に漏れてしまうことです。可能なソリューションはゲームオブジェクトの Mesh Renderer を開き、 Cast Shadows プロパティを Two Sided にします。これによって、問題を解決できる場合があります。ただし、よりリソース負荷が高くなり、シーンをレンダリングするときにパフォーマンスのオーバーヘッドが増加します。
ライトの Bias 値には、望まないエフェクトが発生しないように微調整が必要な場合があります。一般に、計算するよりも目測で値をとる方が簡単です。
さらに、シャドウアクネを避けるために、シャドウパンケーキ ( ディレクショナルライトのシャドウ: シャドウパンケーキ を参照) という技術を使用します。一般的に、この方法は効果的です。しかし、とても大きな三角形には、視覚的なアーティファクトが発生します。
プロパティの Shadow Near Plane Offset 値を適切に調整すると、この問題は解決されます。この値をあまり高く設定すると、シャドウアクネが発生します。