Screen Space Mesh†陰関数曲面から表面を記述する三角形メッシュを抽出する場合, Marching Cubesに代表されるように3D空間を3Dのグリッド構造で分割し, 各セルにおいてメッシュを生成するのが一般的である. これに対して2Dスクリーン空間でメッシュを生成するのが, Screen Space Meshes(SSM)¬e{Muller2007:M. Muller, S. Schirm and S. Duthaler, Screen space meshes, Proc. SCA2007, pp.9-15, 2007.};である. SSMはパーティクルから生成した閉じた陰関数曲面を対象としている. 物体形状を三角形メッシュで表した場合,視点から見えない面(視点から隠れている面)は描画する必要がない. このような隠面消去はOpenGLなどの3D APIにおける描画では一般的である. SSMでは同様の考え方で,そもそも隠面は三角形ポリゴンを作る必要がないとし, 3D空間内のパーティクルを2Dスクリーン空間に投影して生成したデプスマップから, 2Dメッシュを生成,3D空間に逆投影することで視点から見える三角形ポリゴンだけで構成されるメッシュを生成する. また,デプスマップに対して平滑化フィルタをかけることでメタボールのようなレンダリングを得る. 3D Marching Cubesでは計算コストは各軸の分割数nの3乗に比例するが, SSMでは2D空間でメッシュを生成するので,nの2乗に比例するだけである. ただし,視点から見えている面しかできないので, 屈折面だと1回の屈折しか考慮できないことには注意. 入力†SSMはパーティクルデータを対象としているため,入力はパーティクル座標と投影変換行列の2つとなる.
さらに,固定パラメータとして以下のものがある.
手順†デプスマップを とし,各グリッドでのデプス値をで表す. グリッド分割数は,スクリーン間隔とスクリーンサイズ()から以下のように計算する.
以下でを用いたスクリーンスペースメッシュの生成方法を述べる. デプスマップ生成†まず,をで初期化する. 次にすべてのパーティクルの中心座標,半径に投影変換を施す. まず,中心座標に投影変換行列をかける. さらにで割ることで[-1, 1]の正規化座標系に変換 はメッシュ生成の基準に用いるので正規化しない. 半径に関しても同様に, は投影変換行列の各要素である. はすべてのパーティクルで共通なので事前に計算しておく. パーティクル中心座標と半径を使ってデプス値を更新する. ここで, ただし,は, を満たす範囲内のセルである.ここで,である. この処理をすべてのパーティクルで行うことでデプスマップが生成される. デプスマップ平滑化†ユーザが設定したフィルタ幅でBinomialフィルタをかけることでデプスマップを平滑化する (の場合,中心となるデプス値の前後3つのデプス値を使う). まず最初にであるすべてのデプス値に対してx軸方向に1次元フィルタを適用する. 次に同様にしてy軸方向にも適用する. また,,中心デプス値との差が以内のデプス値のみをフィルタに用いる. 輪郭ノード検出†メッシュの外周となる輪郭部分に属するノードを検出する. ここでいうノードとは輪郭をまたぐグリッドエッジ(輪郭エッジ)上の点のことである. ここでのグリッドとはMarching Squaresによりメッシュを生成するためのグリッドのことであり, デプスマップ用のグリッドとは異なる.ただし,説明を簡単にするために以下では両者のグリッド解像度は同じであるとする. 隣接するグリッドのデプス値を比較することで,エッジが輪郭と交差しているかどうかを判定するのだが, 単純にデプス値が有限と無限の境が輪郭とすると, 下図のような場合に本来つながっていないところがつながってしまう(青の波線). 本来赤の実線のようなメッシュを作りたいので,デプス閾値を使って輪郭となるノードを検出する.
デプスマップ生成の際と同様に各パーティクルごとにグリッドエッジを走査し,円と線分の交差判定を使い, パーティクル境界と交差するエッジとノード,および,ノードデプス値を求める. 求めたエッジが輪郭エッジとなる条件は以下.
さらに,
を満たす場合,そのノードを輪郭ノードとしてエッジに格納しておく. このとき,輪郭ノードが含まれる輪郭エッジの両端点のデプス値は後で使うので参照できるようにしておく.
メッシュ頂点生成†輪郭ノードに加えて,内部の頂点も加えて,メッシュ頂点を算出する. 頂点を生成するパターンは以下の3つである.
front vertexの座標,デプス値は輪郭エッジに格納された輪郭ノードと同じである. back vertexの座標は対応するfront vertexと同じであるが,デプス値は分からない. そのため,隣接するグリッドノードのデプス値の外挿により算出する(下の図参照).
三角形メッシュ生成†下図参照.三角形間の隙間はそこに輪郭頂点があることを示す. また,外部輪郭の場合はデプス値がである頂点を含む三角形は排除する. 7,11,13,14のケースでは,3層に分かれており,もう一つ back vertexが必要, 15のケースでは4層で,2つのback vertex を追加する必要がある.
基本的にはMC法と同じくテーブルを作ってやればよいが, いくつかの例外処理(追加のback vertexが必要な場合など)は必要である. 輪郭平滑化†各輪郭頂点座標を,隣接頂点と自分自身の座標値の平均値で置き換えることで, 輪郭の平滑化を行う.ただし,メッシュ生成におけるケース0の頂点は固定とする. 3D空間への逆投影†スクリーン空間内の2Dメッシュを3D空間に戻す. 各メッシュ頂点に対して,以下の処理を行う. ここで,であり, 実装結果†パーティクルを立方体形状にランダムに発生させて,そのメッシュをSSMで生成した結果を以下に示す. 左がメッシュ生成した結果で,右がそのデプスマップを示す. スクリーンの大きさは 640x640 であり,デプスマップのグリッド間隔h=8である. フィルタ幅は3,パーティクル数5000である. デプスマップ上のメッシュを描画した図を以下に示す. また,生成したメッシュを異なる角度からみた結果は以下. CPU実装でもデプスマップ解像度が100x100程度ならリアルタイムで実行でき,GPU版ともほとんど計算時間が変わらない. より細かくなって300x300などになってくるとCPU版だと0.15sec/frameぐらい,GPU版だと0.05sec/frameぐらいで実行できた (Core i7 2.93GHz, GeForce GTX580). サンプルコード(GPU実装含む)†SSMを実装してみたコードを以下に置く(CUDAによるGPU実装含む).
|