・NearClipping
1.近いものはちゃんと描けない。
Direct3DIMで、TLVertexを使った場合や
自分でポリゴンの描画プログラムをかく場合はこれが問題になります。
@あまりz値が視点に近い頂点を持つポリゴン
頂点の計算をするときに0除算やオーバーフローの可能性が出てきます
A視点の後ろ側まで伸びているポリゴン
例えばp1(0,1,1),p2(0,1,-1)があるとします。
これは、上を後方に向かって直線が通っているように見えるはずです。
これをそのままスクリーンに投影すると(スクリーンまでの距離d=1)
x = x * d / z;
y = y * d / z;
p1'(0,1),p2'(0,-1)となります。
これは、目の前に縦に棒が立っているように見えるはずです。
2.じゃあどうしようか?
ポリゴンを切る
どこか適当なところでポリゴンを切ってやります。
Direct3DIMでD3DLVeretexやD3DVertex使った場合は、z=1の平面で切るようです。
1という距離があまりにも遠い、つまり遠くのものまで切ってしまうという場合は
すべてのオブジェクトを拡大する事によって1という距離が
そんなに遠くではなくなるようにします。
3.Aでいこう。でもどうやってポリゴンをきるの?
とりあえず三角形の場合についてのみ考えます。
手順としては以下のようになります。
@ポリゴンをきる必要があるかどうかを調べる
すべての頂点のzの値が切断面のzの値より大きい場合
ポリゴンをきる必要はない
Ai = 0とするp[]は三角形の頂点
B頂点p[i]が切断面の向こう側にあるならリストにインデックスを追加
C頂点p[i]と頂点p[i+1]を結ぶ線分と分断面の交点を求める
交点があるのならば頂点を生成し、そのインデックスをリストに加える。
Di=2ならば終了そうでなければi++してAへジャンプ
平面と線分の交点の求め方
この場合はかならずz軸に垂直な平面での分断となるために
比較的単純ですむ。
tz = p[i+1].z - p[i].z;
if (abs(tz) > 0.0000001)
{
tz2 = p[i+1].z - d; //dは分断面のzの値
tz3 = tz2 / tz;
newp.x = p[i].x + tz3 * (p[i+1].x - p[i].x);
newp.y = p[i].y + tz3 * (p[i+1].y - p[i].y);
//Textureのuvや頂点の色なども線形補完でよいのなら
//同様にしてもとまる
newp.ux = p[i].ux + tz3 * (p[i+1].ux - p[i].ux);
newp.uy = p[i].uy + tz3 * (p[i+1].uy - p[i].uy);
・・・
}
|