3D表示で「等倍表示」を考える 前編

特にそうですが、ギャルゲーで表示に3Dを使おうとすると問題になるのが

3D空間上で元々のテクスチャと等倍となる座標ベクトルって何なのだろうか・・・?

という問題です。システムを作ろうとしている人でこれで悩む場合はかなりあります。

本当は3Dの座標変換を正しく勉強してこのあたりがどうなるかを勉強するのが正しいのですが、ネタがないので何となく投入です。

基本はDirect3DのMatrix処理を考えます。Direct3Dで3Dを表示できるレベルの知識があれば十分です。直接の計算についてはDirect3Dのヘルプを見てください。

ワールド座標上での「等倍表示位置」を求めることを目的とする

大前提ですね。ワールド座標が「3D座標」に一番近い座標系ですので。

ワールド座標でなくて直接ディスプレイ上の座標を指定するのであれば変換後座標の指定(D3DFVF_XYZRHW)を指定して

それぞれの座標を指定すればそれで完了です。

ビュー変換

ビュー変換はDirect3DではD3DXMatrixLookAtLHを使います。

状態としてはカメラが原点からZ軸方向にZeだけ後ろに下がった位置からZ軸正方向を向いている状態を考えます。

このとき、それぞれのベクトルはだいたいこの値を与えることが多いです。

視点ベクトル(カメラがある位置) (0,0,-Ze) Zeは後で計算される
注視ベクトル(カメラが向いている方向) (0,0,Zp) (Zp > -Ze)
上方ベクトル(空間上で「上」がどこか) (0,1,0) 通常はY軸正方向

この中で問題になるのはZeだけです。Zeはこの問題を考える時に式に出てきます。

この変換を設定すると、以下のような行列が完成します。

matView = ¥begin{pmatrix} 1 & 0 & 0 & 0 ¥¥ 0 & 1 & 0 & 0 ¥¥ 0 & 0 & 1 & 0 ¥¥ 0 & 0 & Ze & 1 ¥end{pmatrix}

射影変換

射影変換はDirect3DではD3DXMatrixPerspectiveFovLHかD3DXMatrixPerspectiveLHを使います。エフェクト的に前者の方が考えやすいので前者を使います。

Y方向視野角 ¥theta 自分で任意の値を設定できる
アスペクト比 aspect 表示するウィンドウのアスペクト比と同じ
近クリップZ位置 N 後で計算される
遠クリップZ座標 F 後で計算される

で、これを設定した行列はこのようになります。

matProj = ¥begin{pmatrix} ¥frac{¥cot(¥frac{¥theta}{2})}{aspect} & 0 & 0 & 0 ¥¥ 0 & ¥cot(¥frac{¥theta}{2}) & 0 & 0 ¥¥ 0 & 0 & ¥frac{F}{F - N} & 1 ¥¥ 0 & 0 & -N ¥times ¥frac{F}{F - N} & 0 ¥end{pmatrix}

ちょっとわかりづらいので置き換えをして

matProj = ¥begin{pmatrix} Sx & 0 & 0 & 0 ¥¥ 0 & Sy & 0 & 0 ¥¥ 0 & 0 & Sz & 1 ¥¥ 0 & 0 & -SzN & 0 ¥end{pmatrix}

となります。

ワールド座標=>射影空間への変換を手動でやってみる

ワールド座標から射影空間への変換は今表した行列を順番にかけ算していくだけなんですが、わかりにくいと思いますので結果だけさくっと書きます。

ワールド座標(X,Y,Z)から射影空間上の座標(X’,Y’,Z’)への変換は

X’ = SxX / (Z + Ze)

Y’ = SyY / (Z + Ze)

Z’ = (SzZ – Sz(N – Ze)) / (Z + Ze)

が成立する

となります。

この結果を使うと等倍座標がどこになるか、というよりは等倍座標をどこにするかを決定できます。自由度があるのでいくつかの変数を固定しますが・・・。

前編はここまでです。数学の知識が必要になりますが、わからなければ結果だけ使ってもこの場合(ADVシステムレベル)ならあまり問題になりません。

普通に3Dを使う時にはちゃんと行列変換やら何やらは勉強しないとだめですからね~

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

この記事のトラックバック用URL