開発部エンジニアのY.A.です。
今日はUnityを使って動的に3Dモデルを作成していた際にはまった点をお話ししたいと思います。
はじめに
UnityではMeshクラスを用いて、任意の3Dモデルを作成できます。
具体的な方法は省略しますが、以下のような手順で作成します。
- 頂点一覧を渡す
- 頂点をどのような順番でつなぐかの一覧を作成する
- Meshクラスに渡す
今日のゴール
私が目指しているゴールは以下のような3Dモデルを表示できるようにすることです。
色も鮮やかでとても見やすいですね。
いくつかのモデルを動的に読み込みましたが、テストの中でこのファイルだけうまく取り込めませんでした。
現実
これが、実行時の現実です。
メッシュが左右に広がり、3Dモデルが完全に崩れています。
原因と対応方法
色々と調査していて、頂点数が65535を閾値として描画が崩れていることが分かりました。
最初はシェーダーやレンダラーに問題があると思っていたのですが、とても身近に設定がありました。
65535を超える頂点数はデフォルトでは保持できないんですね。
参考記事
以下の記事でシンプルな対応ができるようになりました。
65535が閾値とわかったときは、65535でモデル分割するべきか悩んでいたので助かりました!
inoookov.hatenablog.com
対応方法
最終的にはMeshクラス作成時の処理を以下のようにすることで、動的生成時の頂点数問題に対応しました。
IndexFormat.UInt32を常に設定してもいいのですが、メモリの確保サイズが2倍異なるとのことだったので、可変にしました。
var mesh = new Mesh(); //▼頂点数に応じてindexFormatを変更 if (vertices.Count > ushort.MaxValue) mesh.indexFormat = IndexFormat.UInt32;//頂点数:4294967295 else mesh.indexFormat = IndexFormat.UInt16;//頂点数:65535 mesh.name = lay.Layer.Name; mesh.vertices = vertices.ToArray();//頂点の設定 mesh.normals = normals.ToArray();//法線ベクトルの設定 mesh.colors32 = colors.ToArray();//頂点色の設定 mesh.SetIndices(triangles, MeshTopology.Triangles, 0);//頂点インデックスの設定 mesh.Optimize();
まとめ
Unityは座標値もFloatだったりと、デフォルトで桁数が少なめに定義されているので、もっと早く気づくべきでした。
コードを書いた後に、「頂点の一覧はこちらから渡しているのだからMeshクラスでいい感じにやってくれないかなぁ」と心の中で文句を言いながら、
いい感じに描画できたモデルをまじまじと眺めています。
3Dの描画は最初が大変ですが、描画ができてしまうととても楽しいですよね。
今後はマテリアルを調整等してもっときれいな描画になるように心がけていきたいです!
おわりに
KENTEMでは、様々な拠点でエンジニアを大募集しています! 建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。 recruit.kentem.jp career.kentem.jp