プロジェクト演習Ⅳ インタラクティブゲーム制作 プログラミング4 2012/11/21 Inside of 3DCG
今日の内容 リアルタイム3DCGの描画処理の流れを 知ろう ネット上のサンプルや、他のライブラリとの連携がやりやすくなる! FKの内側を少しだけ解剖します ネット上のサンプルや、他のライブラリとの連携がやりやすくなる! シェーダプログラミングもやりやすいはず
描画処理の流れ 多くのライブラリは 「描画」しかできない これらのライブラリを用いた場合は、自分で右の流れを組む必要がある OpenGL、Direct3Dは もちろん、XNAやDXライブラリもそう これらのライブラリを用いた場合は、自分で右の流れを組む必要がある 画面をまっさらに 塗りつぶす カメラの位置と向き、その他諸々をセット 描画したいモデルの 座標系をセットする 三角形をたくさんたくさんたくさん描画する (3,4をモデルの個数分) 描き上がった画面を まるっと差し替え
FKの最大の特長 形状-モデル-シーン-ウィンドウからなる階層構造 他にも特長はあるが、あまりゲーム向きではない なかでもモデルの存在は大きい 同じ形状を複数描画する際の効率化 位置、姿勢、スケールの柔軟な制御 シーンへの登録制による描画処理のカプセル化 他にも特長はあるが、あまりゲーム向きではない 形状自体の高度な変形、編集操作など
FKのデメリット カプセル化しすぎてて、融通を利かせるのがちょっと難しい これらを紐解きつつ、自分でいじりたいところのいじり方を伝授したい 形状ごとに描画処理内容が固定されており、自由に実装することができない 一般的な描画処理の流れが隠蔽されており、処理のイメージをつかみづらい これらを紐解きつつ、自分でいじりたいところのいじり方を伝授したい
!? 描画処理の解剖 エントリーした順に画面上の領域を塗りつぶしていく 画面上のどの位置を塗りつぶすかは、カメラの座標系とモデルの座標系で決まる どのような色、画像で塗りつぶすかはマテリアルやテクスチャの設定と、光源と法線ベクトルで決まる !?
何故こうならずに済むのか? エントリー順に塗りつぶすのであれば、右のようになってしまうはず 奥のものから順番にエントリーしないといけないようだが、実際は大丈夫 何故か?
デプス(深度)テスト 塗りつぶす際に、そのピクセルがカメラからどのくらいの距離かを記録していく 色で表すと右図のようなモノクログラデーションになる 実際に塗りつぶす前にピクセル単位で距離を比較し、手前の位置にくる部分だけを塗りつぶす
!? 半透明との組み合わせによって起きる問題 手前に半透明物体を描く 奥に物体を描く この時点では奥に何も描かれてないので、 背景とのブレンド結果で塗りつぶす 当然デプス値にも手前の距離を書き込む 奥に物体を描く 上で手前の距離値が書き込まれている部分は塗りつぶされない 半透明物体を描いた領域は「背景とのブレンド結果のまま」になる !?
考えられる対策 半透明物体の描画順を後回しにする カメラの最前面に来るような物体(パラメータやメッセージなど)はオーバーレイ描画を使う 半透明物体同士の順番も、出来るだけカメラから遠い順になるようにする カメラの最前面に来るような物体(パラメータやメッセージなど)はオーバーレイ描画を使う FKならばentryOverlayModel()を使えばよい 半透明物体はデプス値に影響を与えないようにする 今後もちょくちょく使うテクニック
2段階のデプス値制御命令 これから描く物体は「デプス値に従って前後関係を解決する」or 「その場所がいかなる距離でも無視して上書きする」 glEnable(GL_DEPTH_TEST) glDisable(GL_DEPTH_TEST) これから描く物体は「描画する際にデプス値も一緒に更新する」or「描画する際にデプス値は参照するが更新はしない」 glDepthMask(GL_TRUE) glDepthMask(GL_FALSE)
目的別デプス制御状態まとめ 通常の描画 オーバーレイ描画 背景の後書きを邪魔しない半透明描画 デプステスト有効、デプス値書き込み有効 デプステスト無効、デプス値書き込み有効 背景の後書きを邪魔しない半透明描画 デプステスト有効、デプス値書き込み無効
アルファ値の扱いについて マテリアルとテクスチャで2段階のアルファ値(透明度)が扱える アルファ値は0で完全透過を表す アルファ値0のピクセルは描画領域から除かれるようになっており、デプステストからも外れる これをアルファテストと呼ぶ FKではデフォルトで有効になっている 1で完全不透明となり、その間の値は半透明としてブレンド処理が行われる FKの場合はfk_Sceneでの設定が必要
制御命令ぶっ込みポイント 先ほどの処理の流れに注目 fk_Modelを継承するとこのポイントに割り込みが可能 preでいじってpostで戻せば無問題! 画面をまっさらに 塗りつぶす カメラの位置と向き、その他諸々をセット 描画したいモデルの 座標系をセットする 三角形をたくさんたくさんたくさん描画する (3,4をモデルの個数分) 描き上がった画面を まるっと差し替え preShader() postShader()
どんな命令を突っ込めるか? デプス値制御命令 アルファブレンド制御命令 シェーダ処理命令 独自の描画処理命令 glBlendFunc() (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)がデフォ (GL_ONE, GL_ONE)にすると加算ブレンドになる シェーダ処理命令 独自の描画処理命令 preでいじった状態値はpostで戻すこと
とても参考になるサイト PROJECT ASURA http://asura.iaigiri.com/top.html XNA中心ですが、OpenGLによる実装サンプルも豊富です あくまでターゲットにするスペックの範囲でやれることを探してみるのも良いでしょう
まとめ 一般的な3DCGプログラミングにおける 処理の流れを把握 描画処理の各段階において何が行われているかを知る デプス、アルファなどの挙動と制御 正しい見た目の表現と、外部サンプルをうまく取り込むための基礎知識
今日の課題 「PROJECT ASURA」に掲載されているエフェクトのサンプルのうち、自分たちで使いそうなものをFK上で利用できるように移植してみよう 煙のサンプルについては移植した例があるので、そちらを参考にするとよい