JavaScript
HTML5
WebGL
p5.js

p5.jsがWebGL&3D対応。軽くいじってみます

More than 1 year has passed since last update.

地味に拡張しているp5.js。久々にウォッチしてみると2015/10/05のリリースでWebGL対応していて、それに伴い3Dのサポートもはじめたようです。他のライブラリには色々先を越されていると思いますが、いじってみました。

最後は、時間がなかったのでシンプルなUFO作って終了
29g51155224222822233323233.gif

基本テンプレート

見るところは公式サイトのチュートリアル、あとはリファレンスにはそれに載り切らない実装がありました。まずは基本テンプレを
p5パッケージのサンプルファイルの、コメント冒頭にはShiffmanのサイトへのリンクが。宣伝乙であります

// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com

// Example 1-1: stroke and fill

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
}

function draw(){
  background(255);
  box();
}

結果
スクリーンショット 2015-11-27 0.02.47.png

・・・? 2Dかな?
きっとカメラがあるのだろう。と思いつつ・・・

回してみると・・・

function setup(){
  createCanvas(windowWidth, windowHeight, WEBGL);
}

function draw(){
  background(200);
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
  box(200, 200, 200);
}

動いた
29g5115522422282.gif

frameCount(=進んだフレーム数に応じて増える)
windowWidth(ブラウザの横幅)
windowHeight(縦幅)
と見慣れない便利変数が出てきました。前無かった気がする・・

どうやらグローバル空間はどんどん汚染していく方針のようです。プレイグラウンド用途に特化ですね。まぁ、それもいいと思います。
※2015/12/22 注※
グローバル汚染は回避可能なことが判明しました。
「p5.js を instance mode で使う」
http://qiita.com/turusuke/items/c92a13602523d6378cc0

プリミティブ立体勢揃い&小ネタ

リファレンスにそろっと入ってましたが、drawの中に「orbitControl();」と入れるとドラッグでカメラを動かせるようになります。Threeインスパイアかな
立体を勢揃いさせる時、そのままだと重なるので、translateで座標をずらします。これはまさにProcessingスタイル。コード短いな〜。

function setup(){
  createCanvas(windowWidth, windowHeight, WEBGL);
}

function draw(){

  //ドラッグでカメラ動かす
  orbitControl();

  //ボックス(立方体)
  box(50, 50, 50);

  //動け
  translate(200,200,-100);
  //コーン(三角錐)
  cone(100, 100);

  //プレーン(平面)
  translate(-150,200,-200);
  rotateX(radians(-90)); //-90度回転
  plane(500, 500);

  //スフィア(球)
  sphere(200);

  //シリンダー(円柱)
  translate(-350,100,150);
  rotateX(radians(-90)); //-90度回転
  cylinder(100, 100);

  //トーラス(ドーナツ)
  translate(0,0,350);
  torus(200, 60);

}

転校生たち。初々しいですね
29g511552242228222.gif

カメラとライト

長くなってきたので、紹介だけにします。
リファレンスに実装があります。http://p5js.org/reference/
Three.js,Unityのようなスタイルを踏襲しているようです。プロパティはそれらをやっていれば言わずもがなでしょう(丸投げ)

カメラの種類
・シンプルカメラ
camera(x,y,z)

・パースペクティブ(透視投影)カメラ
perspective(fovy, aspect, near, far)

・オーソグラフィック(正投影)カメラ
ortho(left, right, bottom, top, near, far)

ライトの種類
・アンビエントライト(環境光)
・ディレクショナルライト
・ポイントライト

テクスチャを貼る

画像ファイルのオリジンポリシーにより、ローカルの画像は使えません。
ここで python -m SimpleHTTPServer の登場。

var img;

function setup(){
  createCanvas(windowWidth, windowHeight, WEBGL);
  img = loadImage("sc.png");
}

function draw(){
  texture(img);

  // ... 以下同 ...
}

貼れました。短いなぁ。
スクリーンショット 2015-11-27 0.56.05.png

マテリアルとライトを組み合わせる

マウスの座標に合わせてディレクショナルライトをあてます。それに呼応してくれるように、マテリアルをセットします。これもProcessingらしいプロセスです。

function setup(){
  createCanvas(windowWidth, windowHeight, WEBGL);
}

function draw(){

  //マウスの座標
  var dirY = (mouseY / height - 0.5) *2;
  var dirX = (mouseX / width - 0.5) *2;

  //マウスに合わせてライト強弱
  directionalLight(250, 250, 250, dirX, -dirY, 0.25);

  //マテリアルをセット
  ambientMaterial(250);

  // ... 以下同 ...
}

29g511552242228222333.gif

表現してみよう

締めとして何か表現してみます。
ドーナツと球でUFO、+時間に合わせて光の明滅。そろそろ寝なきゃいけないのでw

どーん。
29g51155224222822233323233.gif

時間経過と三角関数に関しては↓の記事に書きました
メディアアート系で重要な数式・概念 & p5.jsで遊ぶ
http://qiita.com/hp0me/items/8f43ad146744310664ae

function setup(){
  createCanvas(windowWidth, windowHeight, WEBGL);
}

function draw(){

  orbitControl();

  //時間ライト&マテリアル
  var intensity = Math.sin(frameCount * 0.1);
  directionalLight(250, 250, 250, intensity, intensity, 0.25);
  ambientMaterial(250);

  //地面
  translate(0,300,-200);
  rotateX(radians(-90)); //-90度回転
  plane(500, 500);

  //UFO
  var x =  Math.cos(frameCount * 0.03) * 300;
  var y =  Math.sin(frameCount * 0.06) * 300;
  translate(x,y,300);
  torus(200, 60);
  translate(0,0,100);
  sphere(150);

}

主な情報源

以下の2つにほとんど全ての情報があります。
公式チュートリアル(github)
https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5
公式リファレンス
http://p5js.org/reference/

感想

かなりインスタントに3Dビジュアライゼーションができました。Processingらしいです。あとは何を作るかです。でもThreeがあるからなぁ。
カスタムシェーダーには今後対応予定のようです。