‘three.js’ タグのついている投稿

1 2 3 4 5 6 7

three.jsで遊んでみる(4)

 プログラム,
 公開日:2012年9月20日 / 更新日:2013年10月24日

前回で書いたように、
MMDなデータをBlender経由でthree.jsで扱えるjsonへ変換するのは
どうもうまく行かない感じです。

そこで自前で変換ツールを作ることにしました。
Blenderのimporterやexporterは参考になるので、
pythonで作ってみることにしました。
ちなみにpython使うのは初めてだったりします(^_^;)

BoneによるSkeletalなアニメーションは、
こんな感じにthree.jsで動いているので
どうやってるのかを調べることから始めました。

データファイルはthree.jsで扱いやすいようなjsonになっており、
テキストエディタなどで中身を見ることができます。
内容は以下の様な感じ。

1)マテリアルの配列
2)頂点の配列(x,y,z,x,y,z,…)
3)法線の配列(x,y,z,x,y,z,…)
4)UVの配列(u,v,u,v,…)
5)面データの配列
6)Bone情報の配列
7)頂点に対するBoneインデクスの配列
8)頂点に対するBone重みの配列
9)アニメーション情報(Bone毎のキーフレームの配列)

面データは、まずフラグ値があり、
それによって続く値が決まるようになっています。
詳しくは”JSONLoader.js”を参照してみてください。
7)と8)は常に2個セットで扱われるようになっています。
つまり,一つの頂点に対するBoneは2個までとなっています。
例えば、ある頂点に影響するBoneが#2,#7だったとすると、
インデクス=[2,7] 重み=[0.25,0.75]とかになります。
重みの合計は基本的に1.0になります。
頂点に影響するBoneが一つだけの場合は、
インデクス=[3,0] 重み=[1,0]とかになり、
2つ目の値はゼロになるようになっています。
これだと重みゼロで積和することになるので
無駄な計算となるはずですが、
シェーダーで扱いやすいように、この構成なのだと思います。
アニメのキーは位置、回転(クオータニオン)、拡縮の3要素から成っており、
変化のある要素のみが記述されるようになっています。

ということで、どういうjsonを作れば良いか大体わかったので、
MMDなデータファイルから変換する作業へ進みます。

MMDなモデルファイルであるPMDの仕様は公式には公開されていないようですが
ググってみると解析された結果が見つかります。
ところでモデルファイルにはもう一つPMXというのがあります。
PmxEditorに同梱されているファイルに詳しい仕様が記述されています。
さいわいPMDはPMXへ変換することが出来ますので、
変換ツールではPMXファイルを扱うことにしました。
モーションファイルであるVMDの仕様も非公開のようですが、
解析情報は検索したら見つかりました。

さて、
そんなこんなで紆余曲折を経て、
ある一定の成果を得ることが出来ました。
変換時の留意点をまとめてみます。

  • PMXにおけるBoneの位置はルートからの積算になっているので、
    three.jsで扱うには親からの相対値へ変換する必要がある。
  • 左手座標系から右手系への変換が必要。
    位置や法線はZ値の符号を反転させるだけ。
    回転(クオータニオン)の場合はXとYを反転させるとうまくいく感じ。
    あるいはZとWを反転でもいいっぽい。
    面の頂点並びはA->B->CからC->B->Aに反転。
  • PMXにおける Bone Deformation は BDEF1(ボーン1つ)、BDEF2(ボーン2つ)、BDEF4(ボーン4つ)、SDEF(ボーン2つでspherical)の4種類がサポートされているが、three.jsで扱えるように全てBDEF2相当に変換する。ただ、PMDにはBDEF1かBDEF2しかないはず。
  • VMDのBoneキーフレームのposには、
    相対化したPMXでのBoneの位置を加算する必要がある。
  • three.jsにおけるアニメのキーは最低2つ必要で、
    なおかつ最初と最後にはpos(位置),rot(回転),scl(拡縮)が揃って無いとダメ。
  • Boneキーの補間はMMDでは4つの制御点による3次ベジェですが、現状のthree.jsではリニア補間しかない。ただ、4つのキーを使ったCutmull-Romな補間をサポートしている。

あと、
「頭」と「首」のBoneはそれぞれ個別に回転できるわけですが、
実際に再生させると「傾き過ぎる」ような感じになるので、
「頭」の回転量は強制的にゼロにして変換するようにしました。
なぜこういう現象になるのかよくわからないのですが、
とりあえず暫定処置としておきます。

ということで、
表情モーフ無し、IK無し、物理演算無し、toonシェード無し、エッジ処理無し、
Boneによるskeletalなアニメーションだけな再現なので
特に足のIKが無くて変なことになってますが、
とりあえずthree.jsで再現したミックミクな感じのモーションはこれです。
諸般の事情でちょっとローディングに時間がかかりますが、
しばらく待ってみてください。なお、ChromeなどのWebGL対応のブラウザで見てください。PCパワーもそれなりに必要となるかもしれません。

あと、何か変な線が見えてますが、
これはスポットライトの範囲を可視化したものです。

一応、影も出せるようになったのですが、
現状のthree.jsではマテリアル単位で影の濃さを調整できないので、
床影のみにしています。
ライト毎にしか影の濃さを調整できないので、
床影が認識できるような濃さにした上でミクさんにセルフ影を導入すると、
なんか「やり過ぎな影」になっちゃうんです(^_^;)

次は表情モーフあたりをやってみたいかな。

mytest7


※9月28日追記。
「傾き過ぎる」件ですが、変換ツールがバグっていたようです(^_^;)
隣接するキーの内容に同じのがあったら、
端折るようにして最適化したつもりがうまくいってなかったようです。
VMDのキーを素直に出力するようにしました。

three.jsで遊んでみる(3)

 プログラム,
 公開日:2012年9月4日 / 更新日:2013年9月13日

前回
MMDなミクさんを表示することが出来ましたが、
踊らせることは未だできていません。
ただ、いろいろ分かって来たこともあるので
メモっておきたいと思います。

まず、
PMD+VMDをCollada(DAE)に変換できるツールがあることが分かりました。
それはこちらのMMDfromColladaです。
で、Three.jsで再現すべく色々やってみたのですが、
うまく行ってません。
ColladaLoaderはDAEのGeometryとMaterial情報から
SkinnedMeshを作ってくれるのですが、
そのSkinnedMeshにはBone情報が設定されてなく、
各頂点がどのBoneから影響受けるのか、
及びその影響度(重み)情報も設定されていないようです。
ColladaLoader.jsを見てみると、

というようにコメントアウトされている関数があるのを見つけました。
現状では自前でこれをどうにかしないといけない感じです。
当然Animation情報もThree.jsで扱えるようにしないといけないわけですね。
ということで保留・・・(^_^;)

ときに、
Three.jsはリビジョンが50に上がったようです。
んで、こんなのを見つけました。
BoneというかSkeletonアニメが良い感じに動いています。
ShadowMapな影もどうやってるのか参考になりそうですね。
これをミクさんでやりたいのです。
中身を覗いてみたところ、データはjson形式になっており、
“Blender 2.63 Exporter” というテキストを見つけました。
調べた所、BlenderというオープンソースなCGソフト向けの
jsonエクスポータをThree.js側で用意していることが分かりました。
さらに、こここことかここ
PMDやVMDのインポータやエクスポータがあることも発見しました。
Blenderに読み込ませてThree.jsなjsonで書き出せば
バッチリ行けるんぢゃないのか!?

ということで、
意気揚々でやってみたところ、
Blender上で踊ってくれるようになりました。
おお!
んじゃ、あとはThree.jsなjsonで出力すれば!!
Three.jsで再現できるはず!?

・・・残念ながらうまく行ってません。
正確にはモーションさせることは出来たのですが、
結果がわけわかめなことになってます・・・。
なんかもう不気味な踊りになってしまっています(^_^;)

ん~・・・
現状の自分のスキルでは埒が明きそうにないので、
まずはThree.jsの中身を解析して、
より理解を深める所から始めた方がよさそうです(^_^;)

ちなみに、
ちょっと分かったコトは、Blenderを経由すると
MaterialのAmbientやDiffuseの値がおかしくなっている感じです。
少なくともPmdEditorのエクスポータを利用して出力した
DAEの内容と一致していません。
どうやらBlenderの内部のMaterialでは、
Ambientは色(RGBA)としては保持してなくて、
明るさ的な情報だけしか保持していないっぽいようです。
Diffuseが一致してくれないのはイマイチよくわかりませんでした。
なんにしてもBlenderでPMDやPMDから直接変換されたDAEを読み込むと、
一部の情報がうまく再現できなくなってしまう感じです。

three.jsで遊んでみる(2)

 プログラム,
 公開日:2012年8月29日 / 更新日:2014年8月27日

three.js の examples を眺めた結果、
どんな機能があって、どう書けば良いのか、
大体の要領がつかめて来た感じです。

そこで、
MMDなミクさんを表示してみることにしました。
同梱されているモデルファイル(PMD)を利用します。

ただ、
PMDまたはPMXなファイルを読み込むローダが
three.jsには無いので、
PmdEditorまたはPmxEditorColladaエクスポータを利用して
Collada(DAE)形式にいったん変換します。

あとは、
sceneを作って、
適当にcameraとlightを追加。
さらに、
ColladaLoaderで読み込んだDAEを追加。
WebGLRendererを作ってsceneとcameraを渡す。
基本的にはこれだけ。
あっさり表示できてしまいました(^_^;)

実際には、
モデルのスケールの調整とか、
地面のグリッドとか、
FPS表示のためのStatsや
カメラ操作のためのTrackballControlsなどを
導入していますが、
ちょっとの手間で簡単に出来ました。

ちなみに、
ミクさんは細かい所までよく出来ているので、
全体にテクスチャを貼ってるのかと思ってましたが、
実際に貼ってあるのは眼だけで、
基本的に単色ポリゴンで構成されてるのが意外でした。

ということで、
three.jsで表示させてみたWebGLなミクさんはこちらです。
マウスでグリグリ動かせます。
※WebGL対応のブラウザで見てください。Chromeが良いと思います。

mytest3

なお、
残念ながら現状では踊ったりしません(^_^;)
モーションファイルであるVMDを変換して導入する術が
現状ではみつかりませんでした。
ただ、PMDから変換されたDAEを見てみると、
ボーンっぽい情報が含まれているようなので、
VMDからフレーム情報を抽出して適用できれば、
もしかしたら動くようにできるかもしれない
というか、したいなぁ(^_^;)

参考までにソースは以下の通りです。(three.js r49)

three.jsで遊んでみる

 プログラム
 公開日:2012年8月22日 / 更新日:2012年12月10日

enchant.jsにはWebGLなプラグインがあるので、
3Dにも手を出してみようかと思ってWebGL関連でググッたりしてたら、
three.jsというものを見つけました。

three.jsはJavaScriptな3Dライブラリなのですが、
かなり良さげな感じ。
ざっとソースを眺めただけですが、
なんかお手軽にやれそうです。

レンダラとしてWebGLだけでなくHTML5のcanvasとかに対応していたり、
物理演算なライブラリとの連携も出来たりするのも魅力。

サンプルソースが豊富に付いてて、これを見てるだけでもなんか楽しい。
個人的にはアスキーアートなやつとか、kinectなやつ、
あと物理演算なジェンガのサンプルとか、
こんなことまで出来るのね、な感動。
チップセット内蔵のHD4000なグラフィックでサクサク動いてますので、
大抵のデスクトップや外付けGPUなノートPCとかなら
十分に動くんじゃないかと思います。

ちなみに、three.js一式をダウンロードして
examplesフォルダのhtmlを直接実行しようとすると、
XMLHttpRequestによるロードでは Cross origin なエラーとなってしまうので、
例えばxamppなどを利用してローカルなWebサーバーを立てて、
localhost経由で実行するとうまく行くようになります。
ただし、基本的にローカルにテストするだけなのであれば、
念のためリモートからアクセスされないように
ここを参考にアクセス制限をかけておいた方がよいと思います。

ということで、
three.jsをいろいろ弄ってみる予定でいます。
GLSLなシェーダーにも挑戦してみたい。
あと物理演算も試してみたいです。

1 2 3 4 5 6 7