3DCG
WebGL
GLSL
More than 1 year has passed since last update.

これはGPU で暖を取りたい人のための GLSL Advent Calendar 2016の21日目の記事です。

今回は少し頂点シェーダーのネタがあって嬉しいですね。
というわけで今年もvertexshaderart.comにお邪魔して頂点シェーダーネタです。

Blob

Blobとはいわゆるメタボールのことです。
使い分けがあるのかは知りませんがソフトウェアによってそんな呼び方をしているものもあります。
今回はただ語呂合わせのためにそう呼んでいます。

Vertexshaderで描く

本当はこのようなものをレンダリングするにはレイマーチングが簡単です。
それにはフラグメントシェーダーを使うのが高速で美しく、今ではそのような方法はこのアドベントカレンダーに限らずあちこちで紹介されています。

しかしここでは頂点シェーダーを使います。
それにはBlobにより生成される曲面に沿ってポリゴンで面を張るアルゴリズムが必要です。

Logic

とりあえずボクセルを利用して面を張ります。ボクセルとは3D空間上に等間隔に並べたサンプル点です。そして近傍の8個のボクセルからなる立方体をセルと呼んだりします。

voxel.jpg

有名なものはマーチングキューブスでしょうか。
ちなみにこのWikipediaを鵜呑みにして15種類で作ると穴が開くという罠があります。
有名な実装があるので参考にしましょう。

マーチングキューブスはセルの立方体の中にできる面のパターンを全てリストアップしておくというアルゴリズムです。これはわかりやすくて良いのですが、一度に生成されるトライアングルの数が一定ではないという難点があります。

ジオメトリシェーダーなどがある環境ならいいのですが、ここではWebGLを使うのでそんなものはありません。

そこでSurfaceNetという方法を使います。実はSurfaceNetという名前の出所が若干謎なのですが検索すると一応出てくると思います。

これはセルの辺が面に突き刺さっていた場合、その辺を共有する4つのセルの内部には曲面上の点があるはずなので、その点を使って辺に交差する面を張る、というアルゴリズムです。

surfacenet.jpg

この方法では1つの辺に貼られる面は必ず四角形になります。
つまり頂点シェーダーで実装するのが簡単です。

GPUを加熱してやるのだ!

というわけでこちらにとりあえず作ってみたものを用意しました。
残念ながらフラグメントシェーダーで鬼のようなレイマーチングをするほど加熱しませんが、頂点シェーダーとしてはそこそこ暖をとれると思います。

しばらく見ていると四角形の面を張っているのがわかりやすいような仕掛けを入れてありますので十分加熱してご賞味ください。

それではオヤスミパラノイア。
素敵な頂点シェーダーライフを!