CDR6275

Michio SHIRAISHI Official Site


OpenGL 4.1とOpenGL ES SL 1.0で学ぶ3次元コンピュータグラフィックス

東邦大学理学部情報科学科 白石路雄
最終更新: 2014年2月20日

この文書の目的

 iPhoneやAndroidなどのデバイスの普及によって、3次元コンピュータグラフィックスのプログラムが身近なものとなりました。多くの良い本が出ているので、簡単なプログラムであれば誰でも書けるようになっています。ただ、それを発展させて、より高度なことをしようとすると、どうしても3次元コンピュータグラフィックスの仕組みについての理解が必須です。

 3次元コンピュータグラフィックスの仕組みを学ぶ方法の一つとして、教科書を用いて理論を学ぶという方法があります(教科書などの参考文献についてはこのページの下に書きます)。もう一つの方法として、プログラミングを通じて理解を含めていく方法があります。たとえば、サンプルプログラムのパラメータをいじって実際に画像を作ってみることで、その背後にある仕組みをより理解することができます。

 このような理由から「プログラミングを通じて3次元コンピュータグラフィックスの仕組みについて学ぶ」ことが、この文章の目的です。

この文書で使う3次元コンピュータグラフィックス用のAPI

 3次元コンピュータグラフィックスでは、コンピュータの中に仮想的に表現されているデータから2次元の画像を生成します。そのために、スクラッチからプログラムを書いてもいいのですが、通常は3次元コンピュータグラフィックス用のAPIを使って書くのが普通です。

 3次元コンピュータグラフィックス用のAPIとして有名なものにOpenGLがあります。デスクトップの環境では、Macで用いられているOSであるOSXのほか、WindowsやLinuxなどのOSでも利用できます。また、iOSやAndroidなどではOpenGLの組み込み用途向けのOpenGL ESが使用されており、デファクトスタンダードの地位を固めつつあります。

 そこで、この文書ではOpenGLを用いて、3次元コンピュータグラフィックスのプログラミングを行っていきます。

 使用する開発環境は次の通りです。

  •  OS:Windows 7 32/64ビット
  •  言語:C++
  •  統合開発環境:Microsoft Visual Studio 2013 Professional for Windows Desktop

 それ以外のOSや統合開発環境でも動くプログラムにするつもりです。現在のところ、OS X 10.9上でのXcodeとiOS7でも動きます。下の図は左からWindows7, MacOS 10.9, iOS7 (シミュレータ)で動かした例です (AndroidもNDK使えばいけるんじゃないかと思ってますが未確認)。

miku-win7

miku-mac

miku-ios

 また、細かい話では、固定機能パイプラインを使うかどうか悩んだのですが、iOSやAndroidも横目で見ると、そちらではOpenGL ES 2.0だし、iOSの最近のXcodeで作るテンプレートとか見ていると、OpenGL ES 1.0系はばっさりと切り捨てているみたいだし、ということで、プログラマブルパイプラインの機能だけを使って解説することにしました(いや、教育目的だと固定機能パイプラインの方がいいのかな、という気もするし、私もそちらで習ってきたわけで、微妙な部分ではあるのですが、なにごともチャレンジです)。

 ということから、OpenGLのバージョンとしては4.1 Core Profileを使用し、シェーダのバージョンとしてはOpenGL ES SL 1.0(OpenGL ES 2.0で使われているもの)を使うことにします。

目次

1. セットアップ
Windowsにおける開発環境のセットアップを行う方法について述べます。

2. 最初のプログラム
シェーダを使った三角形を描く簡単なプログラムを通して、OpenGLのプログラムの概略について述べます。
[学ぶこと:ウィンドウの開きかた、シェーダの利用方法]
2.1 最初のプログラムを見てみる (FirstStart)
ウィンドウを開くプログラムを作ってみます。
2.2 シェーダを使って三角形を描く (FirstShader)
シェーダについて説明し、三角形を描くプログラムを書いてみます。
2.3 シェーダのコードをファイルから読み込む (FirstShaderFile)
シェーダのコードをプログラムに埋め込むのではなく、ファイルから読み込むようにします。
2.4 ここまでのプログラムをきれいにする (FirstRefactored)
ここまでのソースコードをリファクタリングします。

3. ポリゴンモデル
2章では、1つの三角形を描いてきました。3次元の形状モデルは三角形の集まりとして表されていますので、複数の三角形を描く方法について述べます。
[学ぶこと:ポリゴンのレンダリング]
3.1 五角形の頂点を描く (PentagonVertices)
複数の三角形を描く方法の例として、まず1つの五角形を3つの三角形に分割して描く方法について述べます。まずは頂点座標を求めて、それを点として表示させてみます。
3.2 内部が塗りつぶされた五角形を描く (PentagonFill)
今度は五角形の内部を塗りつぶしてみましょう。
3.3 頂点インデックスを使って描画する (IndexedPentagon)
頂点の座標を順に与えるのではなく、頂点の番号を使って三角形を指定する方法について学びます。
3.4 三角形の稜線を描く (PentagonEdges)
頂点インデックスを使って三角形の稜線を描いてみましょう。
3.5 ポリゴンモデルのクラスを作る (PentagonRefactored)
複数の多角形からなる形状のことをポリゴンモデルと呼びます。このポリゴンモデルを表現するクラスを作ってみましょう。

4. モデリング変換
3次元の形状モデルを3次元の空間の中に自由に配置するには、形状モデルが定義されている座標系から変換する必要があります。この変換のことをモデリング変換と言います。
[学ぶこと:モデリング変換、行列による座標変換]
4.1 モデルを読み込む (ModelLoad)
モデリング変換について学習する前に、具体的な形状モデルを用いるために、初音ミクのモデルデータを読み込んでみます。
4.2 モデル行列 (ModelMatrix)
モデリング変換を行う行列のことをモデル行列と呼びます。この行列を使って、3次元の形状モデルが定義されている座標系から、描画に使われる座標系の座標を変換する手法を学びます。
4.3 合成変換 (MultipliedModelMatrix)
座標変換には、拡大縮小変換、回転変換、平行移動変換など様々なものがあります。これらを組み合わせる方法について学びます。
4.4 3次元モデルを表すクラスを作る (ModelRefactored)
ポリゴンから構成される3次元のモデルを表すクラスを作ります。

5. シェーディング
光源によってモデルが照らされ、その光を反射することによって、モデルには色がついて見えます。
[学ぶこと:シェーディングモデル]
5.1 拡散光 (Diffuse)
光源から物体にあたった光が表面であらゆる方向に同じように反射する、と仮定して色をつける方法を学びます。
5.2 法線ベクトルの変換行列 (NormalMatrix)
拡散反射を計算するには、多角形の法線ベクトルが必要になりますが、このベクトルはモデリング変換によって変わるため、それを考慮する必要があります。
5.3 複数のマテリアル (MultipleMaterials)
3次元形状モデルではそれぞれのポリゴンに色などの材質が設定されています。この情報を使ってパーツごとに塗り分ける方法について説明します。
5.4 テクスチャマッピング (TexureMapping)
初音ミクのモデルでは、目はポリゴンに貼りつけられる画像として定義されています。このように画像をポリゴンに貼り付けることをテクスチャマッピングと呼びます。
5.5 フォンのシェーディングモデル (PhongShadingModel)
拡散光以外に、環境光と鏡面反射光を組み合わせて、材質を表現する方法があります。
6. 投影変換
3次元コンピュータグラフィクスの基本は、3次元空間の中の位置から2次元のディスプレイ上の位置を求めることです。
[学ぶこと:平行投影, 透視投影]
6.1 平行投影する (OrthogonalProjection)
最初の投影変換として、平行投影のプログラムを書きます。
6.2 透視投影する (PerspectiveProjection)
透視投影のプログラムを書きます。
6.3 平行投影と透視投影の違いを学ぶ (MultipleModelsOrthonalProjection, MultipleMoelsPerspectiveProjection, MultipleModelsPerspectiveProjectionWithLines)
平行投影と透視投影の違いについて学びます。
7. アニメーション
アニメーションは、パラメータを少しずつ変えて描くことで作られます。
[学ぶこと:アニメーション、ビュー変換]
7.1 アニメーションの基本 (RotationAnimation)
アニメーションの最初の一歩として、初音ミクのモデルを回転させるアニメーションを作ってみます。
7.2 カメラを動かす (LookAt)
物体を動かすほかにカメラを動かしてもアニメーションを作ることができます。

参考文献

  • アフタブ・ムンシ, ダン・ギンズバーグ, デーブ・シュライナー, 松田 晃一, Open GL ES 2.0 プログラミングガイド, ピアソン桐原, 2009.