ビルボードのいろは
![]()
![]()
![]()
・1999
推定、「今年で地球も終わりか〜」と言ってる人が500万人、「とうとう来年21世紀だよね〜」と言ってる人が50万人、「今年の紅白見た?」と言ってる人が10万人いると思われる昨今ですが(人数は思い付きです)、今年最初の更新はビルボードのついてです。
プエルコルダンを走り回ってて(←某ゲームばっかりしてて)全然書いてませんでした。ゲームに時間を奪われているというか、それともホームページ作りに時間を奪われているのか……。
ビルボードという呼び方を知らない人がいるかもしれません。僕も手法は知ってても名前は知りませんでした。
なお、”いろは”と言っても”色は”じゃなくて”いろはにほへと”の”いろは”ですんで誤解なきよう。
・3Dの中の2D
billboard〈名〉《主に米》(屋外の)広告板,掲示板.
ポリゴンを使った3Dで、球体を書くとそれ相応のポリゴン数を必要とします。ポリゴン数を増やすと見栄えはよくても遅くなり、ポリゴン数を減らすと速度は改善できても見栄えが悪い……。
そこで、ポリゴンで球体を書く代わりにそこに一枚の四角ポリゴンを書きます。それに予め球体を書いたテクスチャを使う事で、そこに球体があるように見えます。ライティングなどの計算も要らなくなります。
四角のポリゴン2枚だけ。
三角ポリゴンなら4枚。
赤が手前、橙が奥にある
位置関係を図で表すと
こんな感じ。下にあるのが
カメラ、それ以外が球体
(実際は四角ポリゴン1枚)これだけで、処理速度は比較にならないほど速くなりますね。これはもちろん球体に限った手法ではなく、ポリゴンで表現しようとすると半端じゃなく処理速度が重くなるような物体(炎や木とか)全般に使えます。
でも、これだけでは問題が。違う方向から見たら一枚ポリゴンだということがバレますね。
球体2つを右から
見てみる。全然
球体じゃない……
カメラから見ると赤が
奥、橙が手前にある解決方法。ポリゴンが常にカメラの方を向くようにしてみましょう。これが一般的なビルボードです。
右から見てもちゃんと
球体に見える
ポリゴンの位置は
そのままに、向きを
カメラの方に向けるライティングは正確じゃないですけど(光源の位置・方向が影響しない)、それほど気にならないでしょう。
カメラを向くようにするのは簡単です。ビュー行列の逆行列を使ってください。向きのみを変えるので、使うのは3x3の部分だけです。X・Y・Z軸は直交してるのでひっくり返すだけでいいです。コードにするとこんな感じ。
matWorld._11 = matView._11; matWorld._12 = matView._21; matWorld._13 = matView._31; // matWorldがワールド行列
matWorld._21 = matView._12; matWorld._22 = matView._22; matWorld._23 = matView._32; // matViewがビュー行列(カメラ行列)
matWorld._31 = matView._13; matWorld._32 = matView._23; matWorld._33 = matView._33; // それぞれD3DMATRIX構造体D3DTLVERTEXではなく、D3DLVERTEXやD3DVERTEXを使うなら、この方法でビルボードを実現してください。
D3DTLVERTEXなら、それよりもっと単純な方法で十分です。以下、D3DTLVERTEXを使うための変換を理解していることを前提で書きます。ポリゴンが常にカメラの方を向いているという事は、ポリゴンに奥行きは無いという事になります。ならば、ポリゴンの基準点(回転する中心。球体なら中心、木なら根元)のスクリーン座標(D3DTLVERTEX)を求め、四角のポリゴン(三角ポリゴン2枚)を書くだけで良いです。座標変換は1頂点だけ。
いきなりスクリーン
座標まで投影変換。
画像の点は求めた
座標を示してます→
それを基準にX・Y値を
大きさ分引いてor
足してポリゴンを描画。
Z値・rhw値は変えない→
結果でも、これだとまだどのくらいの大きさでポリゴンを書けばいいのかわからないし、遠くにある物と近くにある物とが同じ大きさになってしまいますね。
いきなりスクリーン
座標まで投影変換。
画像の点は求めた
座標を示してます→
それを基準にX・Y値を
引いてor足してポリゴン
を描画……ってどのくら
いの数値を足すんだ?→
結果
……橙の方が奥
なのに同じ大きさ
なんですけど。これから解決方法について説明しますが、これは同次座標を使う場合の説明です(Direct3DのD3DVERTEXなどは同次座標を使ってます)。視野角度(画角)やZクリップ位置を変える程度ならこの説明のやり方がそのまま使えますが、オリジナルな変換をしてる方は自分で解決してください。それほどの方なら自分でわかるだろうし。
まずは大きさから。投影(プロジェクション)変換前で大きさ1.0のポリゴンというとそれなりの大きさですが、変換後はスクリーン座標を使うため1.0という数値は1ドットにしかならないです。しかも、解像度が変われば1ドットの見た目の大きさも変わります(320x240と640x480を比べると、面積が4倍違う)。
解決策は簡単。先に、投影変換を使って投影変換前と変換後の長さの比率を求めておきます。
X=1.0 Y=1.0 Z=1.0(Z値には変換後のrhw値が1.0になる数値を使う)の位置にある頂点を投影変換して、出てきたX・Y値から画面の消失点(だっけ?普通は画面の中心)のX値を引きY値を足せば(足すのは、変換前と後でY軸の向きが逆なため)、変換前の1.0の長さが変換後のいくら(何ドット)になるかがわかります。ちょっとわかりにくい文章ですが、例えば640x480の画面サイズなら、X=1.0 Y=1.0 Z=1.0の頂点を投影変換して、X値から320を引き、Y値から240を足し(Z値は必要無いです)、その値を比率として使います。ビルボードのポリゴンの大きさが1.0なら、出てきたX・Y値をそのままポリゴンに大きさに使い、ビルボードのポリゴンの大きさが1.0なら、出てきたX・Y値の2倍の大きさのポリゴンを描画します。
X・Y値は大体同じの場合がほとんどだと思います(符号は逆だけど)。全然違うなら、それは画面が歪んでいます(縦か横に潰れてるor伸びている)。
この計算は、一度やっておけばその数値をずっと使えます。が、画面サイズを変更したり投影行列を変えたりした時には計算し直す必要があります。
次に、奥と手前でも大きさが同じに見える問題について。これは、ポリゴンの大きさを、投影変換で出てきたrhw値で割るだけです。投影変換でX・Y値をrhw値で割りますが、それと同じ事です。以上。
これで、とりあえずビルボードを実現できると思います。注意としては、あまりに大きな物体にビルボードを使うと一枚ポリゴンだとバレやすいです。
ビルボードは新しい技術ではありません。むしろ、ポリゴン時代の前の3Dは全てビルボードだったといってもいいでしょう。
アウトランやアフターバーナー、スペースハリアーなど、セガの体感ゲームが良い例でしょうか。もっと昔のポールポジション(ナムコ)などでは拡大・縮小機能も無かったので、何段階かの大きさの絵を使っていました。ポールポジションがわからない人は、ファミコンのF1レース(任天堂)と言うとわかるでしょうか。これもある程度の年齢以上じゃないとわからないか……。
・ビルボードとポリゴンの共存
球体に2つの目を付けたいと思います。球体はビルボードを使いたいです。さて、目はどこに付ければいいでしょう?
すぐに思い付く方法としては、ビルボードのポリゴンにくっつけます。一見これで良いように見えますが、これだと斜めから見た時に目が隠れたりしてしまいます。
赤い球体に白い目
を2つくっつける
結果→
斜めから見ると
ビルボードのポリ
ゴンも斜めになる
結果、片目は隠れる
し目の位置は変だし目もビルボードにするという方法もありますが、それだとどこから見てもこっちを向いているように見えてしまいます。
そこで、今度はビルボードのポリゴンは球体だと仮定して、目を球体の半径の分だけ離してみましょう。
球体だと仮定して
それに目が付いて
いるようにする
結果→
黒くて丸い線は、
球体と仮定した時
の球の大きさを表す
結果。ちゃんと
斜めから見たように
なっていますねこれだけで、ビルボードであることがバレにくくなります。スーパーマリオ64(任天堂)なんかはかなり使い方がうまくて、全然ビルボードに見えません。この目の例も、ボム兵(敵キャラ)を参考にしてます。木やコイン、球体の多くがビルボードなんですけど、ゲームが半分くらい進むまで木がビルボードだと気付きませんでした。ハナチャン(敵キャラ)は今見てもビルボードに見えません。
マリオは無いけどゼルダ(64版)は持ってる、という人なら、バクダン花を思い出してください。バクダンの部分はビルボードですが、草の部分はポリゴンです。
そうそう、ゼルダと言えば城下町や家の中の背景がたった一枚のテクスチャでできてるのが凄すぎますね。一見の価値あり。
・おまけ
ビルボード以外で色々な方向から見てもそれっぽく見える手法として、数枚のポリゴンを使う方法があります。
ポリゴン1枚
こういう木のテク
スチャを使います→
こういう感じに、
ポリゴンを3枚に
こんな感じになりますビルボードだとずっとこっちを向いているので、カメラが回り込むとなんだかその場で回転しているように見えてしまって困る、という時にはこっちの方が良いでしょう。これなら回り込んでも物体が回転してるようには見えません。
この例での欠点は、真上から見ると3枚のポリゴンだということがすぐにわかってしまうことです。上を向いたポリゴンも付け足せば少しは解消されますが、ポリゴン数は増えます。
今回はビルボードについて説明しましたが、そろそろ次辺りはゲームな話か自分の考えるところでも書きたいと思います。それなら画像作らなくていいし。
![]()
![]()
![]()
written by Y.Ohde e-mail : oode@alles.or.jp