Processingでpixel shaderを使って、ピクセル操作を行っているときにシェーダーはほとんど何もしていないのに異常に処理速度がかかってしまう問題にはまりましたので、その原因と解決方法をメモっておきます。
やっていることは、以下のコードを見ていただくとわかりますがProcessing のPGraphicsオブジェクトを使用して、pixel shaderでカラーをバッファーに書き込み表示するという非常に単純なものです。
[Processingの本体のコード]
// Processing performance test PShader simpleShader; PGraphics pgShader; int scrn_w = 0; int scrn_h = 0; float time; PImage image0, image1; void setup() { size(400, 400, P2D); frameRate(120); scrn_w = width; scrn_h = height; simpleShader = loadShader("simpleShader.glsl"); image0 =createImage( scrn_w, scrn_h, RGB ); pgShader = createGraphics(scrn_w, scrn_h, P2D); } void draw() { float starttime = millis(); pgShader.beginDraw(); pgShader.shader(simpleShader); //pgShader.image(image0, 0, 0); pgShader.image(pgShader.get(), 0, 0); // this line take a lot of time pgShader.endDraw(); image(pgShader, 0, 0); float endtime = millis(); println("time " + (endtime - starttime) + "ms"); // faster code //shader(simpleShader); //rect(0, 0, width, height); }
[pixel shaderのコード: simpleShader.glsl]
void main(void) { gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0); }
このコードを実行すると私の使用しているマシーンですと20msec近くかかってしまいます。
以下の一行をコメントアウトし
pgShader.image(pgShader.get(), 0, 0); // this line take a lot of time
以下の1行をアンコメントすると、
//pgShader.image(image0, 0, 0);
期待通り1msec程度で走るようになります。
おそらくpgShader.get()がバッファーのコピーを行っているのではないかと思われます。
あるいは、pgShaderが毎フレームレンダー用のバッファを用意しているのかもしれません。
Processingのインプリに詳しい方で原因のわかる方おられましたら教えてください。