web-dev-qa-db-ja.com

三角形の各頂点の色を設定します

赤、青、緑のメッシュから三角形の3つの頂点をそれぞれ設定したいと思います。

最初の部分で見たように this 別の言語用のチュートリアル。これは、メッシュから各三角形の各頂点に赤、緑、青を設定するために使用しているコードです。

function set_wireframe_colors(m)
    local cc = {}
    for i = 1, m.size/3 do
        table.insert(cc, color(255,0,0))
        table.insert(cc, color(0,255,0))
        table.insert(cc, color(0,0,255))
    end
    m.colors = cc
end

これは、単純な頂点カラーシェーダーを使用した場合の出力の外観です。

enter image description here


UnityでC#を使用して同じことを再現しようとしましたが、このチュートリアルの最初の部分で苦労しています。

これが私のコードです:

void Start()
{
    Mesh mesh = GetComponent<MeshFilter>().mesh;
    Vector3[] vertices = mesh.vertices;

    //Create new colors array where the colors will be created.
    Color32[] colors = new Color32[vertices.Length];

    for (int i = 0; i < vertices.Length; i += 3)
    {
        colors[i] = new Color32(255, 0, 0, 255);
        colors[i + 1] = new Color32(0, 255, 0, 255);
        colors[i + 2] = new Color32(0, 0, 255, 255);
    }

    //assign the array of colors to the Mesh.
    mesh.colors32 = colors;
}

しかし、これは単純な頂点カラーシェーダーを使用してUnityから取得した出力です。

enter image description here


よく見ると、私の立方体の各頂点には、最初のスクリーンショットの立方体のようにRGBカラーが割り当てられていないことがわかります。しかし、それは非常に近くに見えます。

コードの何が問題になっていますか?最初のスクリーンショットの画像のように、各頂点にRGBカラーがないのはなぜですか。

シェーダー

この問題はおそらくシェーダーとは関係ありませんが、ここではUnityの単純なカラーシェーダーです。

struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    float4 color : COLOR;
};

struct v2f
{
    float2 uv : TEXCOORD0;
    UNITY_FOG_COORDS(1)
    float4 vertex : SV_POSITION;
    float4 color : COLOR;
};

sampler2D _MainTex;
float4 _MainTex_ST;


v2f vert(appdata v)
{
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.color = v.color;

    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
}

float4 frag(v2f i) : SV_Target
{
    return i.color;
}
12
Programmer

彼が使用しているメッシュには、三角形ごとに3つの別々の頂点があります(クワッドごとに6つの頂点)。ユニティキューブでは、各面は4つの頂点を持つクワッドであり、各面の2つの三角形は2つの頂点を共有します。
enter image description here

左側は4つの頂点を持つクワッドで、mesh.triangles配列は0 1 2 1 0 3になり、右側はmesh.triangles = 0 1 2 3 4 5(頂点)を持つ6つの頂点を持つクワッドです。裏面カリングでは順序が重要です。シェーダーでは、カルをオフに設定しています)。

したがって、このシェーダーの画像でわかるように、注意が必要で、各三角形の各頂点に各色が1つあることを確認する限り、4つの頂点クワッドで作成されたメッシュを使用できます。


コメントで述べたように、メッシュを分割して、三角形ごとに3つの一意の頂点を作成できます。

void Start () {
    Mesh mesh = GetComponent<MeshFilter>().mesh;        
    SplitMesh(mesh);
    SetColors(mesh);
}

void SplitMesh(Mesh mesh)
{
    int[] triangles = mesh.triangles; 
    Vector3[] verts = mesh.vertices;
    Vector3[] normals = mesh.normals;
    Vector2[] uvs = mesh.uv;

    Vector3[] newVerts;
    Vector3[] newNormals;
    Vector2[] newUvs;

    int n = triangles.Length;
    newVerts   = new Vector3[n];
    newNormals = new Vector3[n];
    newUvs     = new Vector2[n];

    for(int i = 0; i < n; i++)
    {
        newVerts[i] = verts[triangles[i]];
        newNormals[i] = normals[triangles[i]];
        if (uvs.Length > 0)
        {
            newUvs[i] = uvs[triangles[i]];
        }
        triangles[i] = i; 
    }        
    mesh.vertices = newVerts;
    mesh.normals = newNormals;
    mesh.uv = newUvs;        
    mesh.triangles = triangles;            
}   
void SetColors(Mesh mesh)
{
    Color[] colors = new Color[mesh.vertexCount];
    for (int i = 0; i < colors.Length; i+=3)
    {
        colors[i] = Color.red;
        colors[i + 1] = Color.green;
        colors[i + 2] = Color.blue;
    }
    mesh.colors = colors;
}

enter image description here

11
Pluto