このツールはPsychlopsにおけるGLSLサポートをテストするツールです。 画面右下のボタン群で任意のGLSLプログラムをロードすることができます。 GLSL/fieldでGratingなど任意の式の描画を、 GLSL/imageで任意の画像に対応する変換を行います。 PNG imageをロードするとGLSL/imageに適用する画像を差し替えることができます。 画面左上の変数操作ボックスを使用することで、シェーダへの引数(後述)を変えることができます。 ※(注意点) グラフィックドライバによってGLSLコンパイラの実装に差がありますので、 配布前にはご確認いただけますようお願いします。 //////// シェーダプログラムの書き方 ///////// 今回記述している方法は、OpenGL2.0準拠を謳うビデオカードの多くに合わせるために作成した仕様です。 今後、よりよい方法に変更する予定ですので、これはPsychlops1.5.0における記述法になります。 Psychlopsでのシェーダの利用は現在はピクセルシェーダ(フラグメントシェーダ)のみ利用します。 これは、各画素の色の定義を記述するもので、通常のプログラムで必要なループやメッシュグリッドを書く必要はありません。 以下のPsychlops/GLSL、Psychlops/C++、Psychtoolbox/Matlabコードは相同です。 【Psychlops/GLSL】 void main(void){ pix( sin(xp())/4.0+0.25 + sin(yp())/4.0+0.25 ); }; 【Psychlops/C++】 Image img(100,100); Color col; for(int x=0; x<100; x++) { for(int y=0; y<100; y++) { img.pix(x,y, col.set( sin(x)/4.0+0.25 + sin(y)/4.0+0.25 ) ); } } 【Psychtoolbox/Matlab】 [x,y] = meshgrid(0:100, 0:100); m = sin(x)/4.0+0.25 + sin(y)/4.0+0.25 ); Screen(window, 'PutImage', m); コンパイルエラーは画面上に表示されるほか、実行ファイルと同じパスにある"GLSLTesterErrorLog.txt"に記録されます。 //// 引数の受け取り方 //// 現状、Psychlopsのシェーダプログラムでは、各描画単位への引数は 以下の記法により引き渡します。 (GLSL側) in float contrast, frequency, orientation, phase; // ← main宣言の直前に"in float "に続けて引数をコンマ区切りで記述し、最後にセミコロンを打って改行。ここで指定した順にC++側の配列に格納。 void main(void) { ... (C++側) double arg[16]; // ← 渡す引数を格納する配列を用意。配列長は4, 8, 12, 16のいずれか固定。 shader_field.draw(area_rect, arg, 4); // ← ShaderField / ShaderImageの第2引数で配列を、第3引数で配列長/4を指定。 内部的にテクスチャ座標指定を経由して受け取るよう変換されます。 Psychlopsを使用する限りあまり関係ありませんが、 内部のgl_TexCoordは[0]〜[7]までありますが、うち[3]以降はPsychlopsが使用します。 また、ShaderImageを使う場合は[0]も使用します。 //// 基本文法 //// GLSL公式サイトよりご確認お願いします。 http://www.opengl.org/documentation/glsl/ //// Psychlopsで定義しているGLSL関数 //// const float PI; 円周率(定数) const float E; ネイピア数(定数) float xp() 画像左上を原点としたx座標(ピクセル単位)を得ます。 float yp() 画像左上を原点としたy座標(ピクセル単位)を得ます。 float rp() 画像中心からの距離を得ます。 float thetaf() 画像中心からの角度を得ます。 float width() 画像の幅を得ます。 float height() 画像の高さを得ます。 void pix(in vec4 c); 画素に色を指定します。 void pix(in float l); 同上 void pix(in float l, in float a); 同上 void pix(in float r, in float g, in float b); 同上 void pix(in float r, in float g, in float b, in float a); 同上 vec4 getPix() 現在処理している画素の色を得ます(ShaderImage専用) vec4 getPix(in int x, in int y) 座標(x, y)の画素の色を得ます(ShaderImage専用) vec4 getPixOffset(in int x, in int y) 現在処理している画素から(x, y)ずれた画素の色を得ます(ShaderImage専用)