Deltographos::Blog

deployed

つぶやきGLSLの「型」

つぶやきGLSL

趣味で参加している、twitterの「#つぶやきGLSL」。今日はこれについて、少しだけメモとして書いておきたいと思います。GLSLというのは、シェーダーを記述するプログラミング言語で、このハッシュタグは、要するに1 tweet 280文字に収まるように、短いGLSLを書くという遊びです。

でもシェーダーを知っている人ならば、「GLSLは、どう考えても280字に収まんないでしょ」と思うでしょう。確かに、たとえばGLSL sandboxやShadertoyなどの、オンラインエディタ兼公開サイトを見たりすれば、えらく長々とした複雑なシェーダーのコードが多数掲載されています。

でも、ありがたいことに、共通の定数や変数の宣言をすでにやってくれているオンラインエディタがあります。@h_doxasさんの「twigl.app」です。このサイトにアクセスしたら、regulation(GLSLのバージョン選択)をgeekest (300 es)にします。すると、いろいろな短縮表記が使えるようになるんですね。

たとえば、GLSLの最初に宣言せよと教わるuniform vec2 resolutionなどは不要で、rだけで済ますことができます。同じくuniform float timeなんてのも、あらかじめtに置き換えられています。座標を取得するgl_FragCoordはFCで済みますし、色を出力するgl_FragColorもoで置き換えられています。これは便利ですね。そもそもvoid main()(Shadertoyならvoid mainImage(out なんたら, in なんたら))すら記さず、中身だけ書けばオッケーです。

そんなわけで、宣言要らずで、各種の短縮形を駆使できるtwigl.appのgeekest(300 es)モードは、まさにつぶやきGLSLのためのオンラインエディタだといえるでしょう。多謝。

全体の型 = 万能調味料みたいなもの

さて、では何から書けばよいか。ここで「型」が大いに役に立ちます。いろいろ使えるパターンはあるかと思いますが、個人的にいつも用いているのは次のような型です(先達の方々が使っていた型を、基本的に流用しています)。これは横に回転するトーラスを描く例です。一番下に結果の画像を載せておきます。

float i,j,d=.2,e; vec3 p; // 変数の宣言
for (i=0.;i++<64.&&d>1e-4;){ // 第1のループ
    p=normalize(vec3((FC.xy-.5*r)/r.y,e-.1))*e; // 座標の正規化
    p.z-=2.;p.xz*=rotate2D(t); // 平行移動や回転
    for(j=0.;j++<8.;) // 第2のループ
        p=abs(abs(p)-4.)-1., // 折り込み
        d=length(vec2(length(p.xy)-.3,p.z))-.2, // 距離関数の処理
        d-=clamp(length(p),-.2,.2)/1e4; // 補正、重ねなどなど
    e+=d; // 再帰のために
}o+=3./i; // 色の出力

ループ2つで、その中に処理を書いていくというのがこの型です。最初のループ内で、座標の正規化と移動・回転などの操作を記し、続く2つめのループで、折り込みや回転などの処理、距離関数の処理などを記します。最後は色づけです。

(ハッシュタグを含めて280字に収めるためには、改行やインデントなどを省く必要がありますが、基本形は上の通りです。)

以上、たったこれだけですが、これが全体の流れで、それぞれの個別の箇所では、パラメータの調整や関数の追加など、いろいろな工夫が可能です。そのあたりは先達の方々の方法を参考にしたりして、いまだ手探りで学んでいる状況です。発見の喜びがあったりもして、ここが一つの醍醐味かと思います。

そうした個別の方法についても、追々メモしていきたいと思いますが、今回は簡単ですがひとまず大枠を示してみました。これっていわば万能調味料みたいなものかなと思います。大泉洋が出ている調味料のCMで「これ使っときゃ、大概うまいよ」というのがありますが(笑)、まさにそんな感じでしょうか。

image block

https://twigl.app?ol=true&ss=-NZ9sZUqbwGt3BnewwZk