隠面消去のお話。
 「iPhoneアプリ開発、その(96)」で、なぜに

テン・シー・シー-2

こうなったか?
 それは、個々の三角形平面の前後関係を考えていなかったから。

glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);

は三角形の平面単位で描画を進めるんだけど、まず最初の1枚目の三角形の描画は正しいわけです。

テン・シー・シー-1

でも、引数の指定は6なので、ここで描画を終えずに2枚目の三角形を描画しようとする。

テン・シー・シー-2

で、前後関係なんて考えずに素直に描画しちゃって、本来後ろに隠れて見えないはずの三角形が描かれてしまう。

テン・シー・シー-3

 これが、へんてこテトラ君完成の理由っす。
 んじゃ、どうすればいいんだよ、というのが、3DCG研究者の永遠の課題、隠面消去アルゴリズムなわけです。
 例えば、前後関係考えて後ろの平面から描画すればいいじゃん。ていうのが

Zソート法

 こいつは、物体を構成する平面の位置関係をうまく調整してやれば、そこそこ役に立つんですが、下のように交差した平面はお手上げになるわけです。

テン・シー・シー-4

前の部分もあれば、後ろの部分もある。

テン・シー・シー-5
そのため、どっちの平面を後ろと判断しても交差は表現できない。ちなみにバーチャファイター2はZソート。

SEGA VOICE:10年目の「VF2」
単色のテクスチャとか、涙無しには聞けない話ですな。

 ま、それはおいといて、交差問題を解決するためにスキャンラインアルゴリズムとかレイトレーシング法とかいろいろ考えられた中で、んじゃ、平面塗りつぶすときに、各ピクセル(モニタ画面を構成する最小単位、ピクチャー・セルの略称。iPhoneの画面は320x480のピクセルで構成されている)ごとに平面の視点からの距離(深度)を記憶させておいて、次の平面塗りつぶすときに、塗りつぶそうとしてるピクセルに、自分より前にそのピクセルを塗りつぶした平面の深度が残っていて、自分の深度より浅いなら、塗りつぶさないようにしたらどうよ?

テン・シー・シー-6
おおざっぱに表現すると、こんな感じ。

てのが

Zバッファ法

なわけで、PlayStation、XBoxやDirectXでも使われてる超メジャー隠面消去法なわけです。
 当然、OpenGL ESも使えるわけで、実際、上の交差する三角形の絵もOpenGL ESで描いてる。
 
 これを「iPhoneアプリ開発、その(96)」で安易に使おうとしてglEnableで一発じゃんと思ってたら、実は

glGenRenderbuffersOES

とか

glBindRenderbufferOES

とか、いろいろ手続き踏まないと駄目だったわけですね。

 次回は、ここらへんの設定方法を調査っす。

 iPhoneの320x480画面で4バイトのfloat型で記憶しても600Kバイトのメモリが必要なZバッファ、そんなんが余裕で持てる時代っすよ。

 初代Macintosh、メモリ128KBとか、あり得ね~。


AD