Google Chrome または Safari を使用される事を強くお薦めしますw
他のブラウザでは Javascript の処理が重いです(汗)


2010/10/14

リアルタイムで3D迷路を表示する その3

隠面消去の話です。
視点から見て裏を向いている面は描画する必要がないので除外します。
前回の図で水色の面が表を向いている面、黒いのが裏を向いている面です。

面の裏表を判断するために各面にはあらかじめ法線ベクトルを設定しておきます。
(実行時に計算で求めても良いですが、その分処理が遅くなるのでデータとしてあらかじめ持たせておきます)
そうしておいて面が表を向いているか裏を向いているか判断するのですが、それには内積の計算を行います。

ベクトルの内積 dot はこんな式で求まります。

dot = u1 * u2 + v1 * v2 + w1 * w2

ここで (u1, v1, w1) と (u2, v2, w2) はそれぞれのベクトルの X, Y, Z 方向の成分です。
このゲームでは2次元で計算してオッケーなので、 v1 * v2 の計算は不要です(どちらも 0 なので)。

この内積の値は2ベクトルの関係によってこんな風になります。
ですので、面の裏表の判定は面の法線ベクトルとZ軸(視線方向)との内積で判断できます。
つまり内積がマイナスの値であればこっちを向いている(表の面)ということです。
内積がプラスであった場合にはそれ以上の処理はしないようにします。

これで視錘台の内側でかつこちらを向いている面だけが集まりました。
これを描画するのですが、視点から見て近い面が遠い面を隠さないといけません。単にここまでで集めた面を描画しただけだと面の前後関係が正しくないので3D迷路に見えません。

面の前後関係が正しい表示

面の前後関係が正しくない表示

面の前後関係もいろいろ計算すると求まり、そうやって隠れた面を描画しないことで処理の向上に繋がる場合もありますが、ブラウザの場合は div を余分に表示するくらいは問題なく、それよりも隠れた面を表示しないように計算する方がコストが高いです。

なので、隠れた面を描画対象からはずすことはせずに、HTMLの機能で遠くにある面は遠くに、近くにある面は近くに表示するようにします。
つまり z-index の値で制御します。

このように視点から面b (Back Clipping Plane)までの距離から各面までの距離を引き算したものを div の z-index に設定してやります。

これで面が正しい順序で表示されるようになりました。
次回は面に色をつける話です。

0 件のコメント:

コメントを投稿