MRが楽しい

MRやVRについて学習したことを書き残す

Blenderで面ごとにUVを設定したオブジェクトをUnityに取り込んだ場合のUVマップを確認する

本日は Blender と Unity の調査枠です。
Blenderで面ごとにUVを設定したオブジェクトをUnityに取り込んだ場合のUVマップを確認したので記事に残します。

Blenderで面ごとにUVを設定する

BlenderでUVマップの編集を行うと面ごとにUVマップの編集を行うことが可能です。
例えば、Blenderでは以下のような頂点とUVマップ座標が1対1に紐づかないUVマップ展開が行えます。

通常のUVマップの展開を行った場合


面ごとにUVマップを展開して同じようにテクスチャを参照した場合


本モデルをUnityに取り込む

Unity では取り込んだ3Dモデルを Mesh コンポーネントで再構築します。
Mesh コンポーネントは頂点とそのUVマップの座標が1対1で紐づくため、上記のような1つの頂点に複数のUVマップ座標が割り当てられる3Dモデルがどう再現されるのかを確認してみます。
docs.unity3d.com

以下のコンポーネントを使って取り込んだ3Dモデルのメッシュ攻勢を確認してみました。
・UVCheckTest.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;

public class UVCheckTest : MonoBehaviour
{
    public MeshFilter checkUVMesh;
    
    void Start()
    {
        CheckVerticesZero(checkUVMesh.mesh);
        CheckUVZero(checkUVMesh.mesh);
        CheckTriangleZero(checkUVMesh.mesh);
    }

    /// <summary>
    /// Mesh内の頂点リストを確認する
    /// </summary>
    /// <param name="mesh"></param>
    void CheckVerticesZero(Mesh mesh)
    {
        List <Vector3> vertices = new List <Vector3>();
        mesh.GetVertices(vertices);
        int count = 0;
        string message = "";
        foreach (var vert in vertices)
        {
            message = $"{message}X:{vert.x},Y:{vert.y},Z:{vert.z}, ";
            count++;
        }
        Debug.Log($"{message}");
        Debug.Log($"Vertices Count : {count}");
    }

    /// <summary>
    /// Mesh内のUV座標リストを確認する
    /// </summary>
    /// <param name="mesh"></param>
    void CheckUVZero(Mesh mesh)
    {
        List <Vector2> uvs = new List <Vector2>();
        mesh.GetUVs(0, uvs);
        int count = 0;
        string message = "";
        foreach (var uv in uvs)
        {
            message = $"{message}X:{uv.x},Y:{uv.y}, ";
            count++;
        }
        Debug.Log($"{message}");
        Debug.Log($"UV Count : {count}");
    }
    
    /// <summary>
    /// Mesh内の三角面配列リストを確認する
    /// </summary>
    /// <param name="mesh"></param>
    void CheckTriangleZero(Mesh mesh)
    {
        List<int> triangles = new List<int> ();
        mesh.GetTriangles(triangles, 0);
        int count = 0;
        string message = "";
        foreach (var triangle in triangles)
        {
            message = $"{message}{triangle}, ";
            count++;
        }
        Debug.Log($"{message}");
        Debug.Log($"Triangle Count : {count}");
    }
}

確認結果

確認結果は以下の通りです。
面ごとにUVを設定した3Dモデルは頂点がUVマップ座標の対応ごとに分けられていることが分かりました。
この仕様により、Blender から出力して取り込んだモデルはUVマップの設定によっては三角面数は変わりませんが、頂点数は増えていることがあるようです。

通常のUVマップの展開を行った場合


・頂点数:8
・UVマップ座標数:8
・三角面数:8(24/3)

面ごとにUVマップを展開して同じようにテクスチャを参照した場合


・頂点数:16
・UVマップ座標数:16
・三角面数:8(24/3)