地味に拡張しているp5.js。久々にウォッチしてみると2015/10/05のリリースでWebGL対応していて、それに伴い3Dのサポートもはじめたようです。他のライブラリには色々先を越されていると思いますが、いじってみました。
##基本テンプレート
見るところは公式サイトのチュートリアル、あとはリファレンスにはそれに載り切らない実装がありました。まずは基本テンプレを
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();
}
・・・? 2Dかな?
きっとカメラがあるのだろう。と思いつつ・・・
##回してみると・・・
function setup(){
createCanvas(windowWidth, windowHeight, WEBGL);
}
function draw(){
background(200);
rotateX(frameCount * 0.01);
rotateY(frameCount * 0.01);
box(200, 200, 200);
}
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);
}
##カメラとライト
長くなってきたので、紹介だけにします。
リファレンスに実装があります。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);
// ... 以下同 ...
}
##マテリアルとライトを組み合わせる
マウスの座標に合わせてディレクショナルライトをあてます。それに呼応してくれるように、マテリアルをセットします。これも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);
// ... 以下同 ...
}
##表現してみよう
締めとして何か表現してみます。
ドーナツと球でUFO、+時間に合わせて光の明滅。そろそろ寝なきゃいけないのでw
時間経過と三角関数に関しては↓の記事に書きました
メディアアート系で重要な数式・概念 & 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があるからなぁ。
カスタムシェーダーには今後対応予定のようです。