/**/

チュートリアル 32:
カメラビュー

このチュートリアルでは、カメラビューを設定する方法、および、jit.gl.handle を使ってGLグループオブジェクトを配置し、回転させる方法を紹介します。その中で、カメラビューを構成するコンポーネントのグループ(カメラ位置、カメラが注視する点、“up”ベクトル、投影の種類、レンズのアングル、クリッピング平面)ついて説明します。

・Jitter Tutorial フォルダにある 32jCameraView.pat というチュートリアルパッチを開いて下さい。

パッチの左中央部に、mister という名前の jit.window オブジェクトがあります。このウィンドウが、OpenGLが描画を行なうデスティネーションになります。 jit.window オブジェクトがアトリビュートのためのアーギュメント @depthbuffer 1 を持ち、これによってデプスバッファの生成を指定している点に注意して下さい。デプスバッファにより、OpenGL レンダラは、カメラとの空間的な距離に基づいて、どの描画コマンドがカメラに近いピクセルとして見えるかを判定することができます。デプスバッファを用いない場合、OpenGL は「ペインタアルゴリズム」と呼ばれるものを使用します。この場合、描画コマンドによる最終的な結果は、描画コマンドが実行される順序に対応します。

訳注:ペインタアルゴリズム(画家のアルゴリズム)とは、最初に描画したものの上に次々と上書きしていく描画法のことです。デプスバッファ(Zバッファ)やペインタアルゴリズムは、隠面消去(前のものに隠れて見えない部分の消去)を行なう場合に用いられます。

・Start Rendering と表示された toggle オブジェクトをクリックして下さい。

大きなグレイの円と何本かの黄色い線が見えます。これらは jit.gl.gridshape オブジェクトの2つのインスタンスによって描かれているものです。jit.gl.gridshape オブジェクトは、球、トーラス、円柱、立方体、平面、円といった様々な 3Dのシェイプを描画することができます。ウィンドウに描かれているグレイの円は実際には球で、パッチ内の Grey Shapeと表示されたセクションで描かれています。黄色い線は実際には平面で、パッチ内の Yellow Plane と表示されたセクションで描かれています。黄色い平面のレンダリングには、poly_mode 1 1 が指定されています。これは、平面の前面と背面の両方が、塗り潰されたポリゴンではなく、アウトラインによるポリゴンによって描画されるということを意味します。メッセージボックスの poly_mode $1 $1 に接続された toggle オブジェクトをオフにすると、塗り潰されたポリゴンによってレンダリングされた面を見ることができます。


mister という描画コンテキスト

・パッチのGrey Shapeセクションにある scale 0.3 0.3 0.3 というメッセージボックスをクリックし、その後、shape torus と書かれたメッセージボックスをクリックして下さい。グレイのドーナツ状のものが見えるはずです。

lighting_enable $1 というメッセージボックスに接続された toggle オブジェクトをクリックし、その後、smooth_shading $1 というメッセージボックスに接続された toggle オブジェクトをクリックして下さい。それでは、ライティングとスムースシェーディングが施された、3Dのグレイのトーラスから見ていきましょう。

デフォルトでは、JitterのGLグループオブジェクトのライティングとスムースシェーディングは無効になっているため、これらをオンにする必要があります。ライティングの詳細はチュートリアル36で取り上げます。


スムースシェーディングとライティングを有効にしてレンダリングしたシェイプ

・パッチの Camera View セクションにある jit.gl.render axes と表示された toggle オブジェクトをクリックして下さい。

ウィンドウの中央から右への赤い線と、中央から上への緑の線が見えるはずです。これらはそれぞれ x 軸と y 軸になっています。この軸によってシーンの原点が見つけやすくなります。デフォルトでは、カメラの位置は[ 0. ,0. ,2.]、カメラが注視する点(lookat)の位置は[ 0. ,0. ,0. ] なので、カメラは z 軸に沿ってシーンの原点をまっすぐに見ています。そのため、カメラが見ている向きに沿ったz軸を表す青い線は見えていません。


座標軸を表示

・camera positionというラベルの下の x の値を 1. にセットして下さい。カメラの位置が [ 1. ,0. ,2. ] になり、注視している点は [ 0. ,0. ,0. ] のままなので、z 軸の青い線が見えるようになります。


別の視点での軸

・camera position の x の値を 6.、y を -6.、z を 6. にセットして下さい。これで、カメラ位置は [ 6 ,-6 ,6 ] になります。黄色い平面と軸が実際には有限であることがわかると思います。


平面の端を見る

これまで、y 軸がカメラビューに対して常に上を向いていました。これはデフォルトの“up”ベクトルが [ 0. ,1. ,0. ] すなわち y の単位ベクトルであったためです。

・up vectorというラベルの下の y の値を 0. に、z の値を 1. にセットしてみましょう。ビューが回転し、今度は z 軸の青い線が上を向いているのがわかります。


別の“up”ベクトルの使用

カメラを原点から離れた場所へ移動させるにつれて、トーラス、平面、軸が小さくなることに気付いたでしょう。これは、デフォルトのビューモードがパースペクティブプロジェクション(透視投影)を用いているためで、私たちが存在している3次元の世界で物体を見る場合と同様なものです。あなたがカメラのレンズに精通していれば、これがレンズ角に依存していて、大きな視野に対応するためにレンズ角を大きくすると、対象物が小さくなるということを知っているでしょう。これと同様に、視野を広げるために透視変換のレンズ角を変更することができますが、その場合オブジェクトはさらに小さくなります。

・デフォルトのレンズ角は45度です。lens_angle $1 というメッセージボックスに接続されたナンバーボックスを変更して、60度くらいに設定して下さい。


60度のレンズ角を使用

OpenGLがサポートするもう1つの投影方法に、オーソグラフィックプロジェクション(平行投影)があります。この投影法では、カメラ位置によってオブジェクトの大きさが縮小されることはありません。オーソグラフィックプロジェクションは、メカニカルエンジニアリングのような業務に使われる3D CADソフトウェアで一般的なものです。Q-Bert のような初期のビデオゲームの多くもまた、オーソグラフィックプロジェクションを使用していました。orthographoc projectionと表示された toggle ボックスをクリックすることによって、パースペクティブプロジェクション(透視投影)とオーソグラフィックプロジェクション(平行投影)を切り替えることができます。ortho 1 というメッセージは、オーソグラフィックプロジェクションに切り替えるものです。オーソグラフィックプロジェクションをオンにしてカメラを移動させた場合、オブジェクトが小さくなるようには見えないはずです。しかし、レンズ角を変更した場合には、視野が変化し、視野に比例してオブジェクトの大きさが変化します。


オーソグラフィックプロジェクション(平行投影)を用いたシーンの表示

toggle をもう一度クリックし、ortho 0 メッセージを送信してオーソグラフィックプロジェクションをオフにして下さい。

カメラビューの中で、カメラからの距離によってレンダリングを行なう範囲を決定する「クリッピング平面」について調べてみましょう。OpenGLには、near クリッピング 平面と far クリッピング平面があります。そして、この2つの平面の間にあるジオメトリだけがレンダリングされます。クリッピング平面は、clip_near と clip_far メッセージを用いて、視線ベクトルに沿ったカメラからの距離の値で指定されます。デフォルトでは、near クリッピング平面は0.1に、farクリッピング平面は100に設定されています。

訳注:「ジオメトリ」は「形状」を意味する言葉ですが、3DCG では 3D 空間にある物体の座標をスクリーン座標に変換することを「ジオメトリ処理」と呼びます。ここでは、このジオメトリ処理を行なう対象を「ジオメトリ」と呼んでいます。

・near クリッピング平面の値を10に、far クリッピング平面の値を12に設定してみて下さい。黄色い平面のうち、クリッピング平面の外側が見えなくなり、手前側と後ろ側のエッジが表示されているはずです。


より狭い範囲に設定されたクリッピングプレーンを使用

・near クリッピング平面をデフォルトの 0.1に戻し、far クリッピング平面もデフォルトの100に戻して下さい。

これまで、カメラは常に原点の[ 0. ,0. ,0. ]を向いていました。lookat の x の値を3. に変えると、カメラが注視する点は [ 3. ,0. ,0. ] になります。

・パッチ内のUI Rotation and Position Controlと表示されたセクションにある position 3. 0. 0. と書かれたメッセージボックスをクリックし、トーラスを [3. ,0. ,0. ]の位置に移動させてましょう。トーラスは、再び視野の中心点 [ 3. ,0. ,0. ] に置かれます。


カメラの視点とシェイプの位置の変更

ここでは、position 3. 0. 0.メッセージ を、トーラスに送るだけではなく、jit.gl.handle オブジェクトにも送信しています。jit.gl.handle オブジェクトは、3Dシーンの中でのオブジェクトの移動や回転にマウス情報を使用するGLグループオブジェクトです。jit.gl.handle オブジェクトは、jit.gl.gridshape オブジェクトと同様に名前を持った描画コンテキストを必要とし、その中に描画を行ないます。しかし jit.gl.gridshape と異なる点は、描画コンテキストのデスティネーションの中でのマウスの動きをMaxメッセージに変換するユーザインタフェースオブジェクトでもあるということです。

このパッチでは、jit.gl.handle オブジェクトからのメッセージは、jit.gl.gridshape オブジェクトに送信されています。メッセージは route rotate position オブジェクトにも送信され、フォーマットされているため、送信の内容を正確に見ることができます。しかし、これは jit.gl.handle オブジェクトから送信される情報を表示するだけのもので、「シーンの裏側」で何かを行なっているわけではありません。

トーラスをクリックしてマウスをドラッグすると、jit.gl.handle オブジェクトによって、バーチャルなトラックボールのようにトーラスが回転し始めます。ドラッグする際ににコマンドキーを押し下げたままにしておくと、トーラスを上下左右に移動させることができます。また、ドラッグする際にオプションキーを押し下げたままにしておくと、トーラスが近付いたり離れたりするように移動させることができます。このようなマウス操作を行なう際にシフトキーを使うと、1つの軸に対してのみ動作するように制限されます。

jit.window オブジェクトの中のトーラスをクリックして、トーラスの向きを操作してみて下さい。jit.gl.handle オブジェクトがどのように2次元のマウス情報から3次元の回転情報に変換するのかを体感してみて下さい。


jit.gl.handle オブジェクトを使ったオブジェクト位置の操作

jit.gl.render オブジェクトで表示できる座標軸と同様に、jit.gl.handle オブジェクトは回転するオブジェクトの x(赤)、y(緑)、z(青)平面に対応する色の付いた線を表示します。この線は操作の対象となるオブジェクトの周囲に円として表示されます。マウスは、その時点の視野の最前面にある2つの円の軸をコントロールします。それらの円をオブジェクトの後ろに移動させるように画像の操作を行なうことによって、次のマウスクリックで別の2つの軸をコントロールできるようになります。修飾キー(訳注:オプションキーやコマンドキーのこと)は、オブジェクトを3つの軸上で移動させることによってオブジェクトの位置を変えられるようにします。jit.gl.handle オブジェクトは、接続されたGLグループオブジェクトの rotateposition アトリビュートを設定するために、関連したメッセージを出力します。jit.pwindow にGLコンテキストを表示している場合、jit.gl.handle を使ってズームするためには、Maxの Help in Locked Patchersオプション(これはOptionsメニューの下で変更することができます)を無効にしておく必要があることに注意して下さい。これを行なっていないと、オプションキーを押しながらクリックした場合、jit.pwindow に対するヘルプパッチが表示されてしまいます。

まとめ

OpenGLシーンのカメラビューを構成するいくつかのコンポーネントと、それらをコントロールする jit.gl.render オブジェクトで必要となるアトリビュートについて調べてきました。 camera アトリビュートはカメラ位置を指定し、up は上向きベクトルを、lookat はカメラが注視する位置を、ortho はオーソグラフィックプロジェクション(平行投影)とパースペクティブプロジェクション(透視投影)のどちらを使うかを、near_clipfar_clip はクリッピング平面を指定します。ライティングとスムースシェーディングに関するアトリビュートは、ジオメトリを扱うGLグループオブジェクト(この場合は jit.gl.gridshape オブジェクト)の lighting_enable smooth_shading アトリビュートを設定することによって有効になります。

jit.gl.handle オブジェクトは、マウスとキーボードの修飾キーを使ってGLグループオブジェクトの回転や移動を行なうことを可能にします。jit.gl.handle オブジェクトは、有効な描画コンテキストの名前を取り、自分自身をそのコンテキストに接続します。そして、jit.gl.handleに接続された、同じコンテキストを使用しているオブジェクトに対してメッセージを送信し、そのオブジェクトの回転( rotation )や 位置( position )を設定します。