どうも星姫です。
今日はいつも以上に興味深い話なので、ぜひ楽しんでいってくださいね。
さて、DirectXなどの描画用ライブラリを使ってみるとモデルデータが欲しくなります。
その流れで、ここまでモデリングソフトを扱えるようになりました。
最初はそこいらのテキストに書いてある通り、Xファイルを使うことを考えていたのですが…
確か、XファイルってDirectX10からは、もう使われていないフォーマットなんですよね。
代わりに登場した「DXUT Mesh FIle Format」という形式がありますが、名前から予想出来る通り
DXUTをアプリケーションに組み込まなければ使えません。
えぇー、そんなゲームコーディングやだよ…プログラミングの経験が浅いのにいきなり数万行とか勘弁して…
というわけで!独自フォーマットを作って出力しようという考えに至った訳です。
自分だけのモデルデータフォーマットを考えるのって結構、いえかなり楽しいです。
今回のお話を読めば、誰でも Blender から独自フォーマットを出力できるようになる!
そんなレッスンを目指して頑張ってみようと思います。
以下の記事は Blender 2.49b のものなので、最新の Blender 2.55(2010/12現在)の情報は載ってません。
誰でも簡単に解析できるXML形式で Blender 2.55 からモデルデータを手に入れたい方はダウンロードへお越しください。
まずは実験!上図のようなもっとも簡単な図形データ(三角形にテクスチャを1枚貼り付けたモデル)を作成して、
とりあえずXファイル形式で出力してみましょう。
Blenderから他の形式でデータを出力するには、File→Exportとメニュー操作をします。
DirectX(.x)の項目を選んで、適当な名前でファイルを保存してください。
こちらは、DirectX(.x)の項目を選んだ直後の画面の様子です。とりあえずExport Allを押してみます。
以下は出力されたXファイルの中身です。
たったの三点で構成したモデルデータは、以下に示すような形式で保存されます。
xof 0303txt 0032 template VertexDuplicationIndices { <b8d65549-d7c9-4995-89cf-53a9a8b031e3> DWORD nIndices; DWORD nOriginalVertices; array DWORD indices[nIndices]; } template XSkinMeshHeader { <3cf169ce-ff7c-44ab-93c0-f78f62d172e2> WORD nMaxSkinWeightsPerVertex; WORD nMaxSkinWeightsPerFace; WORD nBones; } template SkinWeights { <6f0d123b-bad2-4167-a0d0-80224f25fabb> STRING transformNodeName; DWORD nWeights; array DWORD vertexIndices[nWeights]; array float weights[nWeights]; Matrix4x4 matrixOffset; } Frame RootFrame { FrameTransformMatrix { 1.000000,0.000000,0.000000,0.000000, 0.000000,1.000000,0.000000,0.000000, 0.000000,0.000000,-1.000000,0.000000, 0.000000,0.000000,0.000000,1.000000;; } Frame Plane { FrameTransformMatrix { 1.000000,0.000000,0.000000,0.000000, 0.000000,1.000000,0.000000,0.000000, 0.000000,0.000000,1.000000,0.000000, 0.000000,0.000000,0.000000,1.000000;; } Mesh { 3; 1.000000; 0.000000; 0.000000;, 0.000000; 1.000000; 0.000000;, 0.000000; 0.000000; 0.000000;; 1; 3; 0, 2, 1;; MeshMaterialList { 2;// 使用されるマテリアルの数 1;// 面の数。 1;;// 面 0 は 2 番目のマテリアルを使用する。 Material Material { 0.800000; 0.800000; 0.800000;1.0;; 0.500000; 1.000000; 1.000000; 1.000000;; 0.0; 0.0; 0.0;; } //End of Material Material Mat1 { 1.0; 1.0; 1.0; 1.0;; 1.0; 1.0; 1.0; 1.0;; 0.0; 0.0; 0.0;; TextureFilename { "023hot.jpg"; } } // End of Material } //End of MeshMaterialList MeshNormals { 3; 0.000000; 0.000000; 1.000000;, 0.000000; 0.000000; 1.000000;, 0.000000; 0.000000; 1.000000;; 1; 3; 0, 2, 1;; } //End of MeshNormals MeshTextureCoords { 3; 1.000000;-0.000000;, 0.000000;-1.000000;, 0.000000;-0.000000;; } //End of MeshTextureCoords } // End of the Mesh Plane } // SI End of the Object Plane } // End of the Root Frame
材質(Material)の部分の数字が、何なのか理解できなかったのでコメントを追加しました。参考にしてください。
Xファイルについて詳しい情報は以下のリンクで学べます。
一見 X ファイルの中身は三角形一つにしては書き過ぎなんじゃないかと思うけど
順を追って書いてあることを確認していくと、全部必要なデータに思えて来ます。
さて、もう少し複雑なモデルデータについてはどうでしょうか?
テクスチャを複数(3つくらい)使ってみたらどうなるか試してみましょう。
…って、Blender でマルチテクスチャの貼り方から調べないといけないのだけどね。
で、調べました。まずは以下の赤枠の部分を参考に Texture を Add New します。
追加されたテクスチャを選択すると、以下の図のようにタブが2つ追加されるので
まずは、Map Input のタブで、赤枠で示したように UV を選択します。
続いて、Map to タブで、赤枠で示したように Multiply を選択します。
さて、テクスチャを複数用意したので、それぞれのテクスチャの UV の座標を設定しなくちゃね。
これも調べました。下図の赤枠を参考に、テクスチャ座標を追加してください。
下図の赤枠のところを適当な名前にして、左側のグリッド絵のアイコンを選択すると
なんと UV Image Editor が連動して切り替わります。
UV Image Editor を開いて、一番上の UV 座標セットをポチッ
二番目の UV 座標セットをポチッ
三番目の UV 座標セットをポチッと、まぁこんな感じでそれぞれの UV 座標を決めてあげましょう。
ちょいと復習です。UV Image Editor での画像ファイルの読み込みは、以下の赤枠のところを押して行います。
一度開いたことがあるファイルだったら、右下の小さい赤枠を押せば選択できます。
えー、ではここで、Blender の不思議仕様の出番です、初心者はほぼ確実に惑わされます。(私は苦しみました…)
現在の状態で、F12キーを押すと Blender のレンダリングが行われますが
なんと結果にテクスチャが反映されません。勿論原因は Blender の不思議仕様です。
結果は下図のようになります。(Blenderのメイン機能のレンダリング結果)
先に解決策を示します。下図の赤枠を参考に、None と書かれている項目を Image に変更します。
下図は画像を選択した結果です。いつか説明しましたが Load ボタンを押す時は
Ctrl ボタンと一緒に押すと、サムネイルを確認しながらテクスチャを選べます。
画像ファイルを Load する時は Ctrl キーを一緒に押すと直感的に選べて便利です。
Blender の不思議仕様のトラップを切り抜けて、無事テクスチャを材質にセット出来たなら
レンダリング結果は下図の通りです。
さて、しっかりレンダリング結果からもマルチテクスチャマッピング
(ポリゴンに複数のテクスチャとテクスチャ座標をセットすること)
を確認したところで、お待ちかね X ファイル形式での出力を行ってみましょう!
Blenderで三角ポリゴンに複数のテクスチャを設定した後、エクスポートした X ファイル形式のデータ
xof 0303txt 0032 template VertexDuplicationIndices { <b8d65549-d7c9-4995-89cf-53a9a8b031e3> DWORD nIndices; DWORD nOriginalVertices; array DWORD indices[nIndices]; } template XSkinMeshHeader { <3cf169ce-ff7c-44ab-93c0-f78f62d172e2> WORD nMaxSkinWeightsPerVertex; WORD nMaxSkinWeightsPerFace; WORD nBones; } template SkinWeights { <6f0d123b-bad2-4167-a0d0-80224f25fabb> STRING transformNodeName; DWORD nWeights; array DWORD vertexIndices[nWeights]; array float weights[nWeights]; Matrix4x4 matrixOffset; } Frame RootFrame { FrameTransformMatrix { 1.000000,0.000000,0.000000,0.000000, 0.000000,-0.000000,1.000000,0.000000, 0.000000,1.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,1.000000;; } Frame Plane { FrameTransformMatrix { 1.000000,0.000000,0.000000,0.000000, 0.000000,1.000000,0.000000,0.000000, 0.000000,0.000000,1.000000,0.000000, 0.000000,0.000000,0.000000,1.000000;; } Mesh { 3; 1.000000; 0.000000; 0.000000;, 0.000000; 1.000000; 0.000000;, 0.000000; 0.000000; 0.000000;; 1; 3; 0, 2, 1;; MeshMaterialList { 2; 1; 1;; Material Grey { 0.800000; 0.800000; 0.800000;1.0;; 0.500000; 1.000000; 1.000000; 1.000000;; 0.0; 0.0; 0.0;; } //End of Material Material Mat1 { // @hoshi-hime はぁ?なんだこのマテリアルは? 1.0; 1.0; 1.0; 1.0;; 1.0; 1.0; 1.0; 1.0;; 0.0; 0.0; 0.0;; TextureFilename { "023hot.jpg"; } // @hoshi-hime オイオイ!マルチテクスチャでしょ?ファイル名一個だけ? } // End of Material } //End of MeshMaterialList MeshNormals { 3; 0.000000; 0.000000; 1.000000;, 0.000000; 0.000000; 1.000000;, 0.000000; 0.000000; 1.000000;; 1; 3; 0, 2, 1;; } //End of MeshNormals MeshTextureCoords { // @hoshi-hime オーイ!設定した3つのUV座標はどこに保存されるのさ! 3; 1.010280;-0.002287;, 0.010279;-1.002287;, 0.010279;-0.002287;; } //End of MeshTextureCoords } // End of the Mesh Plane } // SI End of the Object Plane } // End of the Root Frame
すごく気になるところにコメントを打ってみました。たいへん残念な結果になり、ちょっと落ち込みました。
結果から言えることは、備え付けのXファイル形式でのエクスポーターはマルチテクスチャをサポートしていないということ。
Xファイルを解析して、独自形式のフォーマットに書きかえるなんてことが、まず出来ないということが明らかになりました。
ふぅ、では Python を勉強して自分専用の Exporter を実装しましょうか…面倒だな。でも頑張ろう。
では「次回」の「次回」に続きをやらせていただきます。
次回はちょっとシンプルスター先生のイラストの描き方なんかを勝手に割り込ませちゃう予定なので、申し訳ない。
では、次回の次回をお楽しみに!
blenderからの出力の記事見ました。
そういえば、プラグインという手もあったのですね・・・今は一旦fbxに落としてからfbxsdkで読んでるのですが、
いろいろ面倒なんで、こっちの方法のほうが良さそう。(ちなみに、UVが取れない問題は解決済みですか?) by 通りすがり
Blender は公開しているインタフェースをコロコロ変えるので、独自にプラグインを開発するのは、かなりのコストが見込まれます。
メンテナンス担当に随時対応を依頼できるような、そういった組織で活動する場合は
プラグインもありですが、休日しか使えない個人開発の場合
そういったメンテナンスに時間を割くことは、モチベーションの低下を招きます。
いずれ中間ファイルフォーマットの主流は fbx になると予想できます。(もう主流といって良いと思います。)
今後、モデル情報だけでなく、アニメーション、物理、モディファイア、といった情報を利用することを考えると
fbx から変換する仕組みを用意しておいた方が後々助かることが多いと思います。
UVが取れない問題は解決済みです。
UV をモデルに追加する、マテリアルにテクスチャをUV使用で追加する、UVImageEditor でUV編集すると間違いなくUVが出力されます。
現在は collada から変換する機構を用意しており、Blender から直接マルチテクスチャ座標の出力は不可能ですが
該当する collada タグを複数、手動で埋め込めば変換機構がマルチテクスチャとして読み込むようになっています。
2010/06/27 初記。
2010/07/11 追加。
2014/10/26 更新。