周辺減光の実装
周辺減光
カメラで撮った絵の画面中心から離れるほど暗く見えるような効果を周辺減光と言います。
最近のゲームでもよく見かける効果です。
アーティスティックな効果の他にも,グレア効果など
スクリーンスペースのエフェクトにおいて,画面端の境界によるアーティファクトを軽減する役割があります。
周辺減光を及ぼす原因としては,大きく分けて,「口径食」と「コサイン四乗則」があるようです。
https://en.wikipedia.org/wiki/Vignetting
https://www.ccs-inc.co.jp/guide/column/light_color/vol08.html
口径食
レンズの経や絞りによって,光が遮られることによって周辺部が暗くなる効果を指します。
さらにMechanical VignettingとOptical Vignettingに分類できるそうですが,イマイチ使い分け方がよくわかりません。
結局のところレンズ系や物理的な制約によって周辺が暗くなる効果ですので,適当に画面中心から遠ざかるほど暗くなるようなシェーダーを書いてみます。
const float2 d = abs(uv - float2(0.5f, 0.5f)) * float2(2.0f*ASPECT_RATIO, 2.0f); const float r2 = dot(d, d); float vignettingFactor = 0.0f; // 口径食の効果 vignettingFactor += pow(min(1.0f, r2 / VIGNETTING_MECHANICAL_RADIUS2), VIGNETTING_MECHANICAL_INV_SMOOTHNESS) * VIGNETTING_MECHANICAL_SCALE; // 合成 outputColor.rgb *= lerp(float3(1.0f, 1.0f, 1.0f), VIGNETTING_COLOR, saturate(vignettingFactor));
UnityのPostProcessingStackの周辺減光のコードを若干参考にしました。 これで再現した口径食はこんな感じです。
周辺減光OFF |
口径食ON |
---|
ImageCircle 小さめ |
ImageCircle 大きめ |
---|
コサイン四乗則
Natural Vignettingと呼ばれるものがこちらのコサイン四乗則になります。
光軸とレンズへの入射光のなす角のときに以下のような性質を満たすと考えます
- 斜めに入射する光は単位面積あたりの強度が倍で小さくなる
- 斜めに入射する光は,直進する光と比べて光源からの距離が倍長い。光源から逆二乗で単位面積あたりの強度が下がるので倍
- 世の中の光源は斜めから見ると倍で減衰するものが多い
これらの要素を乗算すると,結局で画面端の色が減衰すると考えることが出来ます。
の計算を詳しく考えてみます。
0~1空間でのUV空間において,アスペクト比を考慮した画面中心からの距離をとします。ただし縦方向画面端で1.0となるように正規化しています。
(口径食のシェーダーで書いたdot(d,d)がです)
このときに,イメージセンサーまでの距離(=焦点距離)を,さらにイメージセンサーの縦サイズをとすると,は
となります。がコサイン四乗則による減光度合いを決めるパラメータとなります。 これを先程のシェーダーに組み込んだ結果です。
const float2 d = abs(uv - float2(0.5f, 0.5f)) * float2(2.0f*ASPECT_RATIO, 2.0f); const float r2 = dot(d, d); float vignettingFactor = 0.0f; // 口径食の効果 vignettingFactor += pow(min(1.0f, r2 / VIGNETTING_MECHANICAL_RADIUS2), VIGNETTING_MECHANICAL_INV_SMOOTHNESS) * VIGNETTING_MECHANICAL_SCALE; // コサイン4乗則 const float cosTheta = 1.0f / sqrt(r2*VIGNETTING_NATURAL_COS_FACTOR + 1.0f); vignettingFactor += (1.0f-pow(cosTheta , VIGNETTING_NATURAL_COS_POWER)) * VIGNETTING_NATURAL_SCALE; // 合成 outputColor.rgb *= lerp(float3(1.0f, 1.0f, 1.0f), VIGNETTING_COLOR, saturate(vignettingFactor));
周辺減光OFF |
コサイン四乗則ON |
---|
は4.0程度にしています。口径食はOFFです。それっぽい気がします。
結果
口径食もコサイン四乗則も入れた結果です。