1

DirectXで、.objファイルからモデルをロードおよびレンダリングできる単純な「エンジン」を作成しました。私が作成したオブジェクト、たとえば、座標が-1.0〜1.0の範囲内にある単純な立方体の場合は問題なく機能します。ただし、異なる単位を使用し、座標が-2kから2kの範囲内にあるモデルをロードすると、デプスバッファーに完全には収まらない巨大なものになるため、1つの巨大な脚または同様の効果のように見えます。

どこかで読んだことを覚えていますが、最近DXをたくさん読んだので、どこに何があったのか思い出せません。だから私の質問は、異なるユニットを使用する異なるモデルをロードできるようにしたい場合、それらがすべて同じサイズで画面にうまく収まるようにするための最良の方法は何ですか?

オブジェクトのロード時に値を変換しようとすることもできますが、変換行列またはシェーダーを使用するDirectXの方法が他にもあるでしょうか。

4

1 に答える 1

2

最も簡単な方法は、モデルに最大の範囲が含まれているコンポーネントを見つけ、その値を使用してモデルを均一にスケーリングすることです。最大の範囲を見つけるには、モデルの境界ボックスを計算し(wavefront obj。ファイルで既に提供されている場合を除きますが、とにかく確認したい場合があります)、ボックスの寸法を範囲として使用して比較します。これにより、インポートされたすべてのモデルが単位範囲に縮小されます。

たとえば、374 * 820 * 512ユニットをカバーするバウンディングボックスを備えたモデルがある場合、最大のものは820のY軸であるため、820で縮小する必要があります(すべてのコンポーネントを820で除算します)。D3DXMatrixScalingこれは、私が間違っていなければ、で初期化できる均一なスケーリング行列で便利に達成できます。バウンディングボックスが2つのベクトル(最大頂点と最小頂点)で与えられていると仮定して、これらのベクトルの差を計算し、最大値を選択して、その逆行列を行列のスケーリング係数として使用します。

D3DMatrix mScale;
D3DVector mx, mn;
obj->getBoundingBox(&mn,&mx);
float scale = 1.0 / max(mx.x - mn.x, max(mx.y - mn.y, mx.z -mn.z));
D3DXMatrixScaling( &mScale, scale, scale,scale);

あとは、レンダリングパイプラインにマトリックスを挿入するだけです。

バウンディングボックスの計算に関しては、モデルのすべての頂点で、最小成分と最大成分を(互いに独立して)維持する単純なループで実行する必要があります。

D3DVector mn, mx;
mn.x = mn.y = mn.z = MAX_FLOAT;
mx.x = mx.y = mx.z = - MAX_FLOAT;
for (int i = 0; i < numVertices ; i++) {
   mn.x = min(mn.x, vertex[i].x);
   mn.y = min(mn.y, vertex[i].y);
   mn.z = min(mn.z, vertex[i].z);
  // same for mx using max
}

もちろん、ビューが単位ボックスよりも広い領域をカバーしている場合は、スケーリング係数を使用する必要がある場合があります(ただし、これが使用しているようです)。

于 2012-12-29T03:19:56.890 に答える