Three.jsでWebGLのコンテンツを作成してみる(2) VRMモデルの読み込み
今回は3Dオブジェクトをシーン上に配置し、VRMモデルなどを表示してみます。
カメラの配置
正投影(OrthographicCamera)と 透視投影(PerspectiveCamera)がありますが、今回は透視投影カメラを使用します。
// カメラ
camera = new THREE.PerspectiveCamera( 45, canvasWidth/canvasHeight, 0.1, 1000 );
scene.add(camera);
camera.position.set(0,1,-3);
camera.lookAt(new THREE.Vector3(0, 1, 0));
操作
OrbitControlsを用いて、カメラを操作出来るようにします。
OrbitControls.jsがthree.jsの
\three.js-master\examples\js\controls
フォルダに入っているので、コピーしておいて
html側で
<script src="js/controls/OrbitControls.js"></script>
と、読み込ませる必要があります。
const controls = new THREE.OrbitControls(camera);
controls.target.set(0,1,0);
controls.update();
ライティング
// 環境光を追加
const ambientLight = new THREE.AmbientLight(0x999999);
scene.add(ambientLight);
// 半球光源を追加
const hemilight = new THREE.HemisphereLight(0x666666, 0x333333, 1.0);
hemilight.position.set(1, 5, 3);
scene.add(hemilight);
図形の描画
Geometry(形状)とMaterial(材質)を作成し、それを含むMesh(面)を生成し、それをシーンに追加します。
// オブジェクト
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshLambertMaterial({color: 0xFF9999});
const box = new THREE.Mesh(geometry, material);
scene.add(box);
モデルの描画
Three.jsには様々なファイル形式に対応したローダーが存在します。今回はVRMLoaderを利用してみます。
VRMはglTF形式を一部拡張したものであり、VRMLoaderは内部でglTFLoaderを呼び出しているため、glTFLoaderも読み込ませる必要があります。
<script src="js/loaders/GLTFLoader.js"></script>
<script src="js/loaders/VRMLoader.js"></script>
また、GLTFLoader/VRMLoaderは現在unlitなマテリアルに対応していないため、
マテリアルを差し替える必要があるようです。
// モデル var loader = new THREE.VRMLoader();
loader.load( 'models/vrm/Alicia/AliciaSolid.vrm', function ( vrm ) {
// VRMLoader doesn't support VRM Unlit extension yet so
// converting all materials to MeshBasicMaterial here as workaround so far.
vrm.scene.traverse( function ( object ) {
if ( object.material ) {
if ( Array.isArray( object.material ) ) {
for ( var i = 0, il = object.material.length; i < il; i ++ ) {
var material = new THREE.MeshBasicMaterial();
THREE.Material.prototype.copy.call( material, object.material[ i ] );
material.color.copy( object.material[ i ].color );
material.map = object.material[ i ].map;
material.lights = false;
material.skinning = object.material[ i ].skinning;
material.morphTargets = object.material[ i ].morphTargets;
material.morphNormals = object.material[ i ].morphNormals;
object.material[ i ] = material;
}
} else {
var material = new
THREE.MeshBasicMaterial();
THREE.Material.prototype.copy.call( material, object.material );
material.color.copy( object.material.color );
material.map = object.material.map;
material.lights = false; material.skinning = object.material.skinning;
material.morphTargets = object.material.morphTargets;
material.morphNormals = object.material.morphNormals;
object.material = material;
}
}
} );
scene.add( vrm.scene );
} );
このように、モデルを表示出来ました。