物理を解説 ♪
ツイッター用のシェアボタン フェイスブック用のシェアボタン はてなブックマーク用のシェアボタン ライン用のシェアボタン
ツイッター用のシェアボタン フェイスブック用のシェアボタン はてなブックマーク用のシェアボタン ライン用のシェアボタン

3Dプログラムの動作

流行りのライブラリの仕様とは違うかもしれない。
作成:2021/6/19

ポリゴン

プログラマ向けにクォータニオンを説明するという目的で話を続けてきているが,プログラマではない人にも楽しんでもらえるように,割りと当たり前のことから説明しようと思うし,ちょっと大雑把過ぎる説明もする.雰囲気がわかってもらえればいいのだ.

3Dゲームに出てくるキャラクターや物体などは全て点の集まりで表されている.点だけで表すのは効率が悪いので,もう少し頭のいい方法を使う.物体の形状の表面に三角形を並べて覆い尽くすように表し,その多量の三角形の頂点の座標をデータとして持っているわけだ.

三角形の 3 頂点の座標があれば面の傾きが計算できるので,その面の角度によって光の反射具合を計算している.この面の上にリアルな質感の画像を貼り付けることで本物らしさを出しているのである.細かい三角形を使うほど複雑で微妙な形を正確に表現できることになる.しかし三角形の数が増えるほど計算の負担が増えてしまうので,あまり形にこだわらなくてもいい部分には大胆に大きな三角形を使い,上に貼り付ける画像でうまくごまかすことになる.

この方式は「ポリゴン」と呼ばれている.ポリゴンとは「多角形」という意味であり,この方式で表された物体全体のことを指していたのだろうが,それを構成する一つ一つの三角形のことを指すことの方が多い.

この三角形の数のことを「ポリゴン数」と呼ぶ.ゲーム機の性能を比較するために 1 秒間に処理することのできるポリゴン数というのが使われていたこともあったが,今ではポリゴン数だけで画質が決まるわけではないのであまり重要な指標ではなくなった.

キャラクターだろうと岩だろうと壁だろうと,このようなポリゴンで構成されているので,わざわざ区別しないでここでは「オブジェクト」と呼ぶことにしよう.画面の中で元気に動き回るキャラクターだって,首や胴体や腕などの別々のオブジェクトが組み合わさって表示されているだけだ.感傷的な思いは無用である.

これらをそのまま表示しようとしても,おそらく望んだような結果にはならないだろう.それぞれのオブジェクトはデータを作成したときのそのままの方向を向いているので,適切な位置に配置し,適切な方向を向けてやらないといけない.座標データの値を変換してから使う必要があるのだ.

幸いにして,どんな方向を向いた物体であろうとも,「回転軸の方向をうまく決めてやれば」一回きりの回転でどんな姿勢にでも向けることができることが知られている.これは「オイラーの定理」と呼ばれているのだが,オイラーが導いた定理は幾らでもあるので調べようとしても苦労するかもしれない.

この回転の計算にクォータニオンを使うしかし具体的な話は後にしよう.一つのオブジェクトに含まれる全ての座標データを同じように回転させてやれば,オブジェクトが丸ごと向きを変えたことになる.

ここで問題になるのが「原点を中心に」回転することになるという点だ.それぞれのオブジェクトは何らかの原点を基準にして作成されている.その点を中心にして回転してしまうことになるから,ひょっとするとその場で回転するといった感じにはならずに,オブジェクトからかなり離れた点を中心にぶん回されてしまう感じになるかもしれない.

そこで,どの点を中心にして回転させたいかによってあらかじめ原点をずらしてやる必要がある.それは難しいことではない.一つのオブジェクトを構成する座標データを一様に足したり引いたりして調整してやればいいだけである.

ちょっと自信なくなってきた.,クォータニオンの理論のことを知らないままクォータニオンのライブラリの動作について勉強したときに,回転と平行移動を同時に実現する行列について学んだ気がする.今となってはそういう具体的な動作について忘れてしまった.このいい加減な私の説明を読んだあとでちゃんと勉強し直してくださいな.


キャラクターのポーズ

一つのキャラクターが複数のオブジェクトから出来ている場合はもうちょっと面倒だ.,,胴体,首などをそれぞれに違う方向に回転させて,自然なポーズになるように調整してやらねばならない.キャラクターの自然な振り付けを実現するのは至難の業だ.関節の位置がずれて外れてしまったり,全く不自然な方向へ曲がったりしてしまう.

動きを先に決めて表示させようとすると,足が地面にめりこんでしまったりもする.だからといって足を基準にキャラクターの表示位置を決めるようにすると,体全体が全く重力を無視したような上下運動をしているように見えたりして非常に気持ち悪い.

そこで物理学を取り入れたシミュレーション的な計算で自然な動きになるようにしたり,スタジオで本物の人間に動いてもらってデータを取って,それをそのまま使ったりすることも多い.

もちろん著者は「インバース・キネマティクス」や「モーション・キャプチャー」などの用語を知っていてそちらの解説に脱線したい気持ちもあるのだが,本題ではないので堪えているのである.

無事にキャラクターのポーズが決まったら,その全体のデータを同じように回転させればキャラクター全体がポーズを保ったまま向きを変えるようにできるだろう.

話が脇道に逸れてしまったが,テレビゲームで自然にさりげなく実現しているような動きの全ては,座標データの平行移動と回転の繰り返しであることを伝えたかったからである.


カメラを通して世界を見る

ここまでに説明したように,様々なオブジェクトを適切な方向に回転させて,平行移動させて,きれいに並べて風景を作っていくことになる.コンピュータ内の仮想的な世界の上に配置していくわけだ.このときに使っている座標のことを「ワールド座標系」と呼ぶ.

これをそのまま表示してもいいのだが,固定カメラで眺めるような味気ないものとなるだろう.そこで,移動可能なカメラを通して世界を見るというイメージの計算を加えてやる.

そのためにはこの世界の中のカメラの位置と,カメラの向きを決めておく必要がある.そして,この世界に存在する全てのオブジェクトの座標データを,まずカメラ位置を原点とするような座標に書き換えてやる.それから,カメラの方向とは逆方向に全てのオブジェクトに対して回転をかけてやる.こうすれば,カメラを基準とした座標系に変換できる.

こうして変換された後の座標はカメラの立場から見た座標であり,カメラ座標系」だとか「ビュー座標系」だとか呼ばれる.

実は画面に表示されるまでにはもう一段階あって,カメラ視点の 3 次元の座標を,2 次元の画面のどの位置に対応させるかという変換が必要になる.遠近感を考慮することなく投影することもできるし,魚眼レンズを通して見たかのようにすることも可能である.この辺りは座標の回転は関係ない.


計算の省略

色々と書いてきたが,まとめると難しいことではない.一旦全てのオブジェクトをワールド座標系の上で並べ,カメラ座標系に一斉に変換して,レンズの設定による変換を施して2次元の画面に再現する.それだけだ.

1秒に30コマの映像を作りたければ,約0.03秒以内にその全ての計算をやり終えないといけない.それをひたすら繰り返すのである.

しかし毎回その全ての計算をやる必要はない.動かないオブジェクトならば,一度ワールド座標系に配置してしまえば,それはそのまま使える.動くオブジェクトについてだけ計算し直せばいい.

ゲームでシーンが切り替わるときにしばらく待たされたりするのは,動かない多数のオブジェクトの配置をあらかじめ計算していたりする.いや,その場でいちいち回転計算をするのは効率が悪いから,あらかじめ計算したデータをプログラム内に持っていて,それをメモリ上にロードしているだけかもしれない.多分そうだろう.

カメラから遠く離れた場所にあるオブジェクトは小さすぎて見えないだろうから,それも省略してしまおう.カメラからオブジェクトまでの距離を計算して,ある程度以上離れていたらそのオブジェクトは無いものとして扱うのである.とは言っても,全てのオブジェクトまでの距離を計算すること自体が負担になるので,ある程度のエリアに分けておいて,遠くのエリアはごっそり計算を省略するというようなことをする.

それでも,山などの巨大なオブジェクトは遠くにあっても見えないとおかしいから,これらは別扱いにしたりする.

ゲームなどでカメラの向きによって消えたり現れたりする物体があったりするのはそういうことである.


どんなプログラムを前提とするか

さて,いよいよクォータニオンをどう使うのかという話に入ろう.3D表示では回転計算だらけだというのを強調したかったのだが,それほど回転計算は必要ないのかもしれない.動かないオブジェクトのデータはあらかじめワールド座標系で表しておけばいいので,いちいち1コマごとに全てのオブジェクトについて回転計算をすることもないだろう.せいぜい,カメラの向きの変化に合わせて一斉に回転させるくらいだ.

しかしそこまで最適化された構造でプログラムが組まれているとは限らない.いちいち1コマごとに元データから回転計算をしてオブジェクトを配置しているプログラムもあったりするだろう.

それにゲームを作る場合には,ワールド座標系にオブジェクトを配置するためのエディタが別に必要になる.マップ作りのための専用ソフトだ.そのようなソフトではあらゆるオブジェクトはユーザーの指示によって動く必要があるだろう.そういうわけで,エディタプログラムを自作するようなイメージで話を進めていくのも無駄ではない.

いやいや,ちょっと待て.エディタだろうがゲームだろうがあまり区別は必要ないかもしれない.ほとんどあらゆるオブジェクトが,小石に至るまで,主人公に蹴飛ばされて動くように作られているゲームだってあるのだ.しかも,エディタであっても必要なときに必要なオブジェクトだけを動かせばいいだけである.つまり,その時だけ元データからの回転を計算して,ワールド座標系での座標値を更新しておけばいい.それ以外の状況では固定した座標データをそのまま保持して使い続ければいいわけである.

そんなわけだから,特定の用途に特化しないで,あらゆる場合に応用できるようなあまり工夫のないプログラムを自作するイメージで話を進めることにした方がいいだろう.

こんなことを話しているうちに今回はここで時間切れだ.話が長くなってしまったのでクォータニオンを使う話は次回にしよう.なんか段取りが悪くて申し訳ない.



趣味の物理学書店の案内バナー

EMAN物理note出張所の案内バナー