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


2010/10/14

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

長いつまらん話ですがw、これで終わりです。

面に色をつける話です。実際には色というよりは明るさの話です。
まずはゲーム画面で面の明るさを見てください。
 真正面にある面は明るい

 斜めになった面は暗い

 遠くにある面ほど暗い

諧調にあまり差がなくてわかりにくいですね。もっと極端に暗くなるようにした方が良いかもしれません。

それはともかく、このゲームは車のヘッドライトで壁が照らされているイメージです。
なので真正面にあるものは明るく、斜めになると少し暗くなり、遠くのものほど暗くなる、という見え方になるようにしています。

これには面の裏表判定で計算した内積の値を流用します。
視点からのベクトルと面の法線ベクトルとの内積は面の向きによってこのように変わります。
表を向いている面なので内積値はマイナスになります。なので絶対値で考えますが、正面では1.0、斜めを向くとこれが小さくなっていき、視線ベクトルに対して90度横を向くと0.0となります。
(内積値が0の面は裏面と判断するので描画しませんが)
この0.0~1.0の内積値をそのまま面の明るさのファクターにしてやります。
(フラットシェーディング)

ただしこの方法だと面単位で明るさが変わるので面と面の境目で色が異なりちょっと不自然ではあります。
面の頂点の法線ベクトル毎に計算して面の内部でも色をなめらかに変化させればきれいな表示になります(グローシェーディング)が、当然計算時間がかかりますし、何より1つの div (の border) の中で色を変化させることはできません。

一応参考までにフラットシェーディングとグローシェーディングの見え方の違いを、他所からパチってきた画像で紹介しておきます。
左が面の法線ベクトルだけで計算したフラットシェーディング、
右が面の各頂点の法線ベクトルで計算したグローシェーディングです。
どちらもポリゴン数は同じです。


それはともかくとして、内積を使えば視線ベクトルに対して斜めになればなるほど暗くなるという表現ができることがお分かりかと思います。

次に遠い面ほど暗くなるですが 、実はこれもまったく同じロジックです。面の遠近によって何か処理をしているわけではありません。
下図を見てもらえばわかるように、遠い面は内積値(絶対値)が小さくなるのです。
というわけで面の裏表判断に使った内積値を流用することで余分な計算することなしに面の明るさを変更するためのファクターを得ています。




と、ここまで書いて、やっぱり遠くの面はより暗い方がヘッドライトで照らしてる感があっていいなと思い直しました。
やってみた結果がこれです。
内積に加え、面までの距離も考慮しました。
面までの距離は div の z-index として算出済ですので計算に負荷はかかっていません。


以上で長かった3D迷路の話は終了です。
お疲れ様でしたw

0 件のコメント:

コメントを投稿