ニコニ立体ちゃん(アリシア・ソリッド)をQt3Dで表示する


ニコニ立体ちゃん(アリシア・ソリッド)

今回Qt3Dの学習をするのに使う3Dモデルを探していたところ、とても良さそうなモデルを発見しました。

ニコニ立体ちゃん特設サイト - ニコニ立体

映像作品や自作ゲーム、技術デモ、同人活動などの様々なシチュエーションにおいて表記不要で無料で使える3Dモデル「アリシア・ソリッド」を公開します。

使用は無料で、2次加工なども認めている、かなり利用しやすいライセンスです。

3Dモデルの配布形式は以下の3種類あります。

今回はこの中のFBXを利用します。 MMDはアドオンを追加することでBlenderでも利用できますが、オブジェクト名に日本語が含まれる等今後の利用にマイナスな点があるため今回は利用しません。 Unity PackageはUnity専用のためこれも利用はしません。

Qt3Dで読み込む(FBX編)

まずは以下の感じでfbxを読み込んでみました。

Entity {
    components: [
        SceneLoader {
                source: "/FBX/Alicia_solid_MMD.FBX"
             },
        Transform {
            translation: Qt.vector3d(0, 0, 0)
        }
    ]
}

結果、画面には何も表示されず、fbxは読み込めないようです。 (よく調べると時間がかかりすぎているだけで読み込みは行われていました。ただしダウンロードした素のfbxではテクスチャ読み込みでエラーが発生し結局表示はされませんでした)

Blenderで読み込む

次にQt3Dでそのまま読み込むのが無理ならいったん加工しようとBlenderで読み込んでみました。

すると、、、

ASCII FBX files are not supported.

うーん、FBXにも種類があるのでしょうか?

調べるとFBXにはASCIIタイプとバイナリタイプがあるということ。 (今までそんな事は気にしたことがなかったです)

FBXの変換

BlenderでFBXを読みたいので、調べるとAutoDeskがFBXのコンバーターを公開していました。 またASCII→バイナリの形式変換だけでなく、テクスチャなどのリソースファイルも外部か埋め込みか選べるようです。

FBX Converter Archives | Autodesk Developer Network

/images/2018/09/16/214810/20180916213037.jpg

使い方は対象のファイルを追加してFBX Save ModeをBinaryにし、Convertを押すだけです。

Blenderで読み込む(2回目)

バイナリ形式にしたFBXをインポートすると、今度はエラーなく読み込みが完了しました。

/images/2018/09/16/214810/20180916213051.jpg

Qt3Dで読み込む形式にエクスポート

Qt3Dで個人的に以前に読み込み実績のあるobj形式でエクスポートしてみました。

するとやはりテクスチャの読み込みでエラーが出ている模様。 objファイルのテクスチャ情報はmtlファイルに書かれているらしいので、mtlの中身を見てみるとイメージファイルの参照が.tgaと.psdの2パターンありました。

Qtのドキュメント(http://doc.qt.io/qt-5/qtimageformats-index.html)を見ると、tgaファイルは対応しているらしいので、psdが読めてないのかなと想像し.psdを.tgaに置換しました。 (そもそもの解決にはなっていませんが.tgaと.psdは同じ数存在していたため、とりあえずの対策として)

その対応後にQtで実行すると

/images/2018/09/16/214810/20180916213105.jpg

表示されました!! でも全体的に表示が粗いのとおデコのあたりに何かあります。

もとのFBX(Binary)ファイルが6MBに対して、obj(テキスト)ファイルは2.7MBとかなり容量が小さくなっているので表示の粗さはしょうがないのかなと思います。 おデコのあたりは恐らくpsdファイルをtgaファイルに変更したせいなのでしょうか?

暫定の対策として、おでこのパーツをBlenderで消してからもう一度objファイルをエクスポートすると、一応おデコのなにかは消えました。

/images/2018/09/16/214810/20180916213118.jpg

QMLに3Dモデルを埋め込む

Blenderからobjファイルをエクスポートすることで Qt3Dで読み込む事はできましたが描画品質は下がってしまいました(恐らく頂点数が減った?)

またSceneLoaderを使ったモデルの読み込みは、アプリケーション起動後に動的に読み込むらしくモデルが表示されるまで少し時間がかかります。 (最初にテキスト形式のfbxが読み込まれていないと思ってしまったのはこのため)

そんな中、KDABさんが公開しているこんなページを見つけました。

こちらの記事に書かれているBlender Exporter Addonを使用するとモデルをバイナリで保存して解析の時間なく利用できるとあります。

早速試してみました。

Exporting 3D content for Qt 3D with Blender - KDAB

このリポジトリのファイルをコピーして、Blenderのaddonsディレクトリに貼り付け後、Blenderの設定からaddonを有効にするとqml書き出しが利用できるようになります。

/images/2018/09/16/214810/20180916213142.jpg

これを利用してエクスポートするとQtのプロジェクトファイル一式が書き出されました。

書き出されたプロジェクトを起動して表示してみると、

/images/2018/09/16/214810/20180916213451.jpg

先程のobj形式を読み込んだものよりも形状はキレイです。 Blender上で見るのとほとんど違いはわかりません。 またウィンドウが表示されてから、3Dモデルが表示されるまでの時間もほとんどありません。 バイナリ埋め込みの効果は高いようです。

しかし、ぱっと見で分かる通り色がついていません。 Blenderのqml書き出しスクリプト(中身はpython)を見てみると、テクスチャを使ったマテリアルの情報は書き出されていませんでした。

書き出されたプロジェクトの中でマテリアルの情報は、MaterialCollection.qmlに書かれていることがわかったので、ここに手動でテクスチャ(*.tga)を使ったマテリアルを再定義することにします。

元のマテリアル定義

readonly property Material wearPsd: PhongMaterial {
   ambient: Qt.rgba(0.2, 0.2, 0.2, 1.0)
   diffuse: Qt.rgba(1.0, 1.0, 1.0, 1.0)
   specular: Qt.rgba(1.0, 1.0, 1.0, 1.0)
}

変更後のマテリアル定義

readonly property Material wearPsd: NormalDiffuseSpecularMapMaterial  {
        ambient: "white"
        diffuse: TextureLoader { source: "matarial/Alicia_wear.tga"}
        normal: TextureLoader { source : "matarial/Alicia_wear.tga" }
        specular: TextureLoader { source: "matarial/Alicia_wear.tga" }
        shininess: 1.0
        textureScale: 1.0
}

変更前、変更後ともにプロパティの型はMaterialであるので、ここを変更すればあとは上手くいくことを期待しました。 どのマテリアルにどのテクスチャを割り当てるかはプロパティ名から推測できたので、そこまで手間ではありませんでした。

この変更を実施してから再度起動してみると、

/images/2018/09/16/214810/20180916213205.jpg

ちゃんと色が付きました!!

ただし、テクスチャの読み込みにTextureLoaderを使ってしまったため、イメージファイルの読み込みが動的に発生し起動後少しだけ待たされるようになりました。 これを解決するにはテクスチャも3Dモデルと同様バイナリ(RGB形式?)で埋め込む必要があると思います。

まとめ

まだ完璧ではなく、課題も残ってはいますがアリシアちゃんの3DモデルをQt3Dで使うことができました。

ただ今回はただ表示しただけなので動いてはいません。 FBX上にはボーンとそれを使ったモーションも定義されているため、次はQt3Dからモーションアニメーションできるのかってことも調査したいと思います。

最終的にアリシアちゃんの情報を埋め込んだプロジェクト一式は以下のリポジトリで公開しています。

おまけ

せっかくの3Dなので、とりあえず回転させてみました。

Qt 

See also