描画領域とその方法の設定 (透視図法、正射影法)

視野錐台に含まれる領域が、実際に画面に表示されます。

透視図法 (Perspective)

DeviceインスタンスのTransform.Projectionプロパティ (射影トランスフォーム行列) にPerspectiveFovLHメソッドで作成した行列を設定します。

public static Matrix PerspectiveFovLH(
    float fieldOfViewY, // 視野角 (カメラの画角) [ラジアン単位]
    float aspectRatio,  // アスペクト比 (空間の高さを幅で割った値)
    float znearPlane,   // 近クリップ面までの距離
    float zfarPlane     // 遠クリップ面までの距離
);
Matrix.PerspectiveFovLH(Single,Single,Single,Single) | MSDN

PerspectiveFovLH

  • Perspective … 透視図法 (遠近法)
  • Fov (Field Of View) … 視野
  • LH (Left-Handed cartesian coodinates) … 左手系

計算式

このメソッドは、

h = cot( fieldOfViewY / 2 )
w = h / aspectRatio

のような演算を行います。演算結果の行列は、

w 0 0 0
0 h 0 0
0 0 zfarPlane / ( zfarPlane - znearPlane ) 1
0 0 -znearPlane * zfarPlane / ( zfarPlane - znearPlane ) 0

であり、コードで表すと次のようになります。

float h = 1.0f / ( float )Math.Tan( fieldOfViewY / 2.0f );
float w = h / aspectRatio;

Matrix matrix = new Matrix();

matrix.M11 = w;
matrix.M12 = 0.0f;
matrix.M13 = 0.0f;
matrix.M14 = 0.0f;

matrix.M21 = 0.0f;
matrix.M22 = h;
matrix.M23 = 0.0f;
matrix.M24 = 0.0f;

matrix.M31 = 0.0f;
matrix.M32 = 0.0f;
matrix.M33 = zfarPlane / ( zfarPlane - znearPlane );
matrix.M34 = 1.0f;

matrix.M41 = 0.0f;
matrix.M42 = 0.0f;
matrix.M43 = -znearPlane * zfarPlane / ( zfarPlane - znearPlane );
matrix.M44 = 0.0f;

近クリップ面のサイズによる指定

視野角ではなく近クリップ面のサイズで指定するならば、PerspectiveLHを用います。

public static Matrix PerspectiveLH(
    float width,       // 近クリップ面の幅
    float height,      // 近クリップ面の高さ
    float znearPlane,  // 近クリップ面までの距離
    float zfarPlane    // 遠クリップ面までの距離
);

演算結果の行列

2 * znearPlane / width 0 0 0
0 2* znearPlane / height 0 0
0 0 zfarPlane / ( zfarPlane - znearPlane ) 1
0 0 znearPlane * zfarPlane / ( znearPlane - zfarPlane ) 0
Matrix.PerspectiveLH(Single,Single,Single,Single) | MSDN

正射影法 (Orthography)

PerspectiveLH (透視図法) ではなく OrthoLH (正射影法) を用いることで、3面図で使用されるような奥行きのない表示にできます。

public static Matrix OrthoLH(
    float width,        // 表示領域の幅
    float height,       // 表示領域の高さ
    float znearPlane,   // 表示領域の最小のZ値 (近クリップ面)
    float zfarPlane     // 表示領域の最大のZ値 (遠クリップ面)
);

演算結果の行列

2 / width 0 0 0
0 2 / height 0 0
0 0 1 / ( zfarPlane - znearPlane ) 1
0 0 znearPlane / ( znearPlane - zfarPlane ) 0
Matrix.OrthoLH(Single,Single,Single,Single) | MSDN

ウィンドウのアスペクト比との一致

アスペクト比をDeviceインスタンスのViewportプロパティから算出することで、ウィンドウのアスペクト比に適切に一致させられます。

float aspectRatio =
    ( float )this.device.Viewport.Width /
    ( float )this.device.Viewport.Height;