どうも、Masaです。
環境マッピングのデモ、見ました。
PII 233MHz 64MB + Monster3D で動かしたところ、35〜45fps 程度出てました。
でもこれ、ディスプレイのリフレッシュレートと同期してますよね。
だから実際には、ほぼ 60fps 程度出てるということになるでしょうか。
しかしやはり速いですね。あのティーポッと、一万頂点くらいあると読んだの
ですが、ポリゴン数(三角形)で数えるとだとどのくらいになるのでしょうか?
非常に興味があるので...。
そうそう、本題に入ります。
あの環境マッピングって、どのようなアルゴリズムを使ってるんでしょうか?
Prejudice を見る限りでは、いわゆるメルカトル図法上の u,v 座標を求めて
いる、つまりは逆三角関数を使って計算しているようなのですが、環境マップ
の BMP を見ると少し違うようです。
メルカトルではなく、Photoshop で球形処理(だったかな?)を施したような
感じに見えます。
環境マッピングと一口にいっても、ベクトルから環境マップ上の u,v 座標を
計算するアルゴリズムはいろいろある訳で、あの環境マップだと、OpenGL で
採用されているアルゴリズム用に見えます。
OpenGLの環境マップは一口では説明しにくいのですが、完全鏡面反射する球体
をある場所に浮かべ、それを無限遠から撮影した場合の球体部分の画像になり
ます。
無限遠といっているのは、球体のどの部分に当たる視線ベクトル(カメラ)も
全て並行になる必要があるからです。
図に描いて考えるともっと解り易いと思うのですが、この球体のこちら側(カ
メラ側)には、上の条件を満たしている場合、理論上 360度全景が映り込みま
す。球体の輪郭部分には視線ベクトルと同じ方向(つまり前方の一点)が輪状
に広がって映り込み、球体の中心部分には、後方(つまりカメラの後ろ方向)
の背景が映り込みます。
さらに、球体の半径を 1.0 とした時、球の中心から √2 / 2 の距離を満たす
円上(球ですが、正面から二次元の円として見た場合です)には、球体の真横、
真上、真下などが映り込む事になりますよね。
そして、360度任意のベクトルから、球に映り込む場所の二次元座標(つまり
は環境マップの u,v 座標)を求める式は、以下のようになります。
ただし、求める座標を u,v とし、ベクトル成分を x,y,z とし、√を root()
で、二乗を ^2 で表記します。
また、この式は、z軸を視線ベクトルと逆向きに(つまり球体から視点に向か
ってくる方向に)とっています。
# 確か Direct3D だと逆ですね...。
m = 2 * root(x^x + y^y + (z + 1)^2) としたとき、
u = x / m
v = y / m
となります。
ただし、ベクトル成分 = (0.0, 0.0, -1.0)(つまり球体のまっすぐ向こう向き
のベクトルで、計算結果が円の輪郭線上に位置するベクトル)については、
m = 0 になるため、計算できません。この場合は、輪郭上の任意の点で良いで
しょう。
u,v 座標はそれぞれ、-0.5〜0.5 の範囲に収まります。
そして、必ず円形上の内部になり、円の外側のピクセルは使われません。
このアルゴリズムの利点は、計算式に三角関数を使わなくて良いことです(平
方根は必要ですが)。
ただし、環境マップの端の方(つまり視線ベクトルに極めて近いベクトル)で
は、環境マップの歪みが激しくなり、また、円形上以外の場所は一切使われな
いため、多少メモリが無駄になるといった欠点もあります。
この環境マップは、非常に広角な(つまり魚眼レンズなどの)カメラで撮影し
た画像をスキャンしたり、普通に撮った写真に Photoshop の球形変形を施し
たりすることで、疑似的に作成できます。
厳密には明らかに間違いで、たとえ魚眼レンズを使っても最大で 前方 180度
の背景しかカバーできませんが、それらしい雰囲気は充分に出せます。
で、環境マッピングティーポットの環境マップは、こちらのアルゴリズム用に
作成されているように感じました。
--
ところで話は変わりますが、DirectX6 の機能はすごく期待感を誘いますね。
特にマルチテクスチャは、是非 OpenGL にも欲しいです。
それ以外はだいたい、OpenGL の機能を採り入れたものですね。
頂点バッファとか DrawPrimitiveStrideとかも...。
# でも、OpenGL では頂点バッファを実際にサポートしている環境はほとんど
# 無いようですが...。使っても効果なし..(;_;)
一つだけ良く解らないのが、Wバッファリングに、ハードウェアの対応が必要
という点です。
ハードウェア側から見れば、与えられた頂点座標(x,y,z)を補間してその中間
座標を求め、求めた z値で Zテストを行なうだけで良いはずで、関係ないよう
な気がするのですが。
要は、ジオメトリ演算側の問題ですよね。ディスプレイ座標に変換するときに
z値をそのまま使うか、1 / z を使うかという...。
# 私がおおぼけかましてるだけかも知れませんが。
ところで、Microsoftって、Microsoft流の言葉が多いと思いませんか?(^^;;
バンプマッピングもフォンシェーディングも、テクスチャマッピングを組み合
わせているだけで、本当の処理をする訳ではないですよね。
もちろん実用性を考えてのことで、これが有効なのは言うまでもありませんが。
# 実際問題、見た目的にも充分バンプマッピングとして通用しますからね。
ただ、Microsoft流バンプマッピング、Microsoft流フォンシェーディングって
いう感じです。あれをはっきりバンプマッピングやフォンシェーディング採用
と言い切ってしまう辺りが、Microsoft ですね。(^^;;
あと、OpenGL が始めから採用している zバッファを わざわざ wバッファといっ
て全く新たな機能のように呼んだりとか...。
# 私は勝手に、Direct3D も始めからこの方法をとってると思い込んでいました。
何だか訳の分からない話ばかりになってしまいましたね。
いつも妙な突っ込みメールばかりですみません m(_ _)m
ではでは〜
______________________________________________________________________
/
_/_/ _/ _/ _/_/ 中部大学 大学院 経営情報学研究科
_/ _/_/ _/_/ _ 高橋研究室所属 川瀬 正樹
_/ _/ _/_/ _ / E-Mail:g93088@isc.chubu.ac.jp
_/_/ _/_/ _/_/_/ http://lpserv01.bais.chubu.ac.jp:8080/~g93088
______________________________________________________________________
|