ジオメトリシェーダを活用した新表現(7)~ポリゴン柱を立てて局所的にボリュームレンダリングを行うディスプレースメントマッピング

形状が大胆に変わることがない、いうなればディテールの装飾にとどまる3Dモデル形状変形であれば、テッセレータを実装しないディスプレースメントマッピングの実現方法の方が向いている。

それが基本形状の3Dモデルの外皮にポリゴン柱(角柱)を立てて、そこに対して局所的にボリュームレンダリングを実行するやり方だ。

角柱を打ち立てるのは計算量の面でベジェ曲面を計算するよりは負荷が低い。しかし、実際にジオメトリレベルの凸を作るので立体的な凹凸の表現ができる。

この方法では、対象3Dモデルを構成しているポリゴン(三角形)のうち、ディスプレースメントマッピングを行う対象となるものに対し、ジオメトリシェーダ用いてそのポリゴンを底面とした角柱を打ち立てることから始める。

ポリゴン柱を立てて、局所的にボリュームレンダリングを行うディスプレースメントマッピングの概念

アプローチのイメージとしては、角柱で大ざっぱな凸を造りだし、そこからハイトマップを用いて、ピクセル単位の凹凸をボリュームレンダリングの彫刻刀で削りだしていくような感じを連想するといいだろう。

前述したように、打ち立てる角柱の底面は3Dモデル側のポリゴンになる。この底面から打ち立てる3辺は、このポリゴンの法線ベクトルの方向とする。こうすることで、隣接する3Dモデルのポリゴンから次々に角柱を打ち立てていったときにも隙間を空けずに済む。

底面ポリゴンの3つの頂点の法線ベクトルの方向に辺を打ち立てて四角柱を形成

この底面ポリゴンの法線ベクトル方向に伸ばした角柱を支える3辺の長さは、作り出す凸部分の最大の高さとする。

打ち立てた三角柱の側面は2つの三角形からなっているので、これを利用すればこの三角柱は3つの四面体に分割できる。

三角柱は側面のポリゴンを一面とした3つの四面体に分割できる

あとはこの3つの四面体に対して、各四面体の底面の深度値と、凹凸を記録したハイトマップから取り出した変位の高さ値とを比較して、視線が衝突しているか否かを判断しボリュームレンダリングを行っていく。このあたりの仕組みは本連載第17回「視差遮蔽マッピング」とほぼ同じだ。

視線を少しずつ伸ばしていき、その位置での四面体の底面の深度値とハイトマップの高さを比較して衝突しているかどうかを判定。衝突していればそこに対してピクセル陰影処理を行う。それ以外は視線をさらに少し伸ばして……以降この繰り返し。最後、3つ目の四面体を飛び出した時点で処理終了

この方法の場合、最初の方法と比べて頂点シェーダやジオメトリシェーダへの負荷が少ないが、その分ピクセルシェーダへの負荷が高くなる。

ディスプレースメントマッピングにて生成された凹凸のセルフシャドウ表現も、視差遮蔽マッピングのところで紹介したセルフシャドウ付き視差遮蔽マッピングの方法を応用すればできなくはないだろうが、負荷と難易度は高くなる。

この方式のディスプレイスメントマッピングのデモ(DirectX SDKのデモより)。ディスプレイスメントマッピングにより背びれとトゲを付加している

オフにすると背びれとトゲが消える

(トライゼット西川善司)