Установить цвет для каждой вершины в треугольнике

Я хочу установить каждую три вершины треугольника из сетки красного, синего и зеленого.

Как видно из первой части этого учебника, предназначенного для другого языка. Это код, который они используют для установки красного, зеленого и синего в каждый текст в каждом треугольнике из сетки:

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

и это то, что выглядит результат с помощью простого шейдерного цветного шейдера:

введите описание изображения здесь


Я попытался воссоздать одно и то же в Unity с С#, но я борюсь с первой частью этого урока.

Вот мой код:

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 с простым вершинным цветным шейдером:

введите описание изображения здесь


Если вы посмотрите внимательно, вы увидите, что каждая вершина в моем кубе не имеет цвета rgb, назначенного ему, как куб с моего первого снимка экрана. Это выглядит очень близко.

Что не так с кодом? Почему каждая вершина не имеет цвета rgb, как изображение с моего первого снимка экрана.

Shader

Эта проблема, вероятно, не имеет ничего общего с шейдером, но здесь простой цветной шейдер в 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;
}

Ответ 1

Используемая сетка имеет три отдельных вершины для каждого треугольника (6 вершин на квадрат). В единичном кубе каждая грань представляет собой квадрант с четырьмя вершинами, а два треугольника на каждой грани имеют 2 вершины.
введите описание изображения здесь

Слева квадрат, который имеет 4 вершины, а массив mesh.triangles будет 0 1 2 1 0 3, а справа - квадрат с 6 вершинами с mesh.triangles= 0 1 2 3 4 5 (порядок вершин имеет значение для back- в моем шейдере у меня есть Cull set off off).

Итак, как вы можете видеть на изображении для этого шейдера, вы можете использовать сетки из четырех вершинных квадратов, пока вы будете осторожны, и убедитесь, что каждый треугольник имеет один из каждого цвета в каждой вершине.


Как я уже сказал в комментариях, вы можете разделить свою сетку так, чтобы у вас было 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;
}

введите описание изображения здесь