視野錐台に含まれる領域が、実際に画面に表示されます。
DeviceインスタンスのTransform.Projectionプロパティ (射影トランスフォーム行列) にPerspectiveFovLHメソッドで作成した行列を設定します。
public static Matrix PerspectiveFovLH( float fieldOfViewY, // 視野角 (カメラの画角) [ラジアン単位] float aspectRatio, // アスペクト比 (空間の高さを幅で割った値) float znearPlane, // 近クリップ面までの距離 float zfarPlane // 遠クリップ面までの距離 );Matrix.PerspectiveFovLH(Single,Single,Single,Single) | MSDN
このメソッドは、
のような演算を行います。演算結果の行列は、
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 |
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 |
アスペクト比をDeviceインスタンスのViewportプロパティから算出することで、ウィンドウのアスペクト比に適切に一致させられます。
float aspectRatio = ( float )this.device.Viewport.Width / ( float )this.device.Viewport.Height;