Version: 2023.1
言語: 日本語
メッシュの基礎
メッシュアセット

メッシュデータ

このページでは、メッシュに含まれるデータと、そのデータを Unity が Mesh クラスに格納する方法についての情報を提供します。

概要

メッシュは、以下のプロパティによって定義されます。

  • 頂点: 3D 空間における位置のコレクションで、任意で属性を追加できます。
  • トポロジー: サーフェスの各面を定義する構造のタイプ。
  • インデックス: 整数のコレクション。トポロジーに基づいて、頂点がどのように組み合わされてサーフェスが作られるかを表します。

これに加えて、可変 (deformable) メッシュは以下のいずれかを含みます。

  • ブレンドシェイプ: メッシュのさまざまな変形バージョンを表すデータ。アニメーションに使用されます。
  • バインドポーズ: スキンされたメッシュのスケルトンの “基本” ポーズを表すデータ。

頂点データ

頂点データの要素は、頂点属性 と呼ばれます。

各頂点は以下の属性を持つことが可能です。

内部的には、すべての頂点データは同じ大きさの別々の配列に格納されます。メッシュに 10 個の頂点位置を持つ 1 つの配列が含まれているとすると、使用する他の頂点属性ごとに 10 の要素を持つ配列も持っています。

C# では、Unity は VertexAttribute enum で利用可能な頂点属性を表します。Mesh クラスのインスタンスが指定された頂点属性を持つかどうかは、Mesh.HasVertexAttribute 関数で確認することができます。

位置

頂点の位置 は、 オブジェクト空間における頂点の位置 を表す。

Unityはこの値を使って、メッシュの表面を決定します。

この頂点属性はすべてのメッシュに必要である。

Mesh クラスで、このデータにアクセスする最も簡単な方法は、Mesh.GetVerticesMesh.SetVertices を使うことです。また、Unity はこのデータを Mesh.vertices に保存しますが、この古いプロパティは効率と使い勝手があまり良くありません。

法線

頂点法線 は、頂点位置でサーフェスから直接 “外” を指す方向を表します。

Unity はこの値を使って、メッシュサーフェスのライトの反射を計算します。

この頂点属性は必須ではありません。

Mesh クラスで、このデータにアクセスする最も簡単な方法は、Mesh.GetNormalsMesh.SetNormals を使うことです。また、Unity はこのデータをMesh.normals に保存しますが、この古いプロパティは効率と使い勝手があまり良くありません。

接線

頂点接線 は、頂点位置でサーフェスの “u” (水平テクスチャ) 軸に沿った方向を表します。

Unity では、頂点接線は、追加のデータとともに 4 成分のベクトルとして保存されます。ベクトルの x,y,z 成分は接線を表し、ベクトルの w 成分はその 向き を表します。Unity では、w の値を使用して、接線と法線のクロス積である 従法線 を計算します。

Unity は、法線マッピングに接線値と従法線値を使用します。

この頂点属性は必須ではありません。

Mesh クラスで、このデータにアクセスする最も簡単な方法は、Mesh.GetTangentsMesh.SetTangents を使うことです。また、Unity はこのデータを Mesh.tangents に保存ししますが、この古いプロパティは効率と使い勝手があまり良くありません。

テクスチャ座標 (UV)

メッシュは最大 8 つの テクスチャ座標 を持つことができます。テクスチャ座標は一般に UV と呼ばれ、ひとまとまりになったものは チャンネル と呼ばれます。

Unity は、テクスチャをメッシュに “巻き付ける” ときにテクスチャ座標を使用します。UV は、テクスチャのどの部分がメッシュサーフェスに揃うのかを頂点位置で示します。

UV チャンネルは一般に、最初のチャンネルを “UV0”、2 番目のチャンネルを “UV1”、以降 “UV7” まで同じ要領で呼ばれます。チャンネルはそれぞれ、シェーダーセマンティクス TEXCOORD0TEXCOORD1 以降 TEXCOORD7 までにマップされます。

デフォルトでは、Unity は最初のチャンネル (UV0) を使用して、ディフューズマップやスペキュラーマップなどの通常テクスチャの UV を保存します。2 番目のチャンネル (UV1) にはベイクされたライトマップ UV を保存し、3 番目のチャンネル (UV2) にはリアルタイムのライトマップ UV の入力データを保存できます。ライトマップ UV と Unity がこれらのチャンネルをどのように使用するかの詳細については、ライトマップ UV を参照してください。

8 つのテクスチャ座標属性はすべて任意です。

Mesh クラスで、このデータにアクセスする最も簡単な方法は、Mesh.GetUVsMesh.SetUVs を使うことです。また、Unity はこのデータを以下のプロパティに保存します。Mesh.uvMesh.uv2Mesh.uv3 以降、同様に Mesh.uv8 まで。この古いプロパティは効率と使い勝手があまり良くありません。

Color

頂点色 は、頂点の通常色を表します (存在する場合)。

この色は、メッシュが使用するテクスチャとは無関係に存在します。

この頂点属性は必須ではありません。

Mesh クラスで、このデータにアクセスする最も簡単な方法は、Mesh.GetColorsMesh.SetColors を使うことです。また、Unity はこのデータをMesh.colors に保存しますが、この古いプロパティは効率と使い勝手があまり良くありません。

ブレンドインデックスとボーンウェイト

スキンされたメッシュでは、 ブレンドインデックス によってどのボーンが頂点に影響を与えるかを示し、ボーンウェイト によってそれらのボーンが頂点に与える影響の強さを表します。

Unity では、これらの頂点属性は一緒に保存されます。

Unity はブレンドインデックスとボーンウェイトを使用して、スケルトンの動きに基づいてスキンしたメッシュを変形させます。詳細は、Skinned Mesh Renderer を参照してください。

これらの頂点属性は、スキンされたメッシュに必須です。

以前は、Unity は 1 つの頂点に影響を与えるボーンを最大 4 つまでしか許可しませんでした。このデータは Mesh.boneWeights 配列の BoneWeight 構造体に格納されていました。現在、Unity では頂点に影響を与えるボーンを最大 256 個まで使用できます。このデータは BoneWeight1 構造体に格納され、Mesh.GetAllBoneWeightsMesh.SetBoneWeights を使ってアクセスすることができます。詳細は、リンク先のドキュメントを参照してください。

トポロジー

トポロジーは、メッシュが持つ面の種類を表します。

メッシュのトポロジーはインデックスバッファの構造を定義し、頂点位置がどのように面に結合されるかを説明します。トポロジーの種類によって、1 つの面を定義するために使用するインデックス配列の要素数が異なります。

Unity は以下のメッシュトポロジーをサポートします。

  • Triangle
  • Quad
  • Lines
  • LineStrip
  • Points

ノート: Points トポロジーは面を作成しません。その代わり、Unity は各位置に 1 つの点を描画します。他のすべてのメッシュトポロジーは、面またはエッジ (辺) を作成するために複数のインデックスを使用します。

Mesh クラスで、Mesh.GetTopology によってトポロジーを取得し、それを Mesh.SetIndices のパラメーターとして設定しできます。

サポートされるメッシュトポロジーの詳細は、MeshTopology enum のドキュメントを参照してください。

ノート: 他のモデリング技術 (NURBS や NURMS/Subdivision Surfaces モデリングなど) を使用するメッシュは、Unity で使用する前に、モデリングソフトウェアに適応する形式に変換する必要があります。

インデックスデータ

インデックス配列には頂点位置配列の要素を参照するための整数が含まれます。これらの整数をインデックスと呼びます。

Unity はインデックスを使用して、頂点の位置を面に接続します。各面を作るインデックスの数は、メッシュのトポロジーに依存します。

Mesh クラスで、Mesh.GetIndices でこのデータを取得し、Mesh.SetIndices で設定します。また、Unity はこのデータを Mesh.triangles に保存しますが、この古いプロパティは効率性と使い勝手があまり良くありません。

ノート: Points トポロジーは面を作成しません。その代わり、Unity は各位置に 1 つの点を描画します。他のすべてのメッシュトポロジーは、面またはエッジ (辺) を作成するために複数のインデックスを使用します。

例えば、以下の値を含むインデックス配列を持つメッシュの場合

0,1,2,3,4,5

メッシュが三角形のトポロジーの場合、最初の 3 つの要素 (0,1,2) が 1 つの三角形を示し、次の 3 つの要素 (3, 4, 5) が別の三角形を示します。 1 つの頂点が寄与できる面の数には制限はありません。つまり、同じ頂点が 1 つのインデックス配列に複数回現れる可能性があります。例えば、インデックス配列は以下のような値を持つことができます。

0,1,2,1,2,3

メッシュが三角形のトポロジーの場合、最初の 3 つの要素 (0,1,2) が 1 つの三角形を示し、次の 3 つの要素 (1,2,3) は最初の三角形と一部の頂点を共有する別の三角形を示します。

巻き順

インデックス配列における各グループの頂点の順序は、巻き順 (winding order) と呼ばれます。Unity は巻き順を使用して、面が表向きか裏向きかを判断し、その結果、面をレンダリングすべきかカリング (レンダリングから除外) すべきかを判断します。デフォルトでは、正面を向いたポリゴンをレンダリングし、背面を向いたポリゴンをカリングします。 Unity は時計回りの巻き順で、インデックスが時計回りにつながっている面を表向きと見なします。

プリズムで可視化された Unity の巻き順
プリズムで可視化された Unity の巻き順

上の図は、Unity が巻き順をどのように使用するかを示しています。各面の頂点の順番によって、その面の法線の方向が決まり、Unity はこれを現在のカメラ視点の前方方向と比較します。法線が現在のカメラの前方方向から離れる方向を指している場合、それは後ろ向きです。 近い方の三角形は (1, 2, 3) の順で、現在の視点に対して時計回りの方向になっています。つまり、この三角形は正面向きである。さらに遠い三角形は (4, 5, 6) となり、この視点からは反時計回りの方向となる。つまり、この三角形は後ろ向きです。

ブレンドシェイプ

ブレンドシェイプは、メッシュがさまざまな形状に変形されたバージョンを表します。Unity はそれらの間を補間します。ブレンドシェイプは、モーフターゲットアニメーション に使用されます。これは顔の表情のアニメーションの一般的なテクニックです。

ブレンドシェイプのデータはブレンドシェイプの頂点として保存されます。ブレンドシェイプのデータは “まばら”です。つまり、すべてのメッシュ頂点に対してブレンドシェイプ頂点があるわけではなく、メッシュ頂点が変形した場合にのみ対応するブレンドシェイプ頂点があります。

ブレンドシェイプの頂点には、位置、法線、接線のデルタと 1 つのインデックス値が含まれます。インデックス値の意味は、どのようにデータをリクエストしたかによって異なります。

Meshクラスでは、Mesh.GetBlendShapeBuffer でブレンドシェイプの頂点データにアクセスできます。これは GPU 上のブレンドシェイプ頂点データへのアクセスを提供する GraphicsBuffer を返します。このメソッドでは、2 つの異なるバッファを選択できます。1 つはブレンドシェイプごとにデータを並べるもので、もう 1 つはメッシュ頂点ごとにデータを並べるものです。バッファの選択によって、インデッ クス値の意味とバッファ内のデータのレイアウトが決まります。バッファレイアウトの詳細については、BlendShapeBufferLayout を参照してください。

ブレンドシェイプの詳細については、ブレンドシェイプの操作方法 を参照してください。

このデータは必須ではありません。

バインドポーズ

スキンされたメッシュでは、ボーンの バインドポーズ は、スケルトンがそのデフォルトの位置 (バインドポーズとも呼ばれる) にあるときのボーンの位置を表します。

Mesh クラスで、このデータを Mesh.bindposes で取得設定することができます。各要素には、同じインデックスを持つボーンのデータが含まれています。

このデータは、スキンされたメッシュに必要なデータです。

メッシュの基礎
メッシュアセット