ofShaderでジオメトリシェーダーを使ってみた

はじめに

前回の記事でVertexShaderとFragmentShaderについて書きましたが、
実はShaderは、VertexShader→GeometryShader(省略可)→FragmentShaderの順番で処理されています。

今回は、前回に省略したGeometryShaderを使ってみたいと思います。

GeometryShaderを使用することによって、次のようなことができます。
・VertexShaderでは1頂点ごとの処理に対し、GeometryShaderでは面ごとの処理が可能。
・頂点を増減させることができ、プリミティブを変更することもできる。
・隣接する頂点を参照することができる。

→このことにより、下記のようなVertexShaderとFragmentShaderだけでは難しい表現などが実現可能です。
 ・オブジェクトをポリゴンごとに分解してバラバラになる表現
 ・点座標を基にポリゴンを作り、テクスチャを貼ることで大量のパーティクルの表現 

今回、以下の画像の3次元グラフのようなものを作成してGeometryShaderを試してみました。

環境

・macOS Sierra 10.12.6
・openFrameworks v0.9.8
・GLSLバージョン 150

Shaderソースの実装

・shader.vert

VertexShaderは位置、法線、色の情報をGeometryShaderにそのまま渡します。

・shader.geom

GeometryShaderでは、頂点情報を設定したらEmitVertex()を呼びます。
今回は、三角形ポリゴンなので3頂点の設定が全て終わったらEndPrimitive()を呼び三角形ポリゴンの設定を完了します。上記では3頂点の入力に2つのプリミティブ(平面と凹凸面)の計6頂点を出力しています。
また、凹凸面に関しては色情報が赤い部分ほど高くなるようにしています。

・shader.frag

FragmentShaderは、頂点の色をそのまま出力します。

openFrameworksの実装

・ofApp.h

・ofApp.cpp

平面のMeshの情報をShaderに渡してCam上で表示しています。
今回は、keyイベントで高さを変えられるようにしています。

実行結果

●この記事を書いた人