2

私は XNA 4.0 を使用しており、Vector3 を取得して、それを画面上の座標を表す Vector2 に変換しようとしています。Viewport.Project を使用できることはわかっています。これにより完璧な結果が得られますが、これを行うには独自の方法を作成する必要があります。GPU ではなく CPU で、フレームごとにすべての頂点を 2D 座標に変換する必要があります。提供された Project メソッドを使用すると、私が望むよりも少し遅くなります。「z」値も返しますが、これは使用しません。できるだけ簡単な方法で (x, y) を返したいだけです。

これが私がこれまでに思いついたもので、ほぼ正しい結果が得られます。しかし、まだそこまでではありません

    private Vector2 ScreenCoords(Vector3 v)
    {
        return new Vector2(
            viewProj.M11 * v.X + viewProj.M21 * v.Y + viewProj.M31 * v.Z + viewProj.M41,
            viewProj.M12 * v.X + viewProj.M22 * v.Y + viewProj.M32 * v.Z + viewProj.M42);
    }

viewProj はちょうど (viewMatrix * ProjectionMatrix)

画面の中心にある頂点は常に (0, 0) として返されるように見えますが、(カメラを動かすと) 頂点が画面座標を変更するため、結果が少し混乱します。頂点が左に移動すると、投影された X結果が減少し、頂点が下に移動すると、投影結果の Y が増加します。したがって、少なくとも私にはその権利がありますが、それらの変化率は正しくなく、一貫性もありません。

編集:これがその方法です。おそらく最も速い方法です(これは[-1、1]の範囲の座標を返すことに注意してください)

    private Vector2 ScreenCoords(Vector3 v) 
    {
        float 
            w = viewProj.M14 * v.X + viewProj.M24 * v.Y + viewProj.M34 * v.Z + viewProj.M44;
        return new Vector2(
            (viewProj.M11 * v.X + viewProj.M21 * v.Y + viewProj.M31 * v.Z + viewProj.M41) / w,
            (viewProj.M12 * v.X + viewProj.M22 * v.Y + viewProj.M32 * v.Z + viewProj.M42) / w);          
    }

これは、Viewport.Project を使用して 2D 座標を取得する場合との比較です - Project を使用した FPS - ScreenCoords を使用した
81 FPS - いずれかを使用せずに 143 FPS - 152 したがって、フレームごとに多くの投影を行っている他の人には、このようなものをお勧めします。


4

1 に答える 1

2

透視投影には同次座標が必要であることを認識する必要があります。分割する必要があります。

同種因子 W によるコンポーネント。

これは数学です:

Vector4 position = new Vector4(pos3, 1);
Vector4.Transform(ref position, ref worldViewProjection, out position);
position /= position.W;

また、ここで詳細情報を見つけることができます: http://en.wikipedia.org/wiki/Transformation_matrix#Perspective_projection

于 2012-05-07T13:08:08.420 に答える