Shade3Dでモデリングした形状をリアルタイム環境に渡すときの最適化

  • 形状をリアルタイム向けに最適化
  • fbxでエクスポート


Shade3Dでモデリングした形状をリアルタイム環境用に最適化します。
ここでのリアルタイムとは、Unityなどのリアルタイムエンジン、ARやVRなどのリアルタイム表示が必要な環境を指しています。

リアルタイム環境に渡す手順は「Unityに形状を渡す」でも説明していますが、
改めての解説とShade3D ver.20で追加されたPBRマテリアルも含めるようにします。

なお、チュートリアルの「キッチンを作る」で作成したキッチンシーンをリアルタイム環境に渡すものとします。
今回は、各種アセットを例として最適化のためのチェック事項を洗い出していきます。
なお、形状をエクスポートするときのファイルフォーマットはfbxを使用します。

Shade3Dで表現できる形状の種類

Shade3Dでは大きく以下の形状の種類があります(光源やカメラなどを除きます)。

  • 線形状 (開いた線形状/閉じた線形状)
  • 自由曲面
  • 掃引体/回転体
  • ポリゴンメッシュ
  • NURBS (Professional版のみ)
  • その他 (円など)

リアルタイム環境で表現できるのは「ポリゴンメッシュ」のみになります。
ポリゴンメッシュ以外の形状は、あらかじめShade3D上でポリゴンメッシュに変換しておくか、
各種エクスポータでエクスポート時にポリゴンメッシュに変換されるため、それに頼ることになります。

また、リアルタイム用途の場合、インポート時に多角形が三角形に分割されることが多いです。
最終的なGPUでのリアルタイム表現ではすべて三角形に変換されます。

チェック事項

  • 原点位置を確認
  • 寸法を確認
  • 面の表と裏を確認
  • 面積が存在しない場合や重複頂点など、不要な頂点/面を削除
  • ポリゴンメッシュの面数が多くならないようにする
  • 形状に割り当てるマテリアルは「マスターマテリアル(マスターサーフェス)」にする
  • できるだけ少ないマテリアル数/形状数になるようにする
  • 日本語の形状名やマテリアル名、テクスチャ名
  • パートの変換行列を確認

これらをキッチンシーンで使った建物やアセットを例に出して確認していきます。

鍋をリアルタイム向けに最適化

鍋のアセットである「鍋(大).shd」をリアルタイム向けに最適化します。

原点位置を確認

まず、形状の中心が原点(0, 0, 0)になっているのを確認します。
この場合は、鍋の底の中心を原点としています。
これにより、他ツールに渡したときにこの位置が中心になります。

寸法を確認

寸法の確認は、ブラウザですべての形状を囲むパートを選択し(単一の形状の場合はその形状を選択しても同じ結果になります)、
形状情報ウィンドウの「サイズ」を確認します。

この場合は、379.44 x 154.55 x 205.11 mmとなります。
この寸法が現実の形状と同じサイズになっているのを確認します。

面の表と裏を確認

透視図の右上のナビゲーションツールのメニューより、「表示オプション」で「両面(裏面カラー)」が選択されているのを確認します。

面の裏返りがある場合、透視図では以下のように薄紫色になります。

この場合は、鍋のフタの取っ手が面反転していることになります。

面を反転する方法は2つあります。
もっとも簡単な方法は、ブラウザの右上または右下の白い三角をクリックしオプションを表示、
面反転」をクリックします。

ポリゴンメッシュの場合は、形状編集モード+面選択モードですべての面を選択し、
ツールボックスの「編集」-「メッシュ」-「編集」-「法線」-「反転」を選択することで面を反転できます。

パートの変換行列のスケールにマイナスを入れて面反転させる方法もありますが、
これは形状のエクスポートとの相性がよくないためお勧めできません。
他ツールでは、変換要素のスケールにマイナスを入れることを許可していない場合もあります。

自由曲面や回転体の分割レベルを確認

ポリゴンメッシュの面数が多くならないようにするための確認を行います。
この鍋の形状は、自由曲面と回転体を多用しています。
これはエクスポート時にポリゴンメッシュ変換されるため、そのままでも問題ありません。
ただし、ポリゴンメッシュに変換されるときの分割レベルが大きくならないように注意する必要があります。
メインメニューの「ファイル」-「エクスポート」-「FBX」でfbx形式でエクスポートします。
エクスポートダイアログボックスの「曲面の分割」でエクスポート時に、
自由曲面や回転体/掃引体などの分割レベルを調整します。

自由曲面や回転体/掃引体のポリゴンメッシュ変換がどのように行われたかの確認は、
一度fbx形式でエクスポートしてからShade3D上で新規シーンを作成し、
fbxとしてインポートするのが早いです。
fbxエクスポート時に「曲面の分割」を「普通」として出力し、新規シーンにインポートすると以下のようになりました。

ブラウザでポリゴンメッシュ形状だけ選択すると、10516面(三角形と四角形含む)となっています。
フタ部分の分割数が多いため、ここは最適化できそうです。

ブラウザで自由曲面や回転体/掃引体の形状名の先頭に「<」をつけると分割レベルを上げることになります。
これを使い、形状ごとの分割数を調整します。

fbxエクスポート時に「曲面の分割」を「普通」として出力し、新規シーンにインポートすると以下のようになりました。

ブラウザでポリゴンメッシュ形状だけ選択すると、7396面となりました。

さらに最適化したい場合は自由曲面や回転体/掃引体をポリゴンメッシュに変換してからエクスポートするようにします。
注意点として、一度ポリゴンメッシュに変換すると元に戻せないため、エクスポート用の別シーンとしてshdファイルを保存したほうがいいかもしれません。
ブラウザで対象形状を選択してツールパラメータの「ポリゴンメッシュに変換」ボタンを押し、
分割数を調整します。

「分割数(交差方向)」「分割数(選択方向)」の数値をそれぞれ調整して変換、やり直したい場合はUNDO(取り消し)、を繰り返すことになります。
ここで最低限の分割数を指定することで、形状と面数のバランスを調整します。

ブラウザでポリゴンメッシュ形状だけ選択すると、2532面となりました。
ポリゴンメッシュに変換後は、リアルタイム表示で面同士の角をスムージングさせるため「限界角度」を上げておきます。
30から50に変更しました。

これで、面数の最適化作業が完了しました。

なぜ面数(ポリゴン数)を抑える必要があるかというと、このキッチンシーンを例として見た場合でも、
建物や数々のアセットを配置することになります。
このキッチンシーンでは43個のアセットがあります。
これらをすべて読み込んでリアルタイム環境で扱うことになります。
そのため、できるだけリソース(GPUで一括して格納される面情報やテクスチャ情報)を削減することが必須になります。
昨今はGPUの性能が上がっておりポリゴン数が多くても処理しきれますが、
スマートフォンやタブレットなどのモバイル環境(アプリのコンテンツでの使用、ARとしての使用)、スタンドアロンのVR環境などは、
まだふんだんにリソースを使うということはできません。
そのため、可能な限りリソースを削減するための最適化を行うことが必要となってきます。

マスターマテリアル(マスターサーフェス)の確認

このキッチンシーンは、すべての表面材質をマスターマテリアル(ver.19以前ではマスターサーフェス)で扱うようにしています。
そのため、マテリアルについてはマスターマテリアルの情報のみ他ツールにエクスポートしたときに調整すればいいことになります。
もし、Shade3D上で形状ごとに独立した表面材質が存在する場合は、マスターマテリアル化するようにしてください。
そうしないと、形状に割り当てられているマテリアル数が増えることになります。
リアルタイムでは、マテリアルの切り替え負荷は高いです。
形状数(ポリゴン数)とマテリアル数を抑えることが効率化の指針となります。
リアルタイムではGPU上の描画の際の1回の呼び出しを「Draw Call」と呼びます。
このときに頂点、ポリゴン情報やUV情報などをマテリアル別に一括して呼び出し描画します。
1フレーム分の描画は複数回の呼び出し(Draw Call)が行われることになります。
マテリアルが増えた場合、このDraw Callがマテリアル数分増えることになります。
Draw Callが増えると、描画速度が低下することになります。

鍋の形状の場合、2つのマスターマテリアルが割り当てられています。

同じマテリアルを持つポリゴンメッシュをまとめる

もし、同一マテリアルを参照するポリゴンメッシュの場合、限界角度が異なるなどの差がない場合は
1つのポリゴンメッシュに結合してしまうほうがリアルタイムには適する状態になります。
以下の画像の場合、鍋の本体と取っ手との接続部の合計3つのポリゴンメッシュは同じ金属のマテリアルのため、
ツールボックスの「編集」-「メッシュ」-「結合/削除」-「オブジェクトの結合」で1つにまとめます。

結合したポリゴンメッシュのフェイスグループは不要のため、形状情報ウィンドウでフェイスグループの指定は削除しておきます。

この段階で、4つのポリゴンメッシュで鍋が構成されることになります。

日本語の形状名やマテリアル名、テクスチャ名

fbx形式でエクスポートした場合、
形状名やマテリアル名で日本語を使っていた場合はUTF-8形式でそのまま保持されます。
エクスポート先の環境により異なりますが、このマルチバイト文字列を受け付けることができる環境とできない環境があります。
Unityはマルチバイト文字列(UTF-8)の形状名などを判断できます。
ただし、特に英語圏のツールによっては正しく読み込めない場合があります。
また、ファイルフォーマットによってもマルチバイト文字列を受け付けないものもあります。
glTFフォーマットはUTF-8で形状名などを保持できますが、USDフォーマットはマルチバイト文字列を認識できません。
※ Shade3Dでは、ver.20段階ではglTF/USDフォーマットのインポート/エクスポートには対応していません。

そのため、安全を取る場合は形状名/マテリアル名/イメージ名は半角の英数字にしておいたほうが安全かもしれません。
以下のようにパート名、形状名、マスターマテリアル名を変更しました。
すべてブラウザ上での名前の変更になります。

一番先頭の「ルートパート」も「root」と名前変更しました。
また、形状名では半角スペースを使用せずに「_」(アンダーバー)を使用、
英数字のみ使用しました。

fbxの場合は同一形状名/マテリアル名を指定することができます。
ただし、リアルタイム環境では同一名を許可しない場合も多いです。
その対策のため、同じ名前が重複しないように名前変更しました。

パートの変換行列を確認

fbxでエクスポートする場合、パートの階層構造もそのままの形で出力されます。
fbxでは、変換行列の要素として「移動」「回転」「スケール」を持ちますが、「せん断」要素を持たせることができません。
ブラウザでパートを選択し、形状情報ウィンドウで「パート属性」をチェックします。
「変換要素」タブを選択すると、パートの変換行列の要素が表示されます。

fbxでエクスポートする場合、「スケール」でマイナス値をつけないようにします。
「せん断」は(0, 0, 0)になっているのを確認します。
「回転」「移動」は指定可能です。
なお、パートの階層構造で「スケール」「回転」を使用している場合、相互関係で簡単に「せん断」状態になります。
これは、他ツールに渡したときに正しく表現できない場合が多いです。
そのため、「スケール」も可能な限り(1, 1, 1)としておくほうがいいかもしれません。

fbx形式でエクスポート

以上で形状の最適化が完了したため、fbxでエクスポートします。
fbx形式は、シーンの階層構造やアニメーション対応しているファイルフォーマットになります。
そのため、他ツールにデータを渡す場合によく利用されます。

メインメニューの「ファイル」-「エクスポート」-「FBX」を選択します。
FBXエクスポートダイアログボックスが表示されるため、オプションをチェックしていきます。
「形式」タブで、「バージョン」を「FBX 2012」、「エンコーディング」で「UTF-8」が選択されているのを確認します。

「ジオメトリ」タブで「面の頂点の法線を出力」チェックボックスをオンにします。
法線は、リアルタイム系では非常に大事な要素になります。
法線が形状に存在しない場合、全体が真っ黒になってしまう場合もあります。
「面の頂点の最大数」が4になっているのを確認します。
他ツールに渡した際、ほとんどのツールでは内部的に面の三角形分割が行われますが、これが意図したとおりになるとは限りません。
そのため、Shade3D側で3角形か4角形で構成されるように面を分割して出力します。

「表面材質」タブで、「イメージをFBXファイルに埋め込み」チェックボックスをオフにします。

これは、Shade3Dの「PBRマテリアル」の場合はver.20の段階ではマテリアルパラメータをfbxファイルに持たせることができません。
また、ver.19までの旧「Shade3Dマテリアル」も正しく他ツールに渡すということは難しいです。
そのため、マテリアルについては他ツール側で再割り当てするようにします。

キッチンシーンではアニメーションを持つ形状は存在しないため、「アニメーション」タブで「出力」を「なし」にします。

「出力対象」タブで、すべてのチェックボックスがオフになっていることを確認します。

出力ファイル名を「nabe_big.fbx」としました。
ファイル名は英数字のみで、日本語などのマルチバイト文字列は使用しないようにします。
これは、形状を渡す他ツールでマルチバイトに対応されていない場合もあるためです。
なお、Unityはファイル名にマルチバイト文字列を使っていても正しく読み込まれます。

以上で、「鍋(大).shd」を「nabe_big.fbx」としてエクスポートしました。
この段階では、マテリアルについては正しくエクスポートされたわけではありません。

テクスチャイメージはマテリアルで参照していないものもすべて出力されます。

今回はここまでです。
鍋のアセットを例にして、リアルタイムに渡す際の基本的なチェックポイントを列挙しました。
他の形状の場合で「サブディビジョンサーフェス」を使っている場合や片面のみの面がある場合など、
まだ確認事項がありますので、これらは次回説明していく予定です。

カテゴリー: リアルタイム環境に渡すための最適化