本稿は「18.7: Loading OBJ Model – WebGL and p5.js Tutorial」YouTube動画を元にしています。
p5.js WEBGLモードでは、Blenderなどの3DCGツールで作成した3Dモデル(立体で作られた人物や動物、キャラクターなどのデータ)を簡単に読み込んで、キャンバスの3D世界に描画することができます。
手順は簡単で、モデルのファイルをloadModel()でp5.jsの3D世界に取り込み、それをmodel()関数に渡すだけです。
目次
3Dモデル
3DモデルはBlenderなどの3DCGツールで作成します。Blenderではマウスのクリックだけでマスコットキャラクターのサル”スザンヌ”が作成できるので、これを使用します。下図はBlenderの書き出し機能を使っているところです。書き出す形式はOBJかSTLにします。
OBJファイル
OBJ形式で書き出した.objファイルは、下図に示すような、モデルを構成する頂点の位置などを記述した単純なテキストファイルです。p5.jsはloadMode()関数でこのデータを読み取り、解釈して、p5.jsの3D世界にレンダリングできるモデルに変換します。
sketch.js
OBJファイルは、画像ファイルなどと同様、preload()関数内で読み込みます。loadModel()関数はモデルを表すp5.Geometryオブジェクトを返すので、これをグローバル関数で受け取ります。描画はdraw()内でmodel()関数にp5.Geometryのモデルを渡すだけです。
function preload() {
monkey = loadModel('assets/monkey.obj');
}
function setup() {
createCanvas(400, 300, WEBGL);
}
function draw() {
model(monkey);
}
冒頭のプログラムでは、次のコードを使用しています。画面のクリックでライトとマテリアルの有無が切り替わり、3Dモデルのポリゴンの枠が黒い線で表示されます。
let angle = 0;
let monkey, pot;
function preload() {
// サル用のobjファイルをロード
monkey = loadModel('assets/monkey.obj');
// ティポット用のstlファイルをロード
pot = loadModel('assets/pot.stl');
}
function setup() {
createCanvas(400, 300, WEBGL);
angleMode(DEGREES);
}
function draw() {
background(100);
orbitControl();
// ページクリックでライト、マテリアルの有無を切り替え
if (isLightMaterialOn) {
noStroke();
ambientLight(200);
directionalLight(255, 255, 255, 1, 1, 0);
ambientMaterial(111, 67, 53)
specularMaterial(111, 67, 53);
}
else {
noLights();
fill(255);
stroke(1);
}
// monky
push();
translate(-100, 0, 0);
// 適度なサイズに拡大
scale(40);
// そのままでは逆さなので上下を逆にする
rotateZ(180);
rotateY(angle * 1.3);
// サルを描画
model(monkey);
pop();
// pot
push();
translate(100, 20, 0);
scale(2);
rotateZ(180);
rotateY(angle * 1.3);
model(pot);
pop();
angle += 1;
}
let isLightMaterialOn = true;
function mousePressed() {
isLightMaterialOn = !isLightMaterialOn
}
loadModel()
OBJかSTLファイルから3Dモデルをロードする。
loadModel()は preload()内に置くべき。これにより、以降のコードが実行される前にモデルのロードを完了できる。
OBJとSTL形式の制限の1つに、スケールの感覚が組み込まれていない、ということがある。これはつまり、モデルのサイズは書き出したプログラムによってさまざまに異なる可能性があるということで、読み込んだモデルが表示されない場合には、normalizeパラメータをtrueにしてloadModel()を呼び出してみる。normalizeをtrueにすると、p5.jsに適合するようにモデルのサイズが変更される。またscale()関数を使うと、モデルの最終(描画される)サイズに変更を加えることもできる。
なお、着色されたSTLファイルは現状ではサポートされていない。色付きのSTLファイルは色属性なしでレンダリングされる。
シンタックス
loadModel(path, normalize, [successCallback], [failureCallback])
loadModel(path, [successCallback], [failureCallback])
パラメータ
path 文字列: ロードするモデルのパス
normalize ブール値: trueの場合、ロード時、モデルは標準的なサイズにスケーリングされる
successCallback 関数(p5.Geometry): モデルのロードが終わったときに呼び出される関数。関数には3Dモデルオブジェクトが渡される(オプション)
failureCallback 関数(Event): モデルのロードが失敗した場合にイベントエラーとともに呼び出される(オプション)
戻り
p5.Geometry: p5.Geometryオブジェクト
model()
3Dモデルを画面にレンダリングする。
シンタックス
model(model)
パラメータ
model p5.Geometry: レンダリングする、ロードした3Dモデル