Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
[go: Go Back, main page]

Add mode
and Volume rendering
3/31 加色合成とボリュームレンダリング




 晴れた空、白い雲。くぅ!たまりませんな。しかもだんだんと暖かくなってきた昨今、街ゆく女性たちの服装も次第に薄着になってきて、まったく嬉しい季節が今年もやってまいりました。

 そんなわけでProjectKの雲について、わりと評判がいいようです。そこで今日は、チョーシに乗ってその種明かしをしたいと思います。




ボリュームレンダリング


 コンピュータグラフィックスの世界で最もポピュラーといえるのは、おそらくポリゴン描画法だと思います。

 ポリゴンは扱いやすく、専用のハードウェアも出そろってきました。

 しかしポリゴンは全ての物体を多面体で表現しようとするため、どうしても無理が出てきます。

 そして、現実の物体の多くは多面体ではありえないので、ポリゴン描画法では自ずと限界があります。

 医学の世界では、昔からCTスキャンという、現実の三次元物体をそのままコンピュータに入力する方法が使われてきました。

 ビデオカメラなどは、一枚の二次元画像をピクセルという小さな正方形の要素に分解しますが、CTスキャンでは、現実の三次元物体をボクセルという小さな立方体の要素に分解します。

 そのようにして得られたデータを、コンピュータ画面上で扱うために考え出されたのがボリュームレンダリングというものです。

 ボリュームレンダリングでは、ボクセルの集合体を画面に描画する際、視線ベクトルと交差するボクセルを次々に求め、α値などを加味しながら可視・不可視の判定を行い、実際の画面を作り出します。

 ボリュームレンダリングの良いところは、ポリゴンと違って、多面体に分類できなくても表現できることです。これはちょうど、定規とコンパスで描かれた図形と、クレヨンや色鉛筆、絵筆で描かれた絵画の関係に似ています。ほとんどの場合は、後者のほうがより豊かな表現力を持っています。

 この、ボリュームレンダリングを応用するととても自然な雲や炎を表現することができるのです。

 自然な雲や炎を表現したい場合にはセル・オートマトンと呼ばれる考え方を使います。

 セル・オートマトンとは、「セル(細胞)」と呼ばれる要素を一様に敷き詰め、ひとつひとつのセルが簡単な動作をしながら近傍のセルと相互作用することで、全体として極めて複雑な計算を行なってしまうというたいへん面白い考え方で、現在の人工生命研究の主流のひとつです。

 そして前述のようにセル・オートマトンを使うと、水の流れや雲の模様、炎などがリアルに、そして簡単に作れることもよく知られています。

 なぜなら、実際の自然現象も、水の粒子や炎の粒子などが近傍の粒子と相互に作用しあって発生していると考えられるからです。

 普通に知られているセル・オートマトンは、ライフ・ゲイムなどに代表される、二次元のマス目のものですが、これを三次元に拡張することは簡単にできます。

 こうして作った三次元のセル・オートマトンは、ひとつのセルがそのままボクセルになりますので、これをボリュームレンダリングします。

 すると、とても立体的でリアルにかたちを変える三次元物体のできあがりです。

 このようなテクニックは、一部のハイエンド環境で、水や炎、煙などを表現する場合によく使われています。また、Lightwave3D 5.5ではボリュームレンダリングがサポートされたようです。

 このようにして、ひとまずリアルな雲を表現することが可能なのはわかっていただけたと思います。





空に浮かぶ雲のタネ明かし


 ところでこのように素晴らしいボリュームレンダリングですが、これを現実に高速動作できるように実装するというのは、なかなか一筋縄にはいかないのがとても残念なところです。

 なにしろボリュームレンダリングは現在のところ、ローエンド環境でのハードウェアアクセラレーションは存在しません。ということは、すべてソフトウェアで処理することになるわけです。

 となると、処理時間はボクセル集合の数に比例して限りなく増大することになります。

 また、必要なメモリ量も馬鹿になりません。たとえば640x480のHi Color(65536色)画面モードで、奥行きが65536まであるボクセル空間を描画するとして、必要なメモリ量は640x480x2x65536 = 40265318400バイト(約40ギガバイト)となってしまい、とてもではありませんが仮想メモリを使いまくっても計算できません(40G以上のハードディスクがあれば可能かもしれませんが)。

 そこで、普通は画面上の一部分だけにボクセルを適用したり、ボクセルの亜種(ボクセル型ハイトフィールドなど)を用いたりして必要なメモリ量をなるべく節約します。

 しかし、ハードウェアアクセラレーションが使えないのは緻密なリアルタイム処理が要求されるゲームなどには致命的です。

 たとえばWindows95などではハードウェアアクセラレーションが受けられないと、かえってスピードが遅くなってしまう可能性もあります。

 そこでたとえばボクセルを利用していることで有名なNovaLogic社のゲームなどは初めからDOSモードで動くものが多いようです。

 しかし、Direct3Dのゲームとして、どうしてもリアルな雲を描画したい。完全にリアルでなくてもいいから、それっぽく見せたいという要求が、僕にはありました。


 最も簡単な解決方法は、普通に雲を描いたテクスチャを普通にスクロールさせるだけのものです。これはFinalRealityを初めとしてデモや数多くのゲームで使われているポピュラーな方法です。

 しかしこれはあまりリアルとは言い難いし、なによりそのまんまパクリでは凡百のメガデマー(メガデマ・・・誇大デマ?)と同じになってしまうので、却下。

 次に考えられるのは、雲は最初から無限遠にあるものとして単純に二次元セル・オートマトンでテクスチャをリアルタイムに作り、描画する方法です。

 しかし、この方法は毎回テクスチャの全てのピクセルについて計算を行わなければいけませんし、満足できるくらいの品質を出すには、かなり大きなテクスチャを作らなくてはいけません。

 そこで、妥協案として、本物のボリュームレンダリングが、半透明なものを表現するときには加色合成を行うところに注目し、複数枚のテクスチャを別々の方向にスクロールさせながら加色合成することを考えました。

 こうすると、雲のかたちがリアルタイムに変化し、なおかつハードウェアアクセラレーションを活かすことで速度が落ちないようにすることができました。

 この原理を説明するためにPhotoshopで作ったGIFアニメが左のものです。

 ちょっと手を抜いているのでわかりにくいかもしれませんが、右図で示したような三枚のテクスチャを別々の方向に一定速度で動かして、それらを加色合成するだけで、このようにリアルタイムに形の変化する雲を作ることができました。

 今回、手違いでテクスチャがシームレスでなくなっているのですが、そのぶん、境界がハッキリしているので、原理を理解しやすいと思います。

 そんなわけでまた次回。