3Dってむずい

3Dゲーム作ってる人はすごいな。
中学レベルの数学知識では行列とか座標変換とか意味わからん。
しかしどんなものでも、資料を何度も読んだりしていればそれがどういうものかが感覚的に少しずつわかってくる。
しつこく何度もぶつかっては砕け散ることを繰り返して、俺はコンピュータの仕組みとプログラミングを身につけてきたのだ。
数学だって、3Dだって、いけるはず。
でもやっぱり時間はかかりそうだ。


さて、DXRubyの3D機能について、きちんと理解できるのはまだ先だが、なんとなく動きそうな雰囲気にはなってきた。
これから考えるべきことは、それをどのようなメソッドとして、機能として、実装するのか、だ。
3DぐりぐりのFPSとかRPGとか、そういうのを作れるものは目指していない。
じゃあ、DXRubyの3D機能として、どういう使い方を想定するのか。


基本的には疑似3Dのゲームを簡単に作れるような感じがよい。
疑似3Dっつーと、例えばスペースハリアーとかアフターバーナーみたいなゲームとしておこう。
このブログでもちょっとしょぼいがアフターバーナーモドキのコードを公開したりしていて、あれは自力で透視座標変換をしている。
そういう処理や拡大縮小の計算は結構計算量が多いから、Rubyで書くんじゃなくてDirectXにやらせてしまいたいと思うわけだ。
それから、マリオカートみたいなゲームの地面の描画。
いくつか細かい機能を追加すれば、テクニックを駆使して実現できそうな気もするが、そういう強引な手法じゃなく、透視座標変換サポートによってスマートに実現したい。
あとは、カルドセプトの戦闘シーンみたいな演出。
立体物の武器がくるくる回ったりするのは難しいかもしれんけど、カードが手前に倒れてみたり、回ってみたりするのは、簡単にできそうなのに2Dではできない。
ついでに東方の背景。
最後に、どーでもいいことだが3D迷路を簡単に作りたい。


逆側から考えてみよう。
3Dの描画ってのは、基本的にはモデルデータがあって、そいつをワールド内での姿勢になるよう回転させて配置、ビュー変換・射影変換して描画となる。
と思う。
画面に作り出される画像は、カメラと物体の位置関係による。
つまり、3Dゲームの座標管理は、画面上のスクリーン座標ではない。
DXRubyでは2Dゲームが基本となるから、全ての座標管理はスクリーン上の座標をベースにしたい。
イメージとしては普通の座標指定に奥行きのzを指定してやれば、奥のほうに行って、つまり中央に寄りつつ縮小される感じだ。
3Dの座標は通常y座標は上に行くほど大きいから、2Dの座標管理とは全く違うことになる。
この時点でモデリングデータを扱うのは大変難しくなるだろう。


DXRubyで目指す疑似3Dとは、簡単に言えば2Dスプライトを3D空間上に配置することだ。
SFCマリオカートでいえば障害物の土管みたいなものを描画する手段。
カメラの範囲に入ってるスプライトが、すべてカメラに対して正面を向くことになる。
たとえばマリオカートを作ろうとすると、自分の後ろにカメラを配置して、自分の移動に沿ってカメラも動かしていく感じをイメージする。
が、それだと3D空間上の障害物の向きを、カメラに対して常に変えていかなければならなくなる。
なんかDirectXってそんなんやる機能があったよーな無かったよーな。気のせいかな。
別の方法としては、カメラを固定してしまって、画面内の物体の位置を自分の移動に合わせて逆方向に動かしていくのがある。
これなら、普通に描画すれば正面を向いているから、画像を回転させる必要すらない。
3D空間のデータがすでにマップとして決まっているマリオカートみたいなものなら前者がやりやすそうで、スペースハリアーみたいなマップなど無いものなら後者がよさそうだ。
が、前者に関してはとりあえず3D空間の座標系というのを作れないとできないわけで、DXRubyでイメージしている座標管理では辛い気がする。
独自の座標系を変換して画面内に配置するビュー変換をRubyで書くか、なんらかの方法を確立してCで書いて提供するかしないといけないだろう。
DircetXの座標系で処理すればいいのかもしれないが、それをすると疑似3Dじゃなくなって本当の3D処理になってしまう。
それは、難しいのだ。
DXRuby的には、あくまでも2Dの延長に疑似3Dを置きたい。


まあ、とりあえず考えてみたのはそんな感じ。
いつものようにぜんぜん確定したものではなく、いままさに考え中なので、どう転ぶかはわからない。
でも本格的な3Dは俺なんかが頑張って作るよりも、例えばEasy3D for Win32のRubyラッパとか作ったほーが絶対いいと思う。
だからDXRubyはそれとは違う方向がよい。