位相関数(雲における光の散乱のシミュレーション)

phase-function.png

位相関数とは?

ある物体に対して、光が当たったら、
どんな風に、どの程度の強さで光が散乱(反射)するのかを
全方位に対して示した配光分布図。

ボリュームにおける光の伝達が、
面のレンダリングにおける
bidirectional reflectance distribution function(BRDF) 双方向反射率分布関数
に似てるようにすること。
散乱粒子と散乱特性を表すもの。
光源からの光が視点方向へ散乱される割合と求めることができる。
BRDFはある面に対する半球だけだが、位相関数は球のすべての方向の光が関与する。

位相関数の入力と出力

普通は入ってくる光出て行く光の角度のコサインだけに依存するのが位相関数である。

  • 入力…視線方向Eと光源方向とのなす角θ
  • 出力….光源からの光が視点方向へ散乱される割合。

位相関数の分布形状

  • 粒子の大きさ
  • 光の波長

に大きく依存する。
光の波長>粒子 ならば レイリー散乱 同じ大きさの玉が2つの分子のような分布形状
光の波長<=粒子 ならばミー散乱 おたまじゃくしのような分布形状
になる。これが分布形状の違いにつながる。
光の波長による変化は少し形が広がったり、縮んだり、形状が変化すると思えばよい。

位相関数の種類

Mie位相関数

ミー散乱のことっぽい。
これもシミュレーションすると、雲の真ん中で虹っぽい現象(glory effect)を再現することができる。

シミュレーションの仕方

scatter_calc.png

目的は、最終的に視線Peに届く色を計算することである。
視線Peに届く光の強さは次の2成分になる。

  1. 物体と視線の交点である点Qからの反射光成分
  2. 光路PeQ間の点R(光源と視線の交点)において、光源からの光が視点方向へ散乱された光の成分

物体と視線の交点である点Qからの反射光成分

物体と視線の交点である点Qでの反射光は視点Peに届くまでに光路PeQ間で減衰する。
この減衰を考慮して点Qからの反射光の強さを計算する。

光路PeQ間の点R(光源と視線の交点)において、光源からの光が視点方向へ散乱された光の成分

光源から点Rの区間での減衰と
点Rから視点Pe区間での減衰
の両方を考慮する必要がある。

散乱粒子の密度により光は距離に対して指数関数的に減衰する。
散乱粒子の密度が一様でない場合には、減衰率もレイマーチング法などの数値的手法を用いて算出される。

次に、ついに位相関数の登場である。
点Rにおいて、散乱粒子の散乱特性を表す位相関数を用いて、
光源からの光が視点方向へ散乱される割合と求める。

更に、光路PeQ間の点R(光源と視線の交点)において、光源からの光が視点方向へ散乱された光の成分では、
光路PeQ間にわたって散乱光を積分する必要がある。
レイマーチング法(レイキャスティング法と同じ)によって点Rの位置を微小距離ずつ移動させながら、光路PeQ間にわたってその散乱光を加算していく。

位相関数の決定源

  • 視線方向ベクトルEと光源のなす角θ

実装の仕方

uniform sampler3D phase_function;
vec3 lightvec = normalize(gl_LightSource[0].position.xyz  - position);
            vec3 viewvec = normalize(v_cam_local - position);
            //dotの結果は±1.0なので0.0-1.0の範囲になるように正規化する
            float phasevalue=(dot(lightvec,viewvec)+1.0)*0.5;
            float phaseval=texture1D(phase_function,phasevalue);
            src=vec4(shading(normal,viewvec,lightvec),scalar)*phaseval;

キャッシュを使って高速化

u
g(光の波長)
v
θ

となるような2Dテクスチャを位相関数として使うといい。

参考にした本

サポートサイト Wikidot.com