Published at: 11:12 pm - 月曜日 12月 12 2011
OpenGL などの描画 API を使っていると頂点の並び順によって描画されたりされなかったりして戸惑った経験をした方もいるかと思います。これはなぜかというとポリゴンが視点に対して表を向けているのか裏を向けているのかで、描画の切り替えをしているからです。
ポリゴンの裏側が描画されない理由
通常、立体物で視点に対して裏になっている場合は、そのポリゴンより手前に別の表を向けているポリゴンがあるはずなので、裏を向いているポリゴンを描画する必要はありません。また、看板や紙のような平らなモデルであっても裏になっているポリゴンをそのまま描画してしまうと文字や模様が裏返ってしまうのでこれも良くありません(ガラスなどの透明な物体は例外になりますが、これはこれで表も裏も描画すれば正確な描画になるかというとそういうことでもありません)。
ポリゴンの表裏はどのように決まるのか
つまり描画する必要のないポリゴンを対象から外すために表側か裏側かで切り替えをしているということになります。では、どうして頂点の並び順によってポリゴンの表と裏が変わるのでしょうか?そもそもポリゴンの表と裏はどうやって決まるのでしょうか?
結論から先に書くと数学的に計算して求めます。
頂点 A, B, C から作られるポリゴン ABC で考えます。ちなみにこちらが表面です。まず頂点 A と B を結んだベクトル AB を求めます。ベクトルは終点から始点を引くことで求められます。式は
となります。同じように頂点 B と C を結んだベクトル BC も求めます。
次にそのベクトル AB, BC の外積を求めます。式は
となります。
それぞれの成分の行列式の求め方は X 成分を例にすると
となります。これを Y 成分と Z 成分ともに同様に求めます。
それでは頂点 A, B, C に具体的な値を入れて計算してみます。
とするとベクトル AB, BC は
となり、これの外積は
となるため、結果は
となります。これは空間的にベクトル AB, BC に対して直交するベクトルになります。ここで Z 成分が正になっていることに注目して下さい。
それでは今度は逆回りのポリゴン ACB を考えた時、ベクトル AC, CB で同じようにしてみます。こちらは裏面を向いている例です。
すると先ほどと同じくベクトル AC, CB に対して直交するベクトルになりましたが、 Z 方向が逆(負)を向いていることが分かります。
このように頂点の並び順によってポリゴンの表と裏が変わることが分かります。ちなみに右回りの場合は時計回りということで clockwise(CW), 左回りの場合は反時計回りということで counter clockwise(CCW) と略します。
右手系と左手系
右手系と左手系というのは Z 軸が手前と奥のどちらを正(プラス)として扱うかということを表しています。手の指先(親指以外)を X 軸の正、手のひらを Y 軸の正とした場合、右手の親指は手前を向き左手の親指は奥を向きます。このため右手系では手前を正、左手系では奥を正とします。
なお、代表的な描画 API としては OpenGL が右手系、DirectX が左手系を採用しています。数学の教科書は右手系で書かれているので、自分がどちらの座標系を扱っているのか意識しないと思った結果にならず戸惑ってしまうかもしれません。
先ほどの略称でいうと右手系では CCW が表、左手系では CW が表として扱われます。つまり上記の例は CCW が表だったので右手系だったということですね。
プリミティブによる違い
トライアングルリストの場合は常に三角形毎の回転方向は変わりませんが、トライアングルストリップの場合はポリゴン毎の回転方向が交互に変わります。ただ、これはこういうもので最初のポリゴンの回転方向を基準に表の扱いを決めているので交互に描画されないといったことはありません。
ローポリゴンモデルの場合
ローポリゴンモデルの場合は皿のように薄い物体や壺などの内側が見える構造の物に対して、上面と下面、外側と内側の両方にポリゴンを貼る余裕がない場合もあります。そういった場合は表裏面の両方を描画するようにしてポリゴン数を抑えるといったこともアリです。その際にはどちらから見ても不自然でないテクスチャデザインにするなどの注意が必要です。