このシリーズの書き込みは久しぶりだったりします。
先日、
とあるPMXなファイルを読もうとしたら、
うまく動かなかったので今回対処してみた次第です。
以前にも書いたりしましたが、
PMXの読み込みに対応してはいるものの、
PMDの代わりっぽく扱っていたりしました。
実際、今までテストで使っていたPMXはPMDから変換したものです。
そんなわけでピュアにPMXなファイルを読み込んでみると、
いろいろ不具合が発覚したりしました(^_^;)
ときに、
PMXではPMDよりテクスチャを多用しているのが多い気がしました。
sphereマップを使って光源処理による陰影感を抑えるようにしてたりとか、
いろいろ工夫があって面白いですね。
ファイルサイズが10MBを超えるようなものもあったりしました。
某MMDなアニメで配布されているのを試してみたのですが、
WebGLではメモリ食い過ぎるようで厳しい感じです(^_^;)
ということで、
修正&改善した所は以下の通りです。
- データ要素を参照する際のindexサイズの扱いが不十分でした。頂点だけ扱いが特別なのですが、やり方がおかしかったのを修正しました。
- BDEF2などのボーン変形による頂点blendingにおいて、ボーンの参照インデクスが-1、つまりボーン指定無しの場合は安全のためにインデクスはゼロに変えました。当然、対応する「重み」はゼロになります。
- 同名のテクスチャファイルを複数読む場合は、共有して使いまわせるようにしました。
- toonテクスチャの参照インデクスが-1、つまりtoon無しに対応しました。PMX仕様には明記されていないのですが、こういうのが認められているようです。素直にシェーディング処理だけをやれば良いのかと思ったのですが、MMD的には光源処理を無効にする指定になるようですので、そのように対処しました。
- sphereモードは乗算に加えて加算にも対応しました。
- sphereありの指定(乗算や加算モード)なのに、sphereテクスチャの参照インデクスが-1、つまりsphere無しという矛盾する場合があるようです。これはsphere無しとしました。どうやら編集でこういうのが作れてしまうようです。
- PNGをテクスチャとして使う場合は常に「透過」扱いにするようにしました。そのため多少効率が悪くなるかもしれません。本来なら透過成分があるかどうか判定したいところですが、JavaScriptの場合はかなり煩雑なのでやっていません。いったんcanvasに描画して、ピクセルのアルファ成分を1つずつ調べて行く方法しかなさそうなので。もっと簡単に判定できる方法があればよいのですが。別途phpとかでヘッダ参照して調べるほうが早いかも。ちなみに、不透過の場合は手前から奥、透過の場合は奥から手前に描画しないと期待したような結果にならないのです。three.jsはこれを自動でやってくれてます。
- あらかじめ全てのモーフターゲットを生成していたのを、必要な分だけ生成するように変えました。メモリ使用量が減ってくれるはず。
これらの対処によって、数MB程度までのPMXファイルならば
とりあえず動作してくれるようになると思います。
実は、変な描画になってしまうPMXが一部あったりするのですが、
原因はよくわかってません。
テストではこちらのデータを拝借しました。
ちびミクさんはなんとも愛らしくて良いですね。
影の有無とか輪郭線の太さを調整できるようにもしてみました。
ということで参照するにはこちらからどうぞ。
ローディングにちょっと時間かかるかも。
なんか最近やたらとサーバーが重いことがあります・・・。
激しく気長に待ってみてください(^_^;)
ChromeなどのWebGL対応のブラウザで見てください。PCパワーもそれなりに必要となるかもしれません。反応がない場合は、リロードして再度試してみてください。
なお、
現状で対応できていない所があります。
以下に列挙しておきます。
- BDEF4
- SDEF
- 回転・移動付与による変形
- 頂点毎の輪郭線スケール
いずれ、どうにかしたいですね(^_^;)