一般社団法人 全国個人事業主支援協会

COLUMN コラム

みなさん、こんにちは。

今回で、C#でOpenGLを使う方法についての紹介は最後になります。

(※よりテクニカルな話題を、突発的に紹介することがあるかもしれませんが…)

前回は座標変換行列について話しました。

今回は、座標変換をOpenTKで実現する方法についてお話します。

 

●OpenTKによるワールド座標系からスクリーン座標系への一連の変換

それでは、前回話しました座標変換行列をOpenTKで書いてみましょう。

ワールド座標系→ビュー座標系→射影座標系→スクリーン座標系までの変換は、OpenTK.Matrix4 クラスの機能を使えば簡単に求められます。

ちなみに、この一連の変換を行う関数を、CalculateWorldToScreenと名付けましょう。

関数の引数には、カメラの視点/注視点/上ベクトル/near/far(それぞれワールド座標系での値)、カメラの縦方向の視野角(ラジアン単位)、スクリーン座標系での幅と高さ(ピクセル単位)を取ります。

ワールド座標系からカメラ座標系への変換行列は、OpenTK.Matrix4.LookAt関数を使って計算できます。

また、カメラ座標系から射影座標系への変換行列は、OpenTK.Matrix4.CreatePerspectiveFieldOfView関数を使って計算できます。

 

射影座標系からスクリーン座標系への変換(=ビューポート変換)は、自分で計算します。

射影座標変換後の立方体をX-Y平面から見ると、図の左のようになります。

左上の座標が(-1.0, 1.0) に、右下が(+1.0, -1.0)ですが、スクリーン座標変換をすると左上が(0, 0)に、右下が(w, h)になるような変換を行います。

※図は OpenGLのglViewPort関数のもので、スクリーン座標変換後の+h方向の向きが上になっていますが、+h方向が下向きになるようにしてください。

すると、変換後の x = width / 2 × (変換前の x + 1)、変換後の y = height / 2 × (-変換前の y + 1) となります。

 

もし座標変換をシェーダに任せたい場合は、スクリーン座標変換を除いた座標変換行列を、GLSLのシェーダ定数にそれぞれセットする形で行います。

スクリーン座標変換は、CPU側で OpenTK.Graphics.GL.Viewport(0, 0, OpenTK.glControl.Width, OpenTK.glControl.Height); を呼んでやればよいです。

 

余談ですが、上記一連の流れの逆行列を作れば、スクリーン座標系のピクセル値からワールド座標系の3次元の座標を求めることもできます(※後日談でお話しするかもしれません)。

 

いかがでしたしょうか?

今後も3DCG関連でお話することがありましたら、発信していきたいと思います。

The following two tabs change content below.

佐藤 潤一

最新記事 by 佐藤 潤一 (全て見る)

この記事をシェアする

  • Twitterでシェア
  • Facebookでシェア
  • LINEでシェア