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);

f:id:chirotec:20181230061453p:plain

モデルの描画 

 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 );
} );

f:id:chirotec:20181230063401p:plain

このように、モデルを表示出来ました。