Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to Render/Draw mesh lines OVER texture at runtime/play mode

Discussion in 'General Graphics' started by vitorenes, Jul 15, 2017.

  1. vitorenes

    vitorenes

    Joined:
    Sep 17, 2013
    Posts:
    10
    Hello, fellow Unity brothers and sisters.

    I, being the complete n00b that I am, have been reading all I could find about this feature I'd love to have, but so far have not found a satisfactory (and, of course, n00b-friendly) answer or explanation.

    You see: VERY easily, in the Editor's Scene view/window, I can enable "Shaded Wireframe" mode to see the actual lines/edges drawn over the PROCEDURALLY GENERATED textured mesh I am, let's say, working with.

    The thing I DESPERATELY WANT is to replicate that look at runtime. Of course, when I go to play mode, bye-bye lines. It is, in my mind, SO APPARENTLY EASY to do, or at least should be, that I haven't figured out how to do it. Here are a couple of sshots - one as it looks now in play mode, and another (captured in the scene view) that shows how I would like it to look (control of the line color would be a plus, although I am completely fine with the line thickness, and the fact that it stays the same all over and doesn't show perspective perception, or something like that):

    Mesh at runtime / play mode:


    Mesh in the Editor window / how I want it to look:


    I have three "approaches" I have derived from everything I've read/asked, but alas, no final solution yet:

    1) Some shader or another. I know there are shaders/assets/whatever out there that could help me do this, but I really don't want to BUY an asset to solve the problem - I want to LEARN how to solve it;

    2) Somebody, VERY knowledgeable suggested me "hey, google Meshtopology.Lines" (and that was it). I did, and this looked promising, until I didn't find any "entry point" for this in the proc gen tutorial I was following (the only reference to it I found was using said Meshtopology.Lines as a parameter for a SetIndices method that I am not using). Also, not much documentation around about " MeshTopology", nor have I found any useful (and again, n00b-friendly) tutorials about this;

    3) Use GL. Now... did I mention I am a n00b? Yeah.

    Any, and I mean ANY, pointers towards more information about how to approach a solution to this would be EXTREMELY appreciated (blogs, articles, books, videos, ancient voodoo rituals requiring animal sacrifices or not...)

    This can't be that HARD... or is it?

    Many thanks in advance,
    Vitor.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
  3. vitorenes

    vitorenes

    Joined:
    Sep 17, 2013
    Posts:
    10
    bgolus,
    Many thanks for your answer. However, and I don't want to sound ungrateful or anything, since (as I mentioned several times) I am very new to this, I am having a little trouble following you here. I looked at the linked thread, and it did provide some orientation, but I am still at a loss here (sorry!)

    Any chance you have some sample code laying around? Or maybe have some other threads or docs you could point me to? I will keep on digging this info you provided, in the hopes I can unravel something else from it.

    Again, may thanks!
     
  4. vitorenes

    vitorenes

    Joined:
    Sep 17, 2013
    Posts:
    10
    Hey, guys.

    I THINK I figured it out - I haven't implemented it yet on my proc gen routine, but at least I managed to get a semblance of what I wanted to achieve in a separate (new) project. I'll try it tomorrow and will report back here.

    Here's what I did, in case anyone wonders or has the same difficulties I did (and I STILL think this is well under-documented):

    • At the moment of initialization of the new mesh, I declared a subMesh count of 2, using:

      mesh.subMeshCount = 2;

    • Then I created (and populated) and array of Materials (you can do this however you want to - I used the inspector), and then passed/set this array as the mesh renderer's materials with:

      GetComponent<MeshRenderer>().materials = materialsArray;

    • This effectively creates a "copy" of the (procedural) mesh "on top" of the original (that, is the submesh) - therefore, you end up with TWO exactly identical (in every aspect) meshes occupying the " same space" that you can access separately and, YES!, that you can assign different materials AND DIFFERENT MESH TOPOLOGIES!
    • So, AFTER creating the " base" mesh with index = 0, say using:

      mesh.SetTriangles(trianglesList, 0);

      and recalculating normals, whatever... you THEN can reuse the triangles list (recast as an array) to set a DIFFERENT mesh topoly to submesh 1 (which I guess since its index is greater than 0 sits "atop" submesh 0) by using SetIndices INSTEAD of using SetTriangles, like so:

      mesh.SetIndices(triangles.ToArray(), MeshTopology.Lines, 1);

    • The KEY here is MeshTopology.Lines, as someone indicated me before (and I didn't knew how to use); this will result in lines drawn on top of whatever you have assigned to the materialArray[0] material, using the materialArray[1] material, since Unity (I guess...) will match whatever material is at whatever index (of the material array) corresponds to the submesh you are working on.
    And that was it! It was pretty rewarding to figure this out, even if it is a stupid little thing that no one else needs, and even if it is one of those things experienced developers look at and think/say: "duh!"

    Again, I will report back whether this was useful for my previous attempts (my guess I it will). Thanks to bgolus again for his initial suggestions, and in case anyone finds this useful, you're welcome! :)

    V.
     
  5. triple_why

    triple_why

    Joined:
    Jun 9, 2018
    Posts:
    47
    I know this is an old thread, but it's still one of the top results when searched for drawing wire frame mesh.

    Above solution is valid with a minor correction, and works for me on Unity 2020.1. Correction is, triangles.ToArray() is not suitable for building lines' indices. So, here is the code part that works and draws wireframed triangular mesh:

    Code (CSharp):
    1. // ... after preparing vertices, uvs and triangle indices;
    2. // assign mesh data
    3. mesh.Clear(false);
    4. mesh.vertices = vertices;
    5. mesh.subMeshCount = 2;
    6. // submesh 0: main-mesh
    7. mesh.uv = uvs;
    8. mesh.SetTriangles(triangles, 0);
    9. // submesh 1: wire-frame
    10. // 3 lines require 6 indices per triangle which has 3 indices at main-mesh, so double indices count
    11. int[] wires = new int[triangles.Length * 2];
    12. for (int iTria = 0; iTria < trianglesCount; iTria++)
    13. {
    14.     for (int iVertex = 0; iVertex < 3; iVertex++)
    15.     {
    16.         wires[6 * iTria + 2 * iVertex] = triangles[3 * iTria + iVertex];
    17.         wires[6 * iTria + 2 * iVertex + 1] = triangles[3 * iTria + (iVertex + 1) % 3];
    18.     }
    19. }
    20. mesh.SetIndices(wires, MeshTopology.Lines, 1);
    21.  
    As already noted, Mesh Renderer component's Materials array's size must be 2. Second material's shader can be a simple one, like Unlit/Color, since it just renders wires, and that materials Main Color will be the color of the wires.