Utils3D.projectVectors で 3D 表現の次なるステージへ(2)
2009/10/29 21:09 - AS3.0
前回は、3D 表現をおこなうにあたってクリアしなければならない点として次の二つが考えられるのではないか、という指摘をしました。
- 遠近表現
- Zソート
Matrix3D.transformVector() を使って、どのようにそれら二つを実装していたのか、というのが今回の話です。
Matrix3D.transformVector() は、引数として指定した三次元座標に変換行列を適用した結果を、三次元座標として返すものです。 引数、返り値、ともに Vector3D になっています。
Vector3D でZソートということなら、特に説明する必要はありませんよね。 よって、遠近表現の話に移ります。
ここでいう遠近表現というのは、遠いものは小さく見え、近くのものは大きく見えるという現象を計算でどのように扱うかということです。
いろいろな書籍や、解説サイトなどを総合すると、遠近表現の公式は以下のように抽象化できます。
頂点に、スキンとして DisplayObject を割り当てた場合、その DisplayObject の scaleX と scaleY に上記公式で得られた値を適用すると、近くに寄ると大きくなり、遠くに離れると小さくなる、という見栄えが実現できます。
これは Matrix3D.transformVector() と Vector3D、そして PerspectiveProjection を使って、以下の手順に従えば実装できます。
1行目では、三次元座標に変換行列を適用して、新たな三次元座標を求めています。
2行目では、新たに求めた三次元座標のZ座標値を用いて、先ほど述べた遠近表現の公式に則った値を取得、そしてそれを Vector3D の w プロパティに格納しています。 その際、PerspectiveProjection の focalLength を使います。
3行目では、遠近表現の公式で求めた値を DisplayObject のスケールに適用し、サイズを変えています。
このような手順を踏むことで、遠近表現が実装できるわけですが、ご覧のとおり、この手法では頂点の数だけ Matrix3D.transformVector() を実行しなければなりません。
例えば頂点を100個設定すると、ENTER_FRAME のたびに Matrix3D と Vector3D を使った計算が100回呼び出されたり、なんてこともあるわけです。
そして、どうも Matrix3D と Vector3D を使った処理というものはけっこう重いもののようで、頂点の数をやたらめったら増やすことはできません。
このやり方には、そのような問題点があります
でいよいよ本題。Utils3D.projectVectors を使ってどうするのか、というのが次回のテーマです。
ところで補足ですが、遠近表現の公式 1 / (1 + z) については、「Flash Math & Physics Design:ActionScript 3.0による数学・物理学表現[入門編]」の第4章「3次元空間で回転するデジタルクロック」が参考になろうかと思います。
ここの70ページに「3次元空間の考え方」ということで図入りで説明がありますよ。
興味のある方はご覧になってはいかがでしょうか。
シリーズ
- Utils3D.projectVectors で 3D 表現の次なるステージへ(4)
- Utils3D.projectVectors で 3D 表現の次なるステージへ(3)
- Utils3D.projectVectors で 3D 表現の次なるステージへ(1)