巴山竜来『リアルタイムグラフィックスの数学』は数学観点からノイズやレイマーチングを解説する薄いながらも内容の濃い本で、濃い故に私のような数学に馴染みのない者にとっては容易に読み進められる内容ではなく、また掲載されているサンプルコードからの抜粋と書籍用に編集された図版とではうまく擦りあわされていないと感じる点もあり、理解には別途配布されているサンプルコードの入手は必須です。
このサンプルコードが Processing でも使えるか気になるのは Processing 使いとしては当然。そこで余裕が出たタイミングでまず何も考えずにPShaderで読み込んでみたところ、次の無慈悲なメッセージに遭遇する羽目になりました。
Vertex and fragment shaders in GLSL ES3.0 must have both the same version.
しょうがないなあと手すきの時間にぼちぼち対応を試みてみたのですが、思いのほかハードルは高く……
GLSL のバージョンが違う
最初のハードルであるエラーの原因はメッセージのとおりバーテックスシェーダーとフラグメントシェーダーのバージョンの違いによるもの。このエラーはバージョン指定を調整すれば解決します。Processing の利用する OpenGL のバージョンは 3.2、GLSL 的には 1.5。なので #version
ディレクティブの指定を 300 es
から 150
に変更すればクリア。
(#version
ディレクティブを削除して指定なしとする手もなくはないのですが、そうすると使えない型が出てきたりするのでおすすめしません)
uniform 変数の名前が違う
次のハードルは uniform 変数の名前。Processing の利用する uniform 変数は同書が実行環境のメインターゲットとして想定するglsl-canvasとも第 0 章で触れられているShadrertoyとも異なります。サンプルコードで参照されている uniform 変数は次の通り。
u_resolution
u_time
u_mouse
このうち u_resolution
とu_time
は Processing ではプレフィックス u_
のない名前なので、単純に u_
を削除すればよし。u_mouse
は対応する uniform 変数が存在しないので、PShader
で描画する前にPShader#set メソッドで自分で設定する必要があります。
shader.set("u_mouse", mouseX / (float)width, (height - mouseY) / (float)height);
これで一部のサンプルコードは利用できるようになります。が、本題のひとつであるノイズ利用にはまだ高いハードルが待ち受けていました……
関数がない
「第 2 章 疑似乱数」の「2.2 進数表示とビット演算」の解説内容はハッシュ関数による疑似乱数生成の下準備ですが、この説明で float 型の int 型への変換に利用する floatBitsToUint 関数が GLSL 1.5 には存在しません。同関数はビット演算のために float 型の int 型への変換を行う重要な関数。しかも The floating-point bit-level representation is preserved.
なので、ヒューマンリーダブルな型変換とは性格が異なるわけです。
floatBitsToInt 関数と同じ処理を行う関数が GLSL 1.5 で可能かはいまの私の知見ではなんとも言えません(無理だから追加された関数ではないかという直感が働きますが、肯定する知識も否定する知識もなく……)。とすると乱数生成に関しては「2.1 レガシー」で解説されるレガシー関数に置き換えるのが確実な代替手段かと思うのですが、その対応はそもそもの本の趣旨に背くことに他なりません……いやこれはまいりました……
とりあえず
とはいうものの、「第 3 章 ノイズ」以降の解説がハッシュ関数に規定されるわけではないので、がんばって置き換えて出力をたしかめる手はあるかも、とも思います。やる気が出たら試してみたいと思います。……やる気が出たら……