2017-08-24 50 views
10

Chcę ustawić każdy z trzech wierzchołków trójkąta z siatki na czerwony, niebieski i zielony.Ustaw kolor dla każdego wierzchołka w trójkącie

Jak widać w pierwszej części samouczek this dla innego języka. Jest to kod, którego używają, aby ustawić czerwony, zielony i niebieski do każdego vertext w każdym trójkącie z siatką:

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 

i to wyjście wygląda z prostym kolorze vertex shader:

enter image description here


próbowałem odtworzyć-samo w jedności z C#, ale walczę z pierwszej części tego poradnika.

Oto mój kod:

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; 
} 

ale to jest wyjście otrzymuję od jedności z prostym kolorze vertex shader:

enter image description here


Jeśli przyjrzeć się bliżej będziesz zobacz, że każdy wierzchołek w mojej kostce nie ma przypisanego do niego koloru rgb, tak jak kostka z mojego pierwszego zrzutu ekranu. Wygląda jednak bardzo blisko.

Co jest nie tak z kodem? Dlaczego każdy wierzchołek nie ma koloru rgb jak obraz z mojego pierwszego zrzutu ekranu.

Shader:

Problem ten prawdopodobnie nie ma nic wspólnego z shadera ale tutaj prosty kolor shader w jedności:

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; 
} 
+0

sprawdzić ten ... będzie pomocne: https://forum.unity3d.com/threads/standard-shader-with-vertex-colors.316529/ – joreldraw

+0

Wystarczy, że czerwony. Ten post mówi o tworzeniu vertexowych shaderów, które mogę zrobić.To pytanie dotyczy ustawiania koloru każdego wierzchołka w każdym trójkącie w siatce, z kodu, a nie z modułu cieniującego. Jest inaczej i myślę, że problem prawdopodobnie wynika z kodu C#. Może wierzchołki nie są w porządku. – Programmer

+0

Nie określono modułu cieniującego ani kodu ... tylko kolor wierzchołka – joreldraw

Odpowiedz

10

Siatka jest on za pomocą posiada 3 osobne wierzchołki dla każdego trójkąt (6 wierzchołków na kwadrat). W sześcianie jedności każda twarz jest kwadratem z 4 wierzchołkami, a 2 trójkąty na każdej powierzchni dzielą 2 wierzchołki.
enter image description here

Po lewej stronie znajduje się quad, który ma 4 wierzchołki i tablica mesh.triangles byłoby 0 1 2 1 0 3, a po prawej stronie jest quad z 6 wierzchołków z mesh.triangles = 0 1 2 3 4 5 (Vertex sprawach porządkowych dla back-face uboju. W moim shader Mam Cull ustawiony na off).

Tak jak widać na obrazku dla tego modułu cieniującego, można użyć oczek utworzonych z 4 wierzchołków kwadratowych, o ile zachowuje się ostrożność i upewnić się, że każdy trójkąt ma jeden z każdego koloru w każdym wierzchołku.


Tak jak powiedziałem w komentarzach, możesz podzielić swoją siatkę, aby mieć 3 unikalne wierzchołki dla każdego trójkąta.

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

+0

Wow, wszystko ma więcej sensu. Właśnie zrobiłem prosty sześcian w Mayi i zaimportowałem go do Unity. Myślę, że trudno byłoby posortować kolejność wierzchołków. Jeśli masz rozwiązanie, które może to zrobić, byłoby dobrze. – Programmer

+0

@Programmer Do czego służy ten program? Czy możesz używać shaderów geometrii? Jeśli nie, możesz podzielić siatkę w jedności lub w programie 3D, takim jak Maya lub Blender, z podziałem veretx/edge. W przeciwnym razie patrzysz na [Problem z kolorowaniem wykresu] (https://en.wikipedia.org/wiki/Graph_coloring) – Pluto

+0

Nie, nie mogę używać funkcji cieniowania Geometry, aby była kompatybilna na różnych urządzeniach. To służy do wyświetlania obiektu w modelu szkieletowym. Zobacz [this] (https://codea.io/talk/discussion/3170/render-a-mesh-as-wireframe) post, aby to dobrze zrozumieć. Po prostu nie mogę dostać pierwszej części tego, aby działać poprawnie ..... – Programmer