描画処理の基礎

Last update: <2004/03/13 17:31:40 +0900>
ここでは,3次元空間におけるモデルを計算機で描画表示するまでの処理について説明しています.また説明に伴って出てくる用語についても,できるだけ詳しく記述するようにしています.用語は日常的に使うものから専門的なものまであります.専門書などを読む場合,こうした語彙の有無が理解に影響しますので,知識として覚えておきましょう.

描画処理の概要

計算機で3次元モデルを描画する場合,手順は大きく4つに分けられます.すなわち,
  1. 映像の視点の位置を設定すること
  2. モデルの配置を設定すること
  3. 視野の大きさを設定すること
  4. 画面の大きさを設定すること
です.この手順を実際のカメラ撮影になぞらえて説明していきます.

まず視点の位置を設定することとは,三脚を組み立ててカメラを配置することです.普段なにげなく構えるカメラですが,これを算術的にあらわそうとすると,空間的な位置(x,y,z)と方向(ヨー,ピッチ,ロール)の6つのパラメータによって定めることができます.つまり,視点を設定するとはこの6つのパラメータを決めることに他なりません.

OpenGLでは,右手の親指と人差し指,中指をそれぞれ直交させ,その方向にそれぞれx,y,z軸をとる右手系の空間座標系を使用しています.ここではz軸(中指)負の方向がカメラの向いている方向(写真の通り)で,y軸が頭上方向(写真の通り)だと考えて下さい.この座標系は基準となり,とても重要です.

図:右手系の座標系(中指の指先から付け根に向かうのが視線方向)

次に描画対象となるモデルを配置します.モデルとは立方体であったり球であったりというような,表示の対象となる物体を意味します.モデルの配置も視点と同様に6つのパラメータによって決められます.

ところで,視点の配置とモデルの配置は非常に密接な関係があります.視点をモデルに近づけることとは,モデルをカメラに近づけることと同じ効果があるからです.このことは後で触れますが,視点の移動とモデルの移動は常に反対の関係にあることを念頭において下さい.視点とモデルの位置姿勢が決定すると視点とモデルの配置関係が定まることになります.

3番目は,視体積の形状を設定することです.視体積とは視野のことで,カメラの場合ならレンズの画角に相当します.広角レンズだと広い範囲の映像を撮影でき,望遠レンズだと狭い範囲を拡大して撮影できます.*5

視体積は通常,四角錘の形をとります.カメラマンのフレーミングを思い出して下さい.視点が四角錘の頂点で,指でフレームを作っているのが四角錘の底面になります.この四角錘が撮影の範囲で,底面が大きく視点に近ければ広角,底面小さく視点から遠いほど狭角になります. 視体積が四角錘の場合,近くにあるものは大きく,遠くにあるものは小さく見えます.これはperspective*6(遠近画,透視図)といいます.カメラでは視体積にあるものをすべてフィルムに投影しますが,コンピュータグラフィクスでも同様で,定義された視体積に入っているモデルはすべて2次元に射影されます.なお,視体積の大きさを定義するパラメータについては後述します.

4番目は画面の大きさを設定することです.カメラの場合,現像したフィルムを印画紙にプリントする必要がありますが,コンピュータグラフィクスでは印画紙の代わりにモニタを使います.4番目の設定は,モニタに表示される大きさを設定することです.

上記のような手順により,計算機上で3次元モデルを描画することが可能となります.


モデルの種類

ここでは計算機によるモデルの表現手法について述べていきます.

まず,モデルの中で最も単純なものは点(point)です. 点は3次元空間上の位置を与えることによって表現されます. 点は他の幾何学的形状の基本要素となりますが,このときは点のことを頂点(vertex)と呼びます.

頂点が2つ集まると線,線分(line)ができます.線は数学的定義によると無限に続くものですが,描画では無限長の線などはあまり意味がありませんので,ここでは2点を結ぶ線分をイメージしてください.

頂点が3つ集まると平面が定まり,三角形が構成されます.描画においては,3点を通る平面などにあまり意味がないので,3点を結ぶ三角形をイメージしてください. 三角形になると面積を持つため,面に様々な属性が導入されます. 例えば面の法線(normal)を決めることができます.法線は面に対する照光処理に用いられます.

頂点が3つ以上集まると,多角形(polygon)や多面体を構成することができます.あらゆる多面体は多角形から構成されていると考えることができます.多角形より構成されている多面体モデルをポリゴンモデル(polygon model)といいます. またポリゴンモデルのように面だけで構成されているモデルを,特にサーフェスモデル(surface model)ということもあります.サーフェスモデルでは面の頂点を定義することで様々な形状を表現できます.

一方,モデルの表面だけでなく中身を数式で表現することもあります.物体の領域を範囲で指定するようなモデルは,中身が詰まっており,論理演算に適用できます.こうしたモデルはソリッドモデル(solid model)と呼ばれています.サーフェスモデルではあらゆる形状でも微小面で近似することで表現できますが,ソリッドモデルでは数式で表わせる形状しか表現できません.

OpenGLではサーフェスモデルを扱っています.

サーフェスモデルでは面による形状の表現をおこなっていますが,面の稜線だけを表示する表現をワイヤフレーム(wire frame)といいます.計算機でワイヤフレームや線分を表示する場合,画面の解像度が粗いとギザギザが生じます.このギザギザはジャギー(jaggy)といいます(図).ジャギーをなくすための工夫として,線の色と背景色の中間色をジャギーに埋めていく方法があります.近くから見ると線がぼやける感じがしますが,遠めで見るとジャギーが消えて滑らかな線に見えます.このようなジャギーをなくす描画手法をアンチエリアシング(anti aliasing)といいます.

図:ジャギーありの線(左)とアンチエリアシングありの線(右)

ところで,点や線,面には色の属性をつけることもできます. 色の指定は光の三原色であるRGBでおこなうのが一般的です.通常の色指定は三原色で十分ですが,4番目の要素として透明度が導入されることもあります.透明度の要素はアルファ(alpha)と呼ばれています.また半透明物質どうしによる色混合をアルファブレンディング(alpha blending)といいます.三原色にアルファ値が加わった場合RGBAと記述することもあります.

面の各頂点に色の属性をつけると,頂点間で補間されながら色がつきます.これをシェーディング(shading)といいます. 面には法線が定義されますが,照光処理をおこなうと法線と光源の位置関係によって明暗が発生します. 各面にそのまま明暗をつけると,隣り合った面同士でも異なった明るさとなります.フラットシェーディング(flat shading)では各面にそれぞれの明るさを割り当てるため,面の境界がはっきり見えてしまいますが,グーローシェーディング(gouraud shading)では隣り合った面の明暗の境界をなくすように明るさのグラデーションをつけています.グーローシェーディングはスムースシェーディング(smooth shading)とも呼ばれます.

図:フラットシェーディング(左)とグーローシェーディング(右)

テクスチャマッピング(texture mapping)とは,面に対して画像を貼り付ける過程のことです.複雑なモデルの設計をおこなわなくとも,表面の画像を平面モデルにテクスチャマッピングすることで,より質感の高いシーンを作成することができます.

視野の種類

前節の視点やモデルの設定は3次元空間でおこなわれますが,グラフィックとして表示されるのは2次元の映像です.ここでは3次元のシーンを2次元に射影する処理について述べていきます.

3次元空間内にあるオブジェクトを2次元平面に射影するのは,ちょうどカメラでフィルム撮影をすることに似ています. カメラマンが写真の構図を考える場合,両手指でフレームを作って前後に動かします.ここで画面の範囲を決定してレンズを選択します.例えば指のフレームが目から遠いほど,見える範囲が小さく拡大率が高いので,望遠レンズを選択することになります.

計算機でグラフィックを生成するときも,見える範囲を決めることになります.見える範囲のことを視体積(view volume)といいます.計算機の場合,カメラの場合と違って視体積は任意の大きさにすることができます.視体積の形状は2通りあります.

図:透視射影変換と正射影変換

(a)透視射影変換(perspective transformation)

カメラや人間の目と同じ視界を持ちます.視体積は四角錐になるため,視点から物体が遠ざかるほど,物体は小さく射影されます.また,四角錐の底面積が四角錐の高さに対して大きくなるほど,広い画角の映像を生成することができます.

(b)正射影変換(orthographic transformation)

四角錐は直方体になるため,視点から物体が遠ざかっても物体は同じ大きさに射影されます.この射影では物体の大きさや角度が常に一定に表示されるため,CADの図面などに用いられます.

視体積が幾何学的に決定されると,3次元空間における物体を射影面に変換することができます.この変換の際に問題になってくるのは,各物体の前後関係に関することです.物体同士の位置関係によっては,近くの物体が遠くのものを覆い隠す(occlusion)必要が出てきます. もっとも,ワイヤーフレームで物体が表現される場合は,手前も奥も関係ありませんので問題はありません*7.しかしポリゴンモデルなど物体が面で構成される場合,面や物体の奥行き判定をおこなって,視点に近い側の物体を表示しなければなりません.こうした操作を隠線消去(hidden-line removal),隠面消去(hidden-surface removal)といいます. 隠線消去を実現する具体的な方法は,デプスバッファ(depth buffer)を使用することです.デプスバッファとは名前の通りデプス(深度)のバッファ,つまり視点からの距離画像のことを指します.

図:フレームバッファとデプスバッファ

処理の手順を簡単に説明すると上図のようになります.これは平面物体が重なって表示されている例です. 3次元空間における物体を射影面に変換した結果,平面像ができます.この像はRGB情報として1画素ごとにフレームバッファ(frame buffer)に格納されていきます.

隠線(隠面)消去の処理を有効にする場合,フレームバッファと同じサイズのデプスバッファを用意しておきます.射影計算の結果,画素がフレームバッファに書き込まれる前に,デプスバッファで遠近判定をおこないます.例えばd1,d3にある平面の描画後に平面d2を描く場合,デプスバッファの遠近判定でd2より値が大きい場所だけが上書きを許されます.上書きできる場合は,フレームバッファにd2の情報が書き込まれ,デプス値が更新されます.

デプスバッファを無効にする場合は,物体の奥行き情報が完全になくなるため,すべての物体が重畳されて描画されます.これは半透明の物体を表現したい場合に有効です.


画面の大きさ

完成した映像を表示するための大きさを設定します. 表示領域はビューポート(viewport)ともいいます.このビューポートにフレームバッファの内容が表示されるため,フレームバッファの大きさはビューポートの大きさに依存します.

画面の大きさを設定する場合,カメラフィルムの感光のように相似的に拡大縮小するだけでなく,上下や左右に伸縮した映像を作成することも可能です. 例えば,視体積の底面が横n:縦mの比率だったとします.ビューポートの大きさを横n:縦mの比率にすると,正常な映像を得ることができますが,横2n:縦mにすると画面横方向に2倍伸張した映像が得られます. なお,画面の縦横比のことをアスペクト比(aspect ratio)と呼びます. 正常な比率で映像を生成するには,常に画面表示と視体積の底面のアスペクト比が一致している必要があります.例えばウインドウに画像を表示していてウインドウサイズが変更された場合,ビューポートのアスペクト比が変化してしまいます.このとき同時に視体積のアスペクト比も変化させなければならないことになります.


演習問題


自習問題

  • glBegin()glEnd()glVertex3f(x, y, z)を使用して,何か自由な形状を作成してみましょう.
  • glutWireSphere(double radius,int slices,int stacks)を使用してみましょう.なお,radiusは半径,slicesは経線数,stacksには緯線数が入ります.
  • glutWireTeapot(double size)を使用してみましょう.sizeで大きさを指定します.
  • ここで勉強したOpenGLの関数は,
    です.赤本を利用して,復習しておきましょう.