0

数日前、私は 3D プログラミングを始めようと決心し、透視投影に出会いました。次のコードを使用して行列を取得します。

public static Matrix3D ProjectionMatrix(double angle, double aspect, double near, double far)
{
    double size = near * Math.Tan(MathUtils.DegreeToRadian(angle) / 2.0);
    double left = -size, right = size, bottom = -size / aspect, top = size / aspect;
    Matrix3D m = new Matrix3D(new double[,] {
    {2*near/(right-left),0,(right + left)/(right - left),0},
    {0,2*near/(top-bottom),(top+bottom)/(top-bottom),0},
    {0,0,-(far+near)/(far-near),-(2 * far * near) / (far - near)},
    {0,0,-1,0}
    });
    return m;
}

カメラには次のコードを使用します。

Matrix3D Camera
{
    get
    {
        Vector3D cameraZAxis = -this.LookDirection;
        cameraZAxis.Normalize();

        Vector3D cameraXAxis = Vector3D.CrossProduct(this.UpDirection, cameraZAxis);
        cameraXAxis.Normalize();

        Vector3D cameraYAxis = Vector3D.CrossProduct(cameraZAxis, cameraXAxis);

        Vector3D cameraPosition = (Vector3D)this.Position;
        double offsetX = -Vector3D.DotProduct(cameraXAxis, cameraPosition);
        double offsetY = -Vector3D.DotProduct(cameraYAxis, cameraPosition);
        double offsetZ = -Vector3D.DotProduct(cameraZAxis, cameraPosition);

        return new Matrix3D(new double[,]{{cameraXAxis.X, cameraYAxis.X, cameraZAxis.X, 0},
                            {cameraXAxis.Y, cameraYAxis.Y, cameraZAxis.Y, 0},
                            {cameraXAxis.Z, cameraYAxis.Z, cameraZAxis.Z, 0},
                            {offsetX, offsetY, offsetZ, 1}});
    }
}

ただし、モデルまたはワールド マトリックスの取得方法がわかりません。また、前のコードに何か問題がありますか?

4

1 に答える 1

0

マトリックスは、オブジェクトをある「空間」から別の「空間」に変換するために使用されます。立方体であるモデルを考えてみてください。モデルの中心は 0,0,0 で、各コーナーは 5 の範囲にあります。これをワールドに変換するには、Worldmatrix を適用して、これらのモデル座標を世界。

たとえば、モデルを 5、5、5 に「移動」する必要がある変換です。この位置をモデルとそのすべてのポイントに追加することを考えてみてください。これらの新しい座標は「ワールド空間内」と呼ばれます。これで、モデルは、ワールド マトリックスの 5,5,5 の位置に配置されます (以前のモデル センターは、この位置でワールドに存在します)。

ビュー マトリックスを理解するのは少し難しいですが、「カメラを動かすことはできないので、すべてのオブジェクトを反対方向に動かして、カメラを動かしたように見える」と考えるのが最も簡単です。難しそうに聞こえますが、実はモデル空間からワールド空間に変換するのと同じです。

ここで、ワールド空間からビュー空間に変換します。最後に、画面に表示する必要があります。明らかに、画面は 2D であり、まだ 3D シーンがあるため、3D オブジェクトをビュー空間に変換する方法が必要です。これは、さまざまな種類の投影で実現できます。2 つの重要なものは、正射影と透視投影です。実際、これは Z コンポーネント (画面のような 2D サーフェスにはありません) と画面解像度を使用して、目に見える世界を画面空間に「投影」します。

これらはすべて、行列を使用して簡単に実現できます。変換ごとに 1 つずつ開始することをお勧めします。公平を期すために、それは必要ありません。画面スペースでデータを直接提供することもできますが、これは実用的ではありません。たとえば、モデルが直接使用できるようにモデル化されている場合に発生する World マトリックスが必要ない場合は、Matrix.Identity を使用します。同じ番号。また、ビューの恒等行列は、カメラを世界の 0,0,0 に配置し、Z 軸を見下ろすようなものです (どの軸は、使用する座標系に大きく依存します)。

シェーダーの最終的なマトリックスを取得するには、通常、これらすべてのマトリックス (または乗算によって結合されたもの) をシェーダーに渡します。固定関数パイプラインを使用する場合、通常、それらを提供するメソッドがあります。投影は通常固定されていますが、スナイパーライフルのズームや魚眼効果などの視覚効果を適用するために変更できます。もちろん、カメラ マトリックスは、カメラの移動と回転に使用されます。また、ワールド マトリックスは、シーン内のオブジェクトの配置、プレイヤーの移動、ドアの回転などに使用されます。

免責事項:これは私が自分ですべてを理解した方法であるため、数学的に正しい説明ではありませんが、OPの助けになるかもしれません.

主題全体をよりよく理解するために、これを読むことができます。

于 2012-06-21T14:04:36.357 に答える