SSブログ

ポリゴンレンダラ - その6 [プログラミング]

こないだPhongの疑似照明モデルの整理をした。物理モデルに較べれば極端に単純化したものだけど、見た目にはそれほど大きな問題はない。今日はそれを光源が複数個ある場合に拡張したあと、Phongモデルのいくつかの問題点について整理する。

こないだの式-26は一つの光源に対しての式だけど、光源が違う位置に複数個あってもいい。

まず、ちょっと手間を減らすために色をベクトルと見て
0413eq28.png
などと書いて、色の場合に限って要素同士の積を
0413eq28a.png
と書くことにする。

光源がnl個あるとして光源について和をとって
0413eq29.png
とすればいい。そうすると
0413eq31.png
として反射係数は面の色にくりこんでしまうこともできる。

この場合
0413eq32.png
とする必要がある。ここでmax()は引数の中の最大値を返す関数だと思って欲しい。これで色の成分が[0−1]の範囲に入る。

ここで一つ注意が必要で、法線nの符号は、面から見て光源と同じ方向を向くとする。つまり
0413eq33.png
となるように符号を決める。面の裏表に関わらず面が見えるようにするためにはこうしないといけない。つまり光源の位置によって符号を取り替える必要がある。

4.1.3  透明度について

透明度は普通はα値として色の属性の一部になっている。もちろん光源の色には透明度はありえないので、今回のようなモデルの場合、色の一般的な属性とは言えない。

これをどう盛り込むか、というのは表示効率の問題があるので結構悩ましい。これは実装に近くなったらもう一度考えることにする。

4.1.4  Ambient照明について

じつはPhong反射モデルにはもうひとつ項がある。アンビエント(Ambient)照明と言ってモデルを一様に照らす光源で、これは光源に位置はない。したがって面の向きによらない。また視点の位置にもよらないという照明で、色と強度だけが定義できる。

そもそもそんな照明は物理的にはほとんどありえない。なぜこんな照明が導入されているのか、僕は経緯がよくわからない。まわりからの散乱を表すという話もあるけど、アンビエントのように見える散乱なんて、あるとすれば積分球の中ぐらいなもので、しかもAmbient照明だけではすべての面がフラットな色になるので形状把握の役には立たない。

でもOpenGLに導入されているし、Mathematicaでもデフォルトの光源に含まれているので、今回も一応導入しておく。つまり式-26を
0413eq34.png
と変更して、kaをAmbient照明の強度とする。kaはただの定数である。

しかしこうするとAmbient照明まで面の属性と言うことになってしまう。これはおかしい。Ambient照明に物理的な実体があいまいだ、ということが原因している。

従ってkaを色にくりこむときは面ではなくて、照明にくりこむべきである。

最終的に整理のためにAmbient照明まで含めた式を書き直すと
0413eq35.png
となる。また、ベクトルの意味もまとめておくと
0413table.png
式-35は、光源と面と視点が渾然となっていて計算が手間である。また、この計算をどのオブジェクトが主体となってやるのか、が曖昧なのでオブジェクト設計で苦労しそうだ、ということが式を見てわかる。

4.1.5  影について

Phongの反射モデルは非常に割り切ったもので物理モデルからはほど遠いんだけど、計算が簡単でしかもそこそこもっともらしく見える。3次元形状把握という目的のためにはぴったりである。

しかしシチュエーションによってはやっぱり不自然さが大きくなって形状把握に支障をきたす場合がある。

そのひとつが影の問題である。Phongのモデルでは光源からの光が面によって遮られて、他の面に到達しない、という状況は考慮されない。現実世界なら2枚の平行な面を光源が照明する場合、光源から見てうしろになる面には光が来ない場合がある。ところがPhongのモデルでは、図-4のようにこの2枚の面はまったく同じに照明されていることになってしまう。
0413fig4.png
また、面での反射光が他の面を照らす、という状況も考慮されない。こういったことは計算を簡単にするための割り切りの結果であって、これらを考慮するためには光線追跡が必要になる。こないだやった光線追跡と言ってもレンズの評価に使われるようなものではなく、視点から見えるそれぞれの方向について逆向きに経路を求めることで行われる。

光線追跡では散乱面で追跡方向が分岐してしまって組み合わせ爆発が起こるので、散乱面はもう少し簡単にできるようなラジオシティ(レディオシティRadiosity)という方法も考えられている。

どちらにしても、今回はフォトリアリスティックな絵ではなく、あくまで素早い形状把握が目的なので、こういった計算は実装も大変だし、計算量も多いのでやらない。Phongのモデルで不自然になったら、そういうものだ、と頭のほうを切り替えることにしよう。

4.1.6  分散について

物質は分散を持っている。分散とは光の波長によって物質の光に対する振る舞いが変わることで、目に見える現象としては例えばプリズムを通した太陽の光が虹色に別れて見えたりすることを言う。空に現れる虹も空気中の水滴の分散の結果である。これは屈折率の値が波長に依存していることによる。

また、波長に近い大きさの凹凸が物質の表面にある場合も分散が現れる。目では細かすぎて見えないけど、光を反射させると虹色が見える。光学グレーティング(回折格子)はまさしくその現象を使って波長を分離するものだけど、光ディスクに反射した光が虹色に見えたり、タマムシの金属光沢に見える羽根なんかも同じ現象である。これは屈折率変化とは色の向きが逆になる(分散の符号が逆)。

シャボン玉の膜に色がついているように見えるのも、膜の厚さが光の波長に近いためで、広い意味の分散である。

こう言う現象は気をつければ身の回りにすぐ見つかるが、Phongのモデルでは再現できない。今回はテクスチャを持たせることはしないのでこう言う面を表示することはできないけど、フォトリアリスティックな表現を目指すような場合、特別な処理が必要になる。

4.1.7  面の向きについて

OpenGLでは面には裏表があって、裏を向いた面は表示しないように指定することができる。今回は面に裏表はあるけどどちらも描画することにする。 ただし、OpenGLと同じようにポリゴンの頂点の順番で裏表を判別したとき、連続した面は裏表も連続していると見なすことにする。

ようするに、頂点の順番に従って法線ベクトルを引いたときに、面によってあちこち向いたりしない、と考えることにする。そうすると、法線ベクトルと視点から面へのベクトルの内積の符号によって裏表が判別できる。

というか、そうなるようにポリゴンのデータを生成しておく必要がある、ということになる。

nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

献立04/13献立04/14 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。