OpenGL でテセレーションのシェーダー(TCS,TES)を使う

OpenGLの4.x世代でテセレーションのシェーダーが使えるようになり、DirectX11相当になりました。前回は簡単な三角形や四角形の再分割は作ってみたので、今回はモデル形状について適用してみたいと思います。
 そして割とテセレーションのサンプルでは定番の PN Triangles の方法で OpenGLのシェーダー Tessellation Control Shader(TCS), Tessellation Evaluation Shader(TES) を作成して描画してみたいと思います。

PN Trianglesについて

PN Triangles は、位置と法線の情報から曲面での再分割の位置を求めるためのアルゴリズムです。詳しくは論文の Curved PN Triangles を参考にしてください。
 DirectX での実装例はよく見かけるのですが、OpenGLでの実装についてはあまりやられているのを見かけませんでした。今回やってみて感じたのは特にOpenGLだから難しいということはない、ということです。それなのにサンプルが少ないのは残念ですね。

DirectX と OpenGL でのシェーダーの違い

基本的には、ハルシェーダー=Tessellation Control Shader、 ドメインシェーダー=Tessellation Evaluation Shader と対応しています。しかし、ハルシェーダー部分が DirectX と OpenGL でちょっと違います。DirectX ではハルシェーダーと表現している部分の処理の中に、テセレーション係数を求めるためのパッチ係数フェーズとコントロールポイント出力フェーズの2つが含まれています(コントロールポイント出力フェーズでは後段へのデータ出力の役割もある模様)。
 OpenGLのTCSでは、パッチ係数フェーズとコントロールポイント出力フェーズを分けずに TCS内で一緒くたに記述してしまうのが作法のようです。一部の例では、パッチ係数を求めるときは下記のように gl_InvocationID で1回だけ実行されるようにしていたりするようです。

図示するとこんな感じでしょうか。

tcs-tes-diagram

PN Trianglesを実装してみる

PN Trianglesを実装してみました。上記のDirectXでのシェーダーとGLでの対応関係がわかってしまえば、DirectXのサンプルを読み解いて、GLで実装し直すのもそこまで難しい話ではないように思います。
 また描画に関しては以前に説明したとおりの内容でモデル描画を行えばよいのでここでは実装したシェーダーを公開してみたいと思います(シェーダー内容は長めなコードになるので末尾を参照)。またプロジェクション変換は頂点が確定した後で行う必要があるので、今までは頂点シェーダーでやっていましたが、これからは TES(ドメインシェーダー) で行う必要があります。

描画結果

動画でキャプチャしてみました。

立方体をPN Trianglesしてみた。確かに割れてます

立方体だけど、8つの頂点の法線は隣接面の頂点と共有できるように合成したものを使用。このときちょっと丸みを帯びていきます。

モデルとして定番のteapot で PN Triangles を適用してみました。

シェーダー例

形状がわかりやすいように、カラー情報は法線を出力するようにしています。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする