私は 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
したがって、フレームごとに多くの投影を行っている他の人には、このようなものをお勧めします。