Archives

Three.jsでobjファイルをアップロードして操作

できました!(画像クリックで飛びます。ロードは長い。)

「ファイルを選択」で.objか.mtlをアップロードしていきます。.mtlのみはムリです。

最初は某住宅が表示されますのでいじってみてください。

ソースコードはこちら。php使ってるのでサーバ必要です。

******

アップロードするってことはobjファイルが私の手に渡りますので、それが嫌な方はソースコードを落としていじってください。

******

なんに使えるかっつーとビミョーだなー。細かい話はまた追加します。

Three.jsのOBJMTLLoaderで影を描画

Three.jsはとても便利な関数が用意されていて、OBJMTLLoader = three.js-master/examples/js/loaders/OBJMTLLoader.js もそのひとつです。

<script src="three.js-master/examples/js/loaders/MTLLoader.js"></script>
<script src="three.js-master/examples/js/loaders/OBJMTLLoader.js"></script>

でインクルード(って言うの?)。

んで、とりあえずobj(3DCGファイルの方)を表示させてみたんだが、影が描画できない。

影の描画のやり方はググれば出てくるが、端的に言えば

  • レンダラの設定:renderer.shadowMapEnabled = true;
  • オブジェクトの設定:cube.castShadow = true; cube.receiveShadow = true;
  • ライトの設定:light.castShadow = true; light.shadowCameraVisible = true;

が必要になる。

lightはTHREE.SpotLightじゃないとダメとかいろいろややこしいが、なんとかできた。

だけど、cubeとかプリミティブには影が付いてるけど、OBJMTLLoaderで読み込んだオブジェクトはできてない。あとPlaneGeometryもなぜか影が計算されない。

 

まず、planeに影が描画されない方は公式に解答がありました。

要は

renderer.shadowMapCullFrontFaces = false;

を加えなさいと。

で、肝心のOBJMTLLoaderの方。読み込みはexampleのwebgl_loader_obj_mtl.htmlに従って

var objPath = "files/Sanple.obj";
var mtlPath = "files/Sample.mtl";

var loader = new THREE.OBJMTLLoader();
loader.addEventListener( 'load', function ( event ) {
    var object = event.content;
    object.position.x = -1000;
    object.position.z = 1000;
    object.castShadow = true;
    object.receiveShadow = true;
    scene.add( object );
});
loader.load( objPath, mtlPath );

みたいな感じにしていたのですが、これではダメなようで、OBJMTLLoader.jsを見てみるとloaderが返す値はどうやらオブジェクトの配列?のようなもののようでした。

そこで、OBJMTLLoader.jsの207行目以降の関数finalize_mesh( group, mesh_info )に次のように追加しました。

function finalize_mesh( group, mesh_info ) {
    mesh_info.geometry.computeCentroids();
    mesh_info.geometry.computeFaceNormals();
    mesh_info.geometry.computeBoundingSphere();
    var tmpMesh = new THREE.Mesh( mesh_info.geometry, mesh_info.material );
    // 以下2行を加える
    tmpMesh.castShadow = true;
    tmpMesh.receiveShadow = true;
    group.add( tmpMesh );
}

できた!

でもよく見るとなんかおかしい。影になってるはずのところがなんか光ってる。

しばらく考えて、最初のコレ

renderer.shadowMapCullFrontFaces = false;

のせいだと気づき、コメントアウトすると、ちゃんと表示されました。

影の計算で、最初の面を無視しますよってのがデフォルトでtrueなんだけど、それをfalseにしちゃうと面で構成されたモノがちょっとおかしくなるかもよってことだろう。

デモスクリプトはもうちょっとだけ追加するもん追加してからにします。