簡體   English   中英

為三角形中的每個頂點設置顏色

[英]Set color for each vertex in a triangle

我想從網格紅色、藍色和綠色中設置三角形的每個三個頂點。

教程的第一部分所示,它適用於另一種語言。 這是他們用來為網格中每個三角形中的每個頂點設置紅色、綠色和藍色的代碼:

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

這就是 output 使用簡單的頂點顏色着色器后的樣子:

在此處輸入圖像描述


我試圖在 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 獲得的帶有簡單頂點顏色着色器的 output:

在此處輸入圖像描述


如果你仔細觀察,你會發現我的立方體中的每個頂點都沒有分配給它的 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;
}

他使用的網格每個三角形有3個獨立的頂點(每個四邊形6個頂點)。 在統一立方體中,每個面是具有4個頂點的四邊形,並且每個面上的2個三角形共享2個頂點。
在此輸入圖像描述

左邊是一個四邊形,有四個頂點, mesh.triangles數組是0 1 2 1 0 3 ,右邊是一個四邊形,有6個頂點,帶有mesh.triangles = 0 1 2 3 4 5 (頂點順序很重要)對於背面剔除。在我的着色器中,我將Cull設置為關閉)。

因此,您可以在圖像中看到此着色器,您可以使用由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;
}

在此輸入圖像描述

這不是一個非常優雅的解決方案,但這對我有用。

    Mesh newMesh = newObject.GetComponent<MeshFilter>().mesh = mesh;
    Vector3[] vertices = newMesh.vertices;
    Vector3[] normals = newMesh.normals;
    int[] triangles = newMesh.triangles;
    var newVertices = new Vector3[triangles.Length];
    var newNormals = new Vector3[triangles.Length];
    var newTriangles = new int[triangles.Length];

    for (var i = 0; i < triangles.Length; i++)
    {
        newVertices[i] = vertices[triangles[i]];
        newNormals[i] = normals[triangles[i]];
        newTriangles[i] = i;
    }
    newMesh.vertices = newVertices;
    newMesh.normals = newNormals;
    newMesh.triangles = newTriangles;

    Color[] colors = new Color[newVertices.Length];
    for (int i = 0; i < newVertices.Length-5; i++)
    {
        float r = UnityEngine.Random.value;
        float g = UnityEngine.Random.value;
        float b = UnityEngine.Random.value;
        if (i % 6 == 0)
        {
            colors[i] = new Color(r, g, b, 1f);
            colors[i + 1] = new Color(r, g, b, 1f);
            colors[i + 2] = new Color(r, g, b, 1f);
            r = UnityEngine.Random.value;
            g = UnityEngine.Random.value;
            b = UnityEngine.Random.value;
            colors[i + 3] = new Color(r, g, b, 1f);
            colors[i + 4] = new Color(r, g, b, 1f);
            colors[i + 5] = new Color(r, g, b, 1f);
        }
    }

    newMesh.colors = colors;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM