Processing.jsでWebGL

JavaScript Advent Calendar 2011 WebGL駅伝13日目の記事です。

Three.jsを使うと超簡単にWebGLを扱えますが、簡単という面ではProcessing.jsも負けていないのではないでしょうか。

WebGLの有効なブラウザでスタートボタンを押してください。


int n = 0;
int N = 3000;

float xs = new float[N];
float ys = new float[N];
float[] zs = new float[N];

void setup(){
  size(500, 500, P3D);

  float dt = 0.01;
  float x = 1.0;
  float y = 1.0;
  float z = 1.0;
  float p = 10.0;
  float r = 28.0;
  float b = 8.0/3.0;

  for (int i = 0; i < N; i++) {
    xs[i] = x;
    ys[i] = y;
    zs[i] = z;
    x += dt * p * (y - x);
    y += dt * (x * (r - z) - y);
    z += dt * (x * y - b * z);
  }
}

void draw(){
  // fill the viewport with white
  background(255);

  camera(0,0,0.001, 0,0,0, 0,1,0);
  ortho(-60,60, 60,-60, -60,60);

  rotateX(PI/12);
  rotateY(0.005 * n);

  // x-axis (red)
  stroke(255, 0, 0);
  line(0,0,0, 100,0,0);

  // y-axis (green)
  stroke(0, 255, 0);
  line(0,0,0, 0,100,0);

  // z-axis (blue)
  stroke(0, 0, 255);
  line(0,0,0, 0,0,100);


  noFill();
  stroke(128,128,0);

  beginShape();
  int last = min(n,N);
  for(int i = 0; i < last; i++){
    vertex(xs[i],ys[i],zs[i]);
  }
  endShape();


  noStroke();
  fill(255, 0, 255);
  translate(xs[i], ys[i], zs[i]);
  sphere(1);

  n++;
}

ただ、マトリックスという概念が難しいかと思います。cameraなどの関数でもマトリックスが変わりますし。


同じようなことをThree.jsでやったのがこちらのデモです。↓

記述量はちょっと増えてますが、さほど変わりません。一つ決定的に違うのが、カメラの動かし方です。Processing.jsで

  rotateX(PI/12);
  rotateY(0.005 * n);

とやると、これはカメラではなく世界を回してるのに対し、Three.jsはカメラを動かすしかなさそうです。

  camera.rotation.x = Math.PI / 12;
  camera.rotation.y = 0.005 * n;

↑こういうふうにしてるんですが、これだとProcessing.jsのほうとちょっと意味が変わってきちゃうのです。(カメラではなくて一つ一つのオブジェクトを世界に対して動かす方法もあるみたいですが)

どちらが扱いやすいかといえば…どちらも面倒ですね。Processing.jsはステートフル、Three.jsはステートレス、という大きな違いです。