Blender 2.64 から Python エクスポート スクリプトを作成しています。アイデアは、OpenGL VBO に適した方法でメッシュ データをエクスポートしようとしているということです。したがって、構造体レイアウトの配列で頂点属性をエクスポートしています。たとえば、頂点、法線、および 1 組のテクスチャ座標を持つメッシュの場合、vertexAttribute
VBO 内のそれぞれは 8 つの連続する float になります。
vvvnnntt
ここまでは順調ですね。問題は、Blender が UV マッピングを行うときに、実際には異なる UV を同じ頂点に割り当てることができることです。
つまり、立方体があるとします。頂点が 8 つあり、面が 6 つあるとします (この場合は四角形)。インデックスが 0,1,2,3 の面/ポリゴンは次のことを暗示していると予想していました。
vertex 0, normal 0, uvCoord0
vertex 1, normal 1, uvCoord1
vertex 2, normal 2, uvCoord2
vertex 3, normal 3, uvCoord3
したがって、たとえば、任意の面でインデックス 0 に言及すると、頂点 0、法線 0、uvCoord0 タプルが常に暗示されます。さて、Blender で判明しました。正しく理解すれば、ある面が uvCoord 0 で頂点 0 を参照し、別の面が別の uVCoord で同じ頂点 0 を参照する可能性があります。data.vertices
したがって、フェイスの loop_indices を実際に使用して、オブジェクト ジェネラルとdata.uv_layers[].data
コンテナ内のベクトルと uvCoord の両方を検索する必要があります。
これにより、面ごとに UV マップを適用できます。したがって、各面に異なる UV テクスチャが適用された立方体を作成できます。2 つの隣接する面が頂点を共有している場合でも、頂点は面に応じて異なる UV 座標を持ちます。
それでも、隣接する面にアンラップしているため、メッシュは同じ頂点に対して異なる UV を持つべきではありません。つまり、私の UV マップでは、ラップされていないメッシュは隣接する面のセット (たとえば、6 つの面で構成される立方体の場合は十字形と考えてください) であり、隣接する 2 つの面の間では、それらの共通の頂点が同じポイントにマップされる必要があります。 UVマップで。
したがって、上記を考えると、このアプローチはうまくいくはずだと思いました:
vertexAttributeList = []
for vertex in mesh.data.vertices:
vertexAttribute = list(vertex.co)
vertexAttribute.extend(list(vertex.normal))
vertexAttributeList.append(vertexAttribute)
for triangle in mesh.data.polygons:
for uv_layer in mesh.data.uv_layers:
for i in triangle.loop_indices:
lookupIndex = mesh.data.loops[i].vertex_index
if len(vertexAttributeList[lookupIndex]) == 6:
uvCoord = uv_layer.data[i].uv
vertexAttributeList[lookupIndex].extend([uvCoord[0], 1 - uvCoord[1]])
ご覧のとおり、上記のコードの意味は、頂点を共有するメッシュの面 (この場合は三角形) を反復処理するために、頂点に複数回アクセスすることです。頂点にアクセスするたびに、まだ UV 座標が割り当てられていない場合は、三角形の loop_indices を使用して検索して割り当てます。結局のところ、私の仮定は、結局のところ、頂点ごとに一意の UV 座標があるということでした。
上記のコードは、たとえば、次のレイアウトを提供します (メッシュの最初の 6 つの頂点属性を表示しています)。
-1.000000 -1.000000 -1.000000 -0.707083 -0.707083 0.000000 0.076381 0.948520
-1.000000 1.000000 -1.000000 -0.707083 0.707083 0.000000 0.454183 0.948519
1.000000 1.000000 -1.000000 0.707083 0.707083 0.000000 0.325162 0.948519
1.000000 -1.000000 -1.000000 0.707083 -0.707083 0.000000 0.205674 0.948519
-1.000000 -1.000000 1.000000 -0.577349 -0.577349 0.577349 0.581634 0.795012
-1.000000 1.000000 1.000000 -0.577349 0.577349 0.577349 0.454183 0.795012
...
しかし、この情報とメッシュの面を使用すると、次のようにレイアウトします。
4 5 1
5 6 2
6 7 3
7 4 0
...
私のプログラム (一種のエンジン) でモデルをレンダリングすると、UV マッピングが明らかにめちゃくちゃになります。つまり、モデルは頂点と法線に関しては適切にレンダリングされますが、UV テクスチャは明らかに正しくマッピングされていません。
何かご意見は?つまり、正しくエクスポートしてアプリの OpenGL レンダリング コードを台無しにしているか、頂点と UV 座標間の間違ったマッピングをエクスポートしています。(または両方、確かに..しかし、今のところ、エクスポートスクリプトを台無しにしていると思います)。
最後にもう 1 つ、上記の Python コードを変更して、頂点 1 に対して、UV がまだ割り当てられていない場合にのみ追加するのではなく、頂点に割り当てられた新しい各 UV を追加すると、次のようになります。
[-1.0, -1.0, -1.0, -0.7070833444595337, -0.7070833444595337, 0.0, 0.07638061791658401, 0.9485195726156235, 0.5816344618797302, 0.9485194832086563, 0.07638061791658401, 0.9485195726156235]
この例では、UV レイヤーが 1 つしかないことに注意してください。明らかに、Blender は 2 つの UV 座標を頂点 1 に割り当てました。