Three.jsを使用してJSON形式の3Dモデルの表示ができない。
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 5,369
前提・実現したいこと
IE11環境で、visualstudioを使用して3Dモデルの表示をしようとしています。
Three.jsはr76を使用しており、3Dデータは、brenderからJSON形式でエクスポートしたものを使用しています。
3Dモデルの読み込みには、JSONLoaderを使用しています。
発生している問題・エラーメッセージ
3Dモデルが表示されません。
visualsutadioのデバッグ機能を使用して確認すると、
JSONLoaderのload関数で登録するコールバック関数の第2引数[下記コードのmaterials]がundifindで返されている。
該当のソースコード
var loader = new THREE.JSONLoader();
loader.load('model.js', function (geo,materials) {
model = new THREE.Mesh(geo, materials);
model.position.set(0, 0, 0);
model.scale.set(10, 10, 10);
scene.add(model);
}
);
試したこと
課題に対してアプローチしたことを記載してください
Three.jsのリビジョンを変更してみたりと試しましたが、
うまくいきません。
JSONLoaderのload関数で登録するコールバック関数の第1引数[上記コードのgeo]は中身の参照ができたので、うまく動いているようにに思います。
同じページ内で読み込みせずに作るモデルの表示はできているので、バグの原因は、上記コード内と見当をつけました。
補足情報(言語/FW/ツール等のバージョンなど)
仕様ブラウザ:IE11
開発環境:visual studio Community2013
使用ライブラリ:Three.js[r76]
使用3Dデータ:brenderからJSON形式でエクスポートしたもの
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
r76はまだノータッチだったので、ちょっと古いバージョン(r73)の情報になってしまうかもですが…
model = new THREE.Mesh(geo, materials);
の行でmaterialsにundifindが返っているんですよね?
new THREE.Mesh
する前にmaterialだけ先にnew THREE.MeshFaceMaterial
し、
その変数をmodelの第二引数に代入しなければならなかったのではないでしょうか?
loader.load('model.js', function (geo,materials) {
var mat = new THREE.MeshFaceMaterial(materials);
model = new THREE.Mesh(geo, mat);
//省略
}
一度お試しを…
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.34%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/05/03 01:58
試してみましたが、うまくいきませんでした。
var mat = new THREE.MeshFaceMaterial(materials);
の実行時点で、materialsはundifindになっています。
undifindeの引数でTHREE.MeshFaceMaterialすることになります。
matの状況を見るとmat.materialsは空のようなので、
マテリアルの登録がされていない?という状態です。
2016/05/03 02:11
…というか、jsonデータなのにファイル名jsになってますが…
何のソフトでどのようにエクスポートしたデータでしょう?
2016/05/03 02:24
brenderからThree.js付属のexporterを使用して
JSON形式でエクスポートしたものです。
実は最初.jsonとしてしていたのですが、
その時はコールバック関数function (geo,materials){}が
呼び出しされていないことを確認しています。
この辺りはvisualstudioのIISの設定の可能性もあるのかな?と思います。
2016/05/03 03:24
多分それでnew THREE.JSONLoader()が失敗しているのだと思います。
サーバーがvisualstudioだったのですね…(見落としていました。。)
となると、ちょっと動作が分からないので何とも言えませんが
コールバックが呼び出されない時に特にエラーが出ていなかったのであれば
別のサーバーや開発環境で一度試されたほうが良いかもしれません。
brenderからJSON形式でのエクスポートなら本来読み込めるはずなので、
new THREE.JSONLoader().load()のコールバックが動かないのはそれ以前にエラーで止まっている以外考えられないかな…と。
多分firefoxあたりだと、ローカルファイル状態でも稼働したはずなので、
jsonファイルの状態で一度試してみられてはいかがでしょう?(できれば再度書き出したほうが良いです)
2016/05/03 05:16
>多分それでnew THREE.JSONLoader()が失敗しているのだと思います。
そうでしたか。
.jsにしているコードを載せているサイトもあったので、よいのかと思っていました。
IIS側の問題点がないか確認したところ
https://www.ipentec.com/document/document.aspx?page=visualstudio-json-file-invalid-access
を見つけたので適用したところ、
拡張子を.jsonにしてもコールバックが呼び出しされるようになりました。
ただ、function (geo,materials){}でmaterialsは取得されずundifined。
geoは取得されているようです。geo.faceVertexUvsに値が入っていました。
jsonファイルに記述のある座標データと同一のようです。
あらためてエラーを見てみたところ
IE11では、
THREE.WebGLRenderer: OES_texture_half_float extension not supported.
THREE.WebGLRenderer: OES_texture_half_float_linear extension not supported.
Chromeでは
THREE.WebGLRenderer 76
cg.js:179 Uncaught TypeError: Failed to execute 'requestAnimationFrame' on 'Window': The callback provided as parameter 1 is not a function.
http://localhost:53909/favicon.ico Failed to load resource: the server responded with a status of 404 (Not Found)
firefoxだと
TypeError: Argument 1 of Window.requestAnimationFrame is not an object.
となっていました。
表示状況は、fireFox・chromeともに、読みだしたモデルだけ表示されず、
別で作った立方体だけ表示されました。
FireFoxでローカルファイルで稼働させたところ、
canvasで指定したエリアが黒抜きになってしましました。
エラーと状況から推察可能ならよいのですが・・・。
別のサーバ、開発環境でも試してみたいと思いますが、
推奨できるものってありますか?
2016/05/03 16:51
昔はthree.jsのblender exporterがjs書き出しでした。(r50くらいの頃だったかと記憶しています)
いつ頃かはちょっと知らないのですが、json書き出しに変わりました。
多分ご覧になったのは数年前の記事などではないかなと思います。
…ちょっと思ったのですが
materialsの確認にconsole.logを使っていない感じでしょうか?
もし、使っていないのであれば、
loader.load('model.js', function (geo,materials) {
のすぐ後に
console.log(materials);
を追加して開発ツールのコンソールを確認してみてください。
materialsがArray [ Object ]で返っているんじゃないかと推測します。
(※もし、console.logの結果でもundifindなのであればエクスポートしたデータそのものに問題があります。)
Array [ Object ]で返ってきている場合
モデルにモーフやアニメーションなど加えていませんか?
複雑なモデルを描画する際は処理の仕方が変わります。(こちらだともうちょっとモデルデータそのものの情報など色々情報開示いただかないと何とも…になります)
一旦ここをチェックしてみていただいて良いですか?
一応こちらでもr76をダウンロードしてjsonモデル読み込みを検証してみましたが、
ローカルファイルのままfirefoxでちゃんと表示できています。
> 別のサーバ、開発環境でも試してみたいと思いますが、
> 推奨できるものってありますか?
一般的なサーバーというとLinax系のものがそうですね。
レンタルサーバー等を特に借りていなければ、VirtualBox等にCentOSなどをインストールしてローカルに開発環境を作成するのがおすすめではありますが、結構時間がかかるので、お時間のある時に…という感じでしょうか。(Vagrantなどを使うと簡単にローカル開発環境を作成できるのですが、WindowsでVagrantを使う場合、前準備が色々必要なようです)
現時点、three.jsのデバッグだけとりあえず、ということであれば
firefoxを使うのが、特に何も準備せずすぐに開発を進められるので良いのではないかなと思います。
普段IEを使い慣れてらっしゃると、最初はちょっと違和感を感じたりするかもしれませんが、デバッグするにはIEよりfirefoxのほうがずっと細かくできるので、一旦IEは最終的にIEのみのバグがないか、の確認くらいにしておくのがいいかなと個人的には思います。(IEの開発者ツールがちょっと貧弱+IEは特有のバグが多いので…)
2016/05/04 01:20
そういった経緯があったのですね、
古い記事だったかもしれません・・・。
function (geo, materials) {
console.log(geo);
console.log(materials);
・・・・
として追加してみました。
farefoxのf12開発者ツールを確認したところ、
materialsは相変わらずundifinedでしたが、
geoはObject { uuid: "2C3C00C1-EFDF-4465-AE4F-00DD766B7EB7", name: "", type: "Geometry", vertices: Array[8], colors: Array[0], faces: Array[12], faceVertexUvs: Array[1], morphTargets: Array[0], morphNormals: Array[0], skinWeights: Array[0], 他 13 個... }
と記述がありましたので、Objectで返されているように思います。
モデルデータにアニメーションなどは加えていないはずです。
brenderの操作に不慣れなので、確信は持てません。
jsonファイルの中身ですが、以下の通りです。
{
"uvs":[],
"vertices":[1.77745,-1.97664,1.77745,1.77745,1.57826,1.77745,-1.77745,1.57826,1.77745,-1.77745,-1.97664,1.77745,1.77745,-1.97664,-1.77745,1.77745,1.57826,-1.77745,-1.77745,1.57826,-1.77745,-1.77745,-1.97664,-1.77745],
"faces":[33,0,1,2,3,0,0,0,0,33,4,7,6,5,1,1,1,1,33,0,4,5,1,2,2,2,2,33,1,5,6,2,3,3,3,3,33,2,6,7,3,4,4,4,4,33,4,0,3,7,5,5,5,5],
"metadata":{
"uvs":0,
"vertices":8,
"version":3,
"type":"Geometry",
"generator":"io_three",
"normals":6,
"faces":6
},
"normals":[-0,0,1,0,-0,-1,1,0,-0,-0,1,0,-1,-0,0,0,-1,-0],
"name":"CubeGeometry"
}
形状は立方体です。
>一応こちらでもr76をダウンロードしてjsonモデル読み込みを検証してみましたが、
>ローカルファイルのままfirefoxでちゃんと表示できています。
私も現状のコードのままr73で確認したところ読み込み失敗していましたので、
私の側での問題であることを再認識しました・・・。
>現時点、three.jsのデバッグだけとりあえず、ということであれば
>firefoxを使うのが、特に何も準備せずすぐに開発を進められるので良いのではないかな>と思います。
将来はレンタルサーバなどにアップして公開してゆきたいと思っていますが、
現状はfirefoxで作業していきたいと思います。
2016/05/04 04:08
逆にすごくシンプルなデータだったということですね。
デフォルト(?)の立方体か何かかと思いますが
データを見ての通り"materials"のkeyがありません。
この場合は当然materialsを引数に指定してもundifindが返ります。
なので、最初にご提示されていたコードの引数を削るだけで表示されるはずです。
var loader = new THREE.JSONLoader();
loader.load('model.json', function (geo) { //materialsを省く
model = new THREE.Mesh(geo); //同様にmaterialsを省く
model.position.set(0, 0, 0);
model.scale.set(10, 10, 10);
scene.add(model);
}
);
このような感じです。
もう少し複雑な構造のモデルを作成されると書き出したデータに"materials"を含む色々なkeyが入るので、その際に引数materialsが必要になる、というところです。
モデルの作成やマテリアル、テクスチャなどについては
http://nvtrlab.jp/column/2-1
などをご覧になって色々試してみると良いかもしれません。
2016/05/04 12:16
大変お世話になえいました。ありがとうございます。
表示毎に読み込んだモデルの全体の色が変わってしまうのですが
model = new THREE.Mesh(geo,new THREE.MeshLambertMaterial({ color: 0xff0000 }));
とすることで単色を指定することもできました。
>モデルの作成やマテリアル、テクスチャなどについては
>http://nvtrlab.jp/column/2-1
>などをご覧になって色々試してみると良いかもしれません。
情報ありがとうございます。
勉強させていただきます。m(_ _)m
2016/05/04 15:08 編集
ちょっと回り道してしまいましたが、無事解決したようで何よりです。
久しぶりにthree.jsに触る機会にもなったので、こちらとしてもいい機会でした。
ありがとうございます。
> 表示毎に読み込んだモデルの全体の色が変わってしまう
データの作成の仕方によって色がちゃんと書き出したデータに反映されていないケースや
ライトの強さ、色によっても色味は変化します。
データの作成についてはBlender関係の記事や書籍を参考にされると良いと思います。(このあたりについて自分はまだ趣味の域を出ないので、お教えできるレベルではないので…。)
ライトの強さや色に関して(光を受けるモデルの反射率や質感などにもよりますが)もBlenderの中で質感とライトの種類、位置、数等を色々変えながら見比べていくとイメージしやすいと思います。
THREE.Mesh()を使って色を再定義する、という方法も無しではないですが
基本として、json等で読み込むモデルは
・多数の頂点を持つ
・複数のパーツ構成
・パーツ毎に色、質感などが違う
・ボーンを持つ
など、通常のthree.jsの機能の中で作成するには非常に難しい複雑なモデル(Ex. 建物モデルや人物モデルなど)を使いたい際に使用するものです。
なので、上記の方法はあまり使わないかな…と個人的には思います。
今回はたまたま「試しに」だったのだと思いますが
基本図形をsceneに追加したいのであれば、デフォルトで用意されている
ジオメトリプリセットを利用するほうが、簡単かつ色々できます。
wikiなどもご覧になってみると良いかもしれません。
http://www56.atwiki.jp/threejs/pages/1.html
また、最初のほうでお話ししていたような方法は
●Blenderとthree.jsを使って行うモーフィングアニメーション
http://www.knockknock.jp/archives/562
あたりで確認されてみると良いかなと思います。
解決されたようであれば、質問を「解決済み」にしておいてください。
2016/05/04 21:47
面ごとに別の色を振ったモデルを読み込むところから勉強をしてみたいと思います。