【GLSL】メタボールの作り方

GLSL

ーナカタの記憶 vol.3ー
幼稚園の時、魔女に扮装したどっかのおばちゃんのハイヒールで足踏まれてメチャメチャ痛かった。

はじめに

なんか「ぐにゅ~ん」てくっついたり離れたりするヤツ。どっかのwebサイトで見たんです。すごいなぁ。なんていう名前の技術なんだろうか。「メタボール」っていうらしい。

ググる

メタボールっていうのは、複数の立体を融合して滑らかな曲線を作る方法なんだとか。さらにこんな事も書いてありました↓。

様々な濃度勾配を持つ球を空間中に近づけて配置すると、それらの間の空間には濃度が重なりあって外縁部よりも濃くなる部分が現れる。このとき、ある特定の濃度を持つ点を繋ぎあわせて面を定義すると、配置された球が滑らかな曲面で繋がった立体図形を構成することができる。

IT用語辞典 e-Words

最近の僕はとても頭が冴えているので、これ読んだだけで作り方が分かってしまったのです。一瞬でコードが頭に浮かびました。すぐに試したかったけど、その時は仕事中だったので「仕事してる場合じゃない。早く帰りたい」と強く思ったのでした。

答え

<!-- フラグメントシェーダー -->
<script id="fs" type="x-shader/x-fragment">
  precision mediump float;

  uniform vec2 uResolution; // ウィンドウの幅と高さ
  uniform vec2 uMouse; // マウス座標
  out vec4 fragColor; // 最終的なピクセルの色

  void main(void) {

    // 正規化
    vec2 p = (gl_FragCoord.xy * 2.0 - uResolution) / min(uResolution.x, uResolution.y);
    
    float c = 0.2 / length(p); // 中央の白い丸
    c += 0.2 / length(p - uMouse); // マウスの位置の白い丸
    c = step(0.7, c); // 0.7以上は1.0に、0.7未満は0.0にする

    fragColor = vec4(c, c, c, 1.0);
    
  }
</script>

これだけ。こうなります↓。

考え方

step関数をコメントアウトするとこうなります↓。

薄いボンヤリ同士が重なると、濃いボンヤリになります。濃くなったところが「ぐにゅ~ん」ってなっているように見えるんですね。で、このままだと白と黒の境界がボンヤリしているので、step関数で「ボンヤリが0.7以上は白!0.7未満は黒!」って二極化してあげると出来上がりです。

あとがき

これは色々使えそうな予感。今回は以上です。ありがとうございました。

おしゃれ度

★★★☆☆

Posted by ナカタ