Search Unity

Wireframe 3D?

Discussion in 'Editor & General Support' started by willgoldstone, Feb 9, 2008.

  1. Wipeout

    Wipeout

    Joined:
    May 31, 2011
    Posts:
    1
    I know I'm a little late to this, but is there a way to set this script to only apply a white wireframe? Perhaps also keep the applied material of the object before script is applied?
     
  2. ina

    ina

    Joined:
    Nov 15, 2010
    Posts:
    1,084
    does this work at runtime or just in the editor?
     
  3. mhaddon

    mhaddon

    Joined:
    Dec 16, 2009
    Posts:
    7
    I've made my little update adding the lastMaterial variable which stores the original material.
    Also changed the Start() to OnEnable() and added the OnDisable() which sets the original material again when you turn off the script.

    Code (csharp):
    1.    
    2. // Add a GUI Button to trigger this?? up to you.
    3. function toggleWireframe(go : GameObject) {    
    4.         var wireframe : Wireframe;
    5.     if(go) {
    6.         wireframe = g.GetComponent(Wireframe);
    7.         if(!wireframe) {
    8.             g.AddComponent(Wireframe);
    9.             return;
    10.         }
    11.        
    12.         wireframe.enabled = !wireframe.enabled;
    13.     }
    14. }
    15.  
    Slightly modified from above posts in this thread.
    Code (csharp):
    1.  
    2. // attach to an object with a mesh filter
    3.  
    4.     var lineColor : Color = Color.white;
    5.     var backgroundColor : Color = Color.white;
    6.     var ZWrite = true;
    7.     var AWrite = true;
    8.     var blend = true;
    9.      
    10.     private var lines : Vector3[];
    11.     private var linesArray : Array;
    12.     private var lineMaterial : Material;
    13.     private var meshRenderer : MeshRenderer;
    14.    
    15.     private var lastMaterial : Material; //when first enabled it will get the current material and set as the last material.
    16.    
    17.     //Wireframe off, set back to the old material.
    18.     function OnDisable() {
    19.         meshRenderer.material = lastMaterial;
    20.     }
    21.    
    22.     //Can change back to on start if you want :)
    23.     function OnEnable ()
    24.     {
    25.         meshRenderer = GetComponent(MeshRenderer);
    26.         if(!meshRenderer) meshRenderer = gameObject.AddComponent(MeshRenderer);
    27.         if(!lastMaterial) lastMaterial = meshRenderer.material;
    28.         meshRenderer.material = new Material("Shader \"Lines/Background\" { Properties { _Color (\"Main Color\", Color) = (1,1,1,1) } SubShader { Pass {" + (ZWrite ? " ZWrite on " : " ZWrite off ") + (blend ? " Blend SrcAlpha OneMinusSrcAlpha" : " ") + (AWrite ? " Colormask RGBA " : " ") + "Lighting Off Offset 1, 1 Color[_Color] }}}");
    29.        
    30.         lineMaterial = new Material("Shader \"Lines/Colored Blended\" { SubShader { Pass { Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Cull Front Fog { Mode Off } } } }");
    31.        
    32.         lineMaterial.hideFlags = HideFlags.HideAndDontSave;
    33.         lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
    34.        
    35.         linesArray = new Array();
    36.         var filter : MeshFilter = GetComponent(MeshFilter);
    37.         var mesh = filter.mesh;
    38.         var vertices = mesh.vertices;
    39.         var triangles = mesh.triangles;
    40.        
    41.         for (var i = 0; i < triangles.length / 3; i++)
    42.         {
    43.             linesArray.Add(vertices[triangles[i * 3]]);
    44.             linesArray.Add(vertices[triangles[i * 3 + 1]]);
    45.             linesArray.Add(vertices[triangles[i * 3 + 2]]);
    46.         }
    47.        
    48.         lines = linesArray.ToBuiltin(Vector3);
    49.     }
    50.      
    51.      
    52.     function OnRenderObject()
    53.     {  
    54.         meshRenderer.material.color = backgroundColor;
    55.         lineMaterial.SetPass(0);
    56.        
    57.         GL.PushMatrix();
    58.         GL.MultMatrix(transform.localToWorldMatrix);
    59.         GL.Begin(GL.LINES);
    60.         GL.Color(lineColor);
    61.        
    62.         for (var i = 0; i < lines.length / 3; i++)
    63.         {
    64.             GL.Vertex(lines[i * 3]);
    65.             GL.Vertex(lines[i * 3 + 1]);
    66.            
    67.             GL.Vertex(lines[i * 3 + 1]);
    68.             GL.Vertex(lines[i * 3 + 2]);
    69.            
    70.             GL.Vertex(lines[i * 3 + 2]);
    71.             GL.Vertex(lines[i * 3]);
    72.         }
    73.              
    74.         GL.End();
    75.         GL.PopMatrix();
    76.     }
     
  4. Mstrymt

    Mstrymt

    Joined:
    Jul 2, 2012
    Posts:
    6
    Updated the C# version so the colours work, changed some syntax for personal preference but otherwise exactly the same.
    (I resisted the urge to change "Color" to "Colour")

    I take no credit, I literally found the missing pieces from the JS script and pasted them in.

    Code (csharp):
    1. using System.Linq;
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4.  
    5.  
    6. public class WireframeRenderer : MonoBehaviour
    7. {
    8.  
    9.     //****************************************************************************************
    10.  
    11.     //  Material options
    12.  
    13.     //****************************************************************************************
    14.  
    15.     public Color LineColor;
    16.     public Color BackgroundColor;
    17.  
    18.     public bool ZWrite = true;
    19.     public bool AWrite = true;
    20.     public bool Blend = true;
    21.  
    22.     public int Fidelity = 3;
    23.  
    24.     public MeshRenderer MeshRenderer;
    25.  
    26.  
    27.     //****************************************************************************************
    28.  
    29.     // Line Data
    30.  
    31.     //****************************************************************************************
    32.  
    33.     private Vector3[] _lines;
    34.     private readonly List<Line> _linesArray = new List<Line>();
    35.  
    36.     private Material _lineMaterial;
    37.  
    38.  
    39.     //*****************************************************************************************
    40.  
    41.     // Helper class, Line is defined as two Points
    42.  
    43.     //*****************************************************************************************
    44.  
    45.     public class Line
    46.     {
    47.  
    48.         public Vector3 PointA;
    49.         public Vector3 PointB;
    50.  
    51.         public Line(Vector3 a, Vector3 b)
    52.         {
    53.             PointA = a;
    54.             PointB = b;
    55.         }
    56.  
    57.         //*****************************************************************************************
    58.  
    59.         // A == B if   Aa&Ab == Ba&Bb or Ab&Ba == Aa  Bb
    60.  
    61.         //*****************************************************************************************
    62.  
    63.         public static bool operator ==(Line lA, Line lB)
    64.         {
    65.  
    66.             if (lA.PointA == lB.PointA  lA.PointB == lB.PointB)
    67.             {
    68.                 return true;
    69.             }
    70.  
    71.             if (lA.PointA == lB.PointB  lA.PointB == lB.PointA)
    72.             {
    73.                 return true;
    74.             }
    75.  
    76.             return false;
    77.  
    78.         }
    79.  
    80.  
    81.  
    82.         //*****************************************************************************************
    83.  
    84.         // A != B if   !(Aa&Ab == Ba&Bb or Ab&Ba == Aa  Bb)
    85.  
    86.         //*****************************************************************************************
    87.  
    88.         public static bool operator !=(Line lA, Line lB)
    89.         {
    90.             return !(lA == lB);
    91.         }
    92.  
    93.     }
    94.  
    95.  
    96.  
    97.     //*****************************************************************************************
    98.  
    99.     // Parse the mesh this is attached to and save the line data
    100.  
    101.     //*****************************************************************************************
    102.  
    103.     public void Start()
    104.     {
    105.         MeshRenderer = gameObject.GetComponent<MeshRenderer>() ?? gameObject.AddComponent<MeshRenderer>();
    106.         MeshRenderer.material = new Material("Shader \"Lines/Background\" { Properties { _Color (\"Main Color\", Color) = (1,1,1,1) } SubShader { Pass {" + (ZWrite ? " ZWrite on " : " ZWrite off ") + (Blend ? " Blend SrcAlpha OneMinusSrcAlpha" : " ") + (AWrite ? " Colormask RGBA " : " ") + "Lighting Off Offset 1, 1 Color[_Color] }}}");
    107.  
    108.         _lineMaterial = new Material("Shader \"Lines/Colored Blended\" { SubShader { Pass { Blend SrcAlpha OneMinusSrcAlpha BindChannels { Bind \"Color\",color } ZWrite On Cull Front Fog { Mode Off } } } }");
    109.  
    110.         _lineMaterial.hideFlags = HideFlags.HideAndDontSave;
    111.  
    112.         _lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
    113.  
    114.         var filter = GetComponent<MeshFilter>();
    115.  
    116.         var mesh = filter.sharedMesh;
    117.  
    118.         var vertices = mesh.vertices;
    119.  
    120.         var triangles = mesh.triangles;
    121.  
    122.         for (var i = 0; i < triangles.Length / 3; i++)
    123.         {
    124.  
    125.             var j = i * 3;
    126.             var lineA = new Line(vertices[triangles[j]], vertices[triangles[j + 1]]);
    127.             var lineB = new Line(vertices[triangles[j + 1]], vertices[triangles[j + 2]]);
    128.             var lineC = new Line(vertices[triangles[j + 2]], vertices[triangles[j]]);
    129.  
    130.             switch (Fidelity)
    131.             {
    132.                 case 3:
    133.                     AddLine(lineA);
    134.                     AddLine(lineB);
    135.                     AddLine(lineC);
    136.                     break;
    137.                 case 2:
    138.                     AddLine(lineA);
    139.                     AddLine(lineB);
    140.                     break;
    141.                 case 1:
    142.                     AddLine(lineA);
    143.                     break;
    144.             }
    145.  
    146.         }
    147.  
    148.     }
    149.  
    150.  
    151.  
    152.     //****************************************************************************************
    153.  
    154.     // Adds a line to the array if the equivalent line isn't stored already
    155.  
    156.     //****************************************************************************************
    157.  
    158.     public void AddLine(Line l)
    159.     {
    160.         var found = _linesArray.Any(line => l == line);
    161.         if (!found)
    162.         {
    163.             _linesArray.Add(l);
    164.         }
    165.     }
    166.  
    167.  
    168.  
    169.     //****************************************************************************************
    170.  
    171.     // Deferred rendering of wireframe, this should let materials go first
    172.  
    173.     //****************************************************************************************
    174.  
    175.     public void OnRenderObject()
    176.     {
    177.         MeshRenderer.sharedMaterial.color = BackgroundColor;
    178.  
    179.         _lineMaterial.SetPass(0);
    180.  
    181.         GL.PushMatrix();
    182.         GL.MultMatrix(transform.localToWorldMatrix);
    183.         GL.Begin(GL.LINES);
    184.         GL.Color(LineColor);
    185.  
    186.         foreach (Line line in _linesArray)
    187.         {
    188.             GL.Vertex(line.PointA);
    189.             GL.Vertex(line.PointB);
    190.         }
    191.  
    192.         GL.End();
    193.         GL.PopMatrix();
    194.  
    195.     }
    196.  
    197. }
     
  5. diese440

    diese440

    Joined:
    May 25, 2007
    Posts:
    105
    Thanks to Unity 4.0 and new Mesh.SetIndices function (cf : http://docs.unity3d.com/Documentation/ScriptReference/Mesh.SetIndices.html?from=MeshTopology );)

    Here is my new contribution to this thread with just a small script for a wireframe mesh rendering in realtime. It is not finished yet but i want to share it with the community. The nice thing of is this : Adding 0 draw call !

    Code (csharp):
    1. // a simple convertor to WIREFRAME RENDERING at runtime
    2. // Edited by Claude Micheli (aka diese440) nov 2012
    3. //v1.0a works only with Unity => 4.0
    4.  
    5. #pragma strict
    6. //@script ExecuteInEditMode()
    7.  
    8. function Start () {
    9.     ConvertToWireframeMesh();
    10. }
    11.  
    12. function ConvertToWireframeMesh(){
    13.  
    14.     if (!GetComponent(MeshFilter)){
    15.         EditorUtility.DisplayDialog("Wireframe Convertor",gameObject.name+" must have a MeshFilter componnent !","OK");
    16.         return;
    17.     }
    18.    
    19.     if (!GetComponent(MeshRenderer)){
    20.         EditorUtility.DisplayDialog("Wireframe Convertor",gameObject.name+" must have a MeshRenderer componnent !","OK");
    21.         return;
    22.     }
    23.    
    24.     var mesh : Mesh = GetComponent(MeshFilter).sharedMesh;
    25.  
    26.  
    27.     var vertices : Vector3[] = mesh.vertices;
    28.     var triangles : int[] = mesh.triangles;
    29.     var lines : Vector3[] = new Vector3[triangles.length];
    30.     var indexBuffer : int[];
    31.     var GeneratedMesh : Mesh = new Mesh();
    32.    
    33.    for (var t = 0; t < triangles.length; t++)
    34.    {
    35.         lines[t]=(vertices[triangles[t]]);
    36.    }
    37.  
    38.     GeneratedMesh.vertices=lines;
    39.     GeneratedMesh.name = "Generated Wireframe";
    40.    
    41.     var LinesLength : int = lines.length;
    42.     indexBuffer = new int[LinesLength];
    43.    
    44.     var uvs : Vector2[] = new Vector2[LinesLength];
    45.     var normals : Vector3[] = new Vector3[LinesLength];
    46.    
    47.     for(var m = 0; m< LinesLength;m++)
    48.         {
    49.         indexBuffer[m] = m;
    50. //      uvs[m] = Vector2 (GeneratedMesh.vertices[m].x, GeneratedMesh.vertices[m].z);// sets a Planar UV (VERY SLOW)
    51.         uvs[m] = Vector2(0.0,1.0); // sets a fake UV (FAST)
    52.         normals[m] = Vector3(1,1,1);// sets a fake normal
    53.         }
    54.  
    55.     GeneratedMesh.uv = uvs;
    56.     GeneratedMesh.normals = normals;
    57.     GeneratedMesh.SetIndices(indexBuffer, MeshTopology.LineStrip, 0);
    58.     GetComponent(MeshFilter).mesh=GeneratedMesh;
    59. }
    60.  
    You are welcome if you want to help me to finish this script ( how to manage uvs normals properly and how to clean the GeneradMesh...)

    btw have fun with this version,:D
    Claude.
     
  6. patrickt

    patrickt

    Joined:
    Mar 23, 2011
    Posts:
    21
    Here is the Unity 4.0 script switched to C# and with OnEnable and OnDisable functions to toggle the effect on or off. There is also a temporary material for the wireframe render which allows the color to be changed through a simple shader.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3.  
    4. public class WireframeRenderer : MonoBehaviour
    5. {
    6.     Mesh LastMesh;
    7.     Material LastMaterial;
    8.  
    9.     string lineshader = "Shader \"Unlit/Color\" { Properties { _Color(\"Color\", Color) = (0, 1, 1, 1)   } SubShader {  Lighting Off Color[_Color] Pass {} } }";
    10.    
    11.     public void OnEnable()
    12.     {
    13.         var mesh = gameObject.GetComponent<MeshFilter>().sharedMesh;
    14.         var renderer = gameObject.GetComponent<MeshRenderer>();
    15.         LastMaterial = renderer.material;
    16.         LastMesh = mesh;
    17.         var vertices = mesh.vertices;
    18.         var triangles = mesh.triangles;
    19.         var lines = new Vector3[triangles.Length];
    20.         int[] indexBuffer;
    21.         var GeneratedMesh = new Mesh();
    22.  
    23.         for (var t = 0; t < triangles.Length; t++)
    24.         {
    25.             lines[t] = (vertices[triangles[t]]);
    26.         }
    27.  
    28.         GeneratedMesh.vertices = lines;
    29.         GeneratedMesh.name = "Generated Wireframe";
    30.  
    31.         var LinesLength = lines.Length;
    32.         indexBuffer = new int[LinesLength];
    33.         var uvs = new Vector2[LinesLength];
    34.         var normals = new Vector3[LinesLength];
    35.  
    36.         for (var m = 0; m < LinesLength; m++)
    37.         {
    38.             indexBuffer[m] = m;
    39.             uvs[m] = new Vector2(0.0f, 1.0f); // sets a fake UV (FAST)
    40.             normals[m] = new Vector3(1, 1, 1);// sets a fake normal
    41.         }
    42.  
    43.         GeneratedMesh.uv = uvs;
    44.         GeneratedMesh.normals = normals;
    45.         GeneratedMesh.SetIndices(indexBuffer, MeshTopology.LineStrip, 0);
    46.         gameObject.GetComponent<MeshFilter>().mesh = GeneratedMesh;
    47.         Material tempmaterial = new Material(lineshader);
    48.         renderer.material = tempmaterial;
    49.     }
    50.  
    51.     void OnDisable()
    52.     {
    53.         gameObject.GetComponent<MeshFilter>().mesh = LastMesh;
    54.         gameObject.GetComponent<MeshRenderer>().material = LastMaterial;
    55.     }
    56. }
     
    Last edited: Dec 4, 2012
    skyrick likes this.
  7. Divbyze

    Divbyze

    Joined:
    Dec 20, 2012
    Posts:
    1
    I put the gameobject in one of my layers, removed this layer from MainCamera's cullingMask. Great, the object is visible only for the SecondaryCamera. But, when enable "wireframe mode", it becomes shown by both cameras!
     
  8. topofsteel

    topofsteel

    Joined:
    Dec 2, 2011
    Posts:
    999
    Can someone give me a quick rundown of how this is used? Thanks.
     
  9. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    In Unity 4.0 you can just use GL.wireframe and all the above complexity would go away.
     
  10. diese440

    diese440

    Joined:
    May 25, 2007
    Posts:
    105
    Yes Aras you are totally right...

    To perform this with 2 cameras :
    1. have a scene with some GameObjects and a camera
    2. create a new layer (for instance named "wireframe")
    3. set the gameobject(s) to render in wireframe mode in this new layer
    4. now, add a new camera and set is CullingMask to this new layer only (ie : "wireframe")
    5. set the ClearFlag of this camera to "Don't Clear" and set his Depth = the Depth of your first cam...
    6. add the following script to this new camera
    Code (csharp):
    1. #pragma strict
    2.  
    3. // Attach this script to a camera, this will make it render in wireframe
    4. function OnPreRender() {
    5.     GL.wireframe = true;
    6. }
    7. function OnPostRender() {
    8.     GL.wireframe = false;
    9. }
    Et voila. Happy Xmas friends !;)
    Claude
     
    Last edited: Dec 21, 2012
  11. Mz3D

    Mz3D

    Joined:
    Jul 11, 2012
    Posts:
    1
    I tried this script but the line color always remains black, it can't be changed! why?
     
  12. topofsteel

    topofsteel

    Joined:
    Dec 2, 2011
    Posts:
    999
    How is this done exactly. I've tried this script on the gameobject.

    Code (csharp):
    1. gameObject.renderer = WireFrameGameobject;
    I'm just getting back to this after a busy holiday. And how are the cameras supposed to be configured? In the same place? Thank you!
     
  13. diese440

    diese440

    Joined:
    May 25, 2007
    Posts:
    105
    I can be done easy : http://docs.unity3d.com/Documentation/Components/Layers.html

    Yes in the same place (you may just duplicate your first camera...)
    ... and set is CullingMask to this new layer only (ie : "wireframe"),
    then set the ClearFlag of this camera to "Don't Clear" and set his Depth = the Depth of your first cam...
    ;)
     
  14. sama-van

    sama-van

    Joined:
    Jun 2, 2009
    Posts:
    1,734
    Still true under 4.0?
     
  15. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Unity can't change the fact that these platforms (OpenGL ES Flash) just do not have wireframe. It does not exist there.

    So yeah, with Unity 4.0, you still can't render wireframe there. Nor with any other game engine.
     
  16. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Hi Aras.

    Can you confirm if enabling GL.wireframe causes the mesh to be rendered in openGL's immediate mode (ie GL.Begin(GL.LINES); ) or if the mesh is rendered from a buffer on the GPU as per normal rendering?

    Thanks.
     
  17. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    GL_LINES thing is not done automatically. If you enable wireframe, that just does not do anything on OpenGL ES or Flash (it works on all other platforms).

    If you want to render mesh as lines, that works on any platform, then either manually do immediate mode GL.Begin style rendering with GL.LINES, or create a mesh with MeshTopology.Lines topology.
     
  18. TIGGYsmalls

    TIGGYsmalls

    Joined:
    Jan 10, 2013
    Posts:
    38
    Hi, I can only get the Java code to work in my scene. Then I can only Change the Background colour, the Line colour is always black.

    If it worked It's exactly what I want.

    None of the C# works at all. I cant even drag it onto the Inspector without getting an error.
     
  19. juliang

    juliang

    Joined:
    Nov 25, 2008
    Posts:
    98
    Thanks for this. I'm having a strange problem in 4.1.2 though: the buffer doesn't clear, so in a second my window has turned black from all the black lines piling up. This seems like such a given it makes me wonder what's missing? Can it be something else is needed now?
     
  20. diese440

    diese440

    Joined:
    May 25, 2007
    Posts:
    105
    Ok, i don't understand why this not work in 4.1.2, but it is true.
    In order to make it working again you can try this :

    1. have a scene with some GameObjects and a camera (considered as the first camera...)
    2. create a new layer (for instance named "wireframe")
    3. set the gameobject(s) to render in wireframe mode in this new layer
    4. now, add a new camera and set the CullingMask to this new layer only (ie : "wireframe"). (considered as the second camera...)
    5. set the ClearFlag of this camera to "Don't Clear" and set his Depth > the Depth of your first cam...
    6. add the script (from previous post in this page) to this new camera (second camera)
    7. NEW : then select the first camera and remove the new layer (ie : "wireframe") from the CullingMask

    Note modification in item #5 (> in place of =) and the new item #7.
    I did this and it was OK for me with 4.1.2.

    Cheers..;)
     
  21. juliang

    juliang

    Joined:
    Nov 25, 2008
    Posts:
    98
    I went through it again and everything worked fine. Now I think that before I must have been in Play mode, so of course my changes were not getting saved. Thanks again.
     
  22. Exalia

    Exalia

    Joined:
    Aug 14, 2013
    Posts:
    22
    This works thanks, how would this be written in C#?

    and would it be possible to set it up on a button?

    something like

    function OnPreRender() { if (ButtonPress == true) { GL.wireframe = true; }}

    Thanks in advance :)
     
  23. Exalia

    Exalia

    Joined:
    Aug 14, 2013
    Posts:
    22
    As GL.wireframe doesn't work for android I'd like to achieve the same effect can anyone help me out in doing so?
     
  24. Staples

    Staples

    Joined:
    Jan 14, 2009
    Posts:
    224
    Hi all,

    I've been playing around with this using the GL.Lines method and it works quite well, however I want to adjust the background material to accept lighting and also an image texture. How would I modify this shader to do that?

    I've tried setting Lighting to on and a few other things, but the only way I can get lighting to work is with a CG program, but when I do that the ZWrite doesn't seem to work and I get flickering/non-stable lines drawn on the texture (kind of texture fighting).

    Here is the shader I created that doesn't work with lights
    Is there a way to get lighting to work without a CGPROGRAM? Alternatively is there a way for ZWrite to work withinin the CGPROGRAM?

    Any suggestions?

    Thanks
     
  25. reckless_glitch

    reckless_glitch

    Joined:
    Nov 22, 2013
    Posts:
    14
    OK OK I am not up to date, but this might come in handy, the old wireframe script of from page 1
    BUT

    - transforming with the mesh
    - not drawing wireframe twice (double as fast)
    - normals
    - vertex extensions (together with normals gets the mesh nicely furry ;)
    - set up for speed sacrificing memory (6 arrays, less calculation)


    Code (csharp):
    1.  
    2. /*
    3. wireframe update benjamin kiesewetter 2013
    4. faster
    5. normals
    6. vertex extensions
    7. */
    8.  
    9. using UnityEngine;
    10. using System.Collections;
    11.  
    12. public class wireframe : MonoBehaviour {
    13.  
    14.     public bool render_mesh = true;
    15.     public bool render_wiresframe = true;
    16.     public float normal_length = 1f;
    17.     public float vertext_extention_length = 1f;
    18.     public float lineWidth = 1;
    19.     public Color lineColor = new Color (0.0f, 1.0f, 1.0f);
    20.     public Color backgroundColor = new Color (0.0f, 0.5f, 0.5f);
    21.     public bool ZWrite = true;
    22.     public bool AWrite = true;
    23.     public bool blend = true;
    24.  
    25.     public int size = 0;
    26.     public int ignored =0;
    27.    
    28.     private Vector3[] points_a;
    29.     private Vector3[] points_b;
    30.     private Vector3[] vertices;
    31.     private Vector3[] vertex_extensions;
    32.     private Vector3[] normals_center;
    33.     private Vector3[] normals;
    34.     public Material lineMaterial ;
    35.  
    36.     /*
    37.     ████████       ▄▀▀■  ▀▀█▀▀  ▄▀▀▄  █▀▀▄  ▀▀█▀▀
    38.     ████████       ▀■■▄    █    █■■█  █▀▀▄    █  
    39.     ████████       ■▄▄▀    █    █  █  █  █    █  
    40.     */
    41.    
    42.     void Start () {
    43.         if (lineMaterial == null ) {
    44.             lineMaterial = new Material ("Shader \"Lines/Colored Blended\" {" +
    45.                                         "SubShader { Pass {" +
    46.                                         "   BindChannels { Bind \"Color\",color }" +
    47.                                         "   Blend SrcAlpha OneMinusSrcAlpha" +
    48.                                         "   ZWrite on Cull Off Fog { Mode Off }" +
    49.                                         "} } }");
    50.         }
    51.  
    52.         lineMaterial.hideFlags = HideFlags.HideAndDontSave;
    53.         lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
    54.  
    55.         // find vertices
    56.         MeshFilter filter  = gameObject.GetComponent<MeshFilter>();
    57.         vertices = filter.mesh.vertices;
    58.         vertex_extensions = new Vector3[vertices.Length];
    59.  
    60.         // find wire lines and normals by triangles
    61.         int[] triangles = filter.mesh.triangles;
    62.         ArrayList points_a_List = new ArrayList(); //first points of wireframe lines
    63.         ArrayList points_b_List = new ArrayList(); //second points of wireframe lines
    64.         ArrayList normals_center_List = new ArrayList();
    65.         ArrayList normals_List = new ArrayList();
    66.  
    67.         for (int i = 0; i+2 < triangles.Length; i+=3)
    68.         {
    69.             //for rEaDaBiLiTy
    70.             Vector3 a = vertices[triangles[i]];
    71.             Vector3 b = vertices[triangles[i + 1]];
    72.             Vector3 c = vertices[triangles[i + 2]];
    73.  
    74.             /* Make the Lines:
    75.                 evry line may border two triangles
    76.                 so to not render evry line twice
    77.                 compare new lines to existing*/
    78.             bool[] line_exists = new bool[]{false,false,false};
    79.             for (int j=0; j<size; j++){
    80.                 if (points_a_List[j].Equals(a)){
    81.                     if      (points_b_List[j].Equals(b)){
    82.                         line_exists[0]= true;
    83.                     }else if(points_b_List[j].Equals(c)){
    84.                         line_exists[2]= true;
    85.                     }
    86.                 }else if (points_a_List[j].Equals(b)){
    87.                     if      (points_b_List[j].Equals(a)){
    88.                         line_exists[0]= true;
    89.                     }else if(points_b_List[j].Equals(c)){
    90.                         line_exists[1]= true;
    91.                     }
    92.                 }else  if (points_a_List[j].Equals(c)){
    93.                     if      (points_b_List[j].Equals(a)){
    94.                         line_exists[2]= true;
    95.                     }else if(points_b_List[j].Equals(b)){
    96.                         line_exists[1]= true;
    97.                     }
    98.                 }
    99.             }
    100.             // only add lines if they dont yet exist
    101.             if(!line_exists[0]){
    102.                 points_a_List.Add(a);
    103.                 points_b_List.Add(b);
    104.                 size++;
    105.             } else {
    106.                 ignored++;
    107.             }
    108.             if(!line_exists[1]){
    109.                 points_a_List.Add(b);
    110.                 points_b_List.Add(c);
    111.                 size++;
    112.             } else {
    113.                 ignored++;
    114.             }
    115.             if(!line_exists[2]){
    116.                 points_a_List.Add(c);
    117.                 points_b_List.Add(a);
    118.                 size++;
    119.             }
    120.             else {
    121.                 ignored++;
    122.             }
    123.  
    124.             // Make the Normals
    125.            
    126.             //center of triangle
    127.             normals_center_List.Add((a+b+c)*(1f/3f));
    128.             //normal of triangle
    129.             normals_List.Add(Vector3.Cross(b - a, c - a).normalized);
    130.         }
    131.        
    132.         //arrays are faster than array lists
    133.         points_a = (Vector3[]) points_a_List.ToArray(typeof(Vector3));
    134.         points_a_List.Clear();//free memory from the arraylist
    135.         points_b = (Vector3[]) points_b_List.ToArray(typeof(Vector3));
    136.         points_b_List.Clear();//free memory from the arraylist
    137.  
    138.         normals_center = (Vector3[]) normals_center_List.ToArray(typeof(Vector3));
    139.         normals_center_List.Clear();//free memory from the arraylist
    140.         normals = (Vector3[]) normals_List.ToArray(typeof(Vector3));
    141.         normals_List.Clear();//free memory from the arraylist
    142.     }
    143.  
    144.     /*
    145.     ████████       █▄ ▄█  █▀▀▀  ▀▀█▀▀  █  █  ▄▀▀▄  █▀▀▄  ▄▀▀■
    146.     ████████       █▀▄▀█  █■■     █    █■■█  █  █  █  █  ▀■■▄
    147.     ████████       █ █ █  █▄▄▄    █    █  █  ▀▄▄▀  █▄▄▀  ■▄▄▀
    148.     */
    149.  
    150.     private float vertext_extention_length_old = 0;
    151.  
    152.     void update_vertex_extension_length(){
    153.         /* asuming the length of the vertex extensions to barely change
    154.          * only calculate this if really nessecairy,
    155.          * increases memory but should speed up*/
    156.         if(vertext_extention_length_old != vertext_extention_length){
    157.             vertext_extention_length_old = vertext_extention_length;
    158.             for(int i = 0; i<vertices.Length; i++){
    159.                 vertex_extensions[i]=vertices[i].normalized*vertext_extention_length;
    160.             }
    161.         }
    162.     }
    163.  
    164.     private float normal_length_old = 0;
    165.  
    166.     void update_normal_length(){
    167.  
    168.         /* asuming the length of the normals to barely change
    169.          * only calculate this if really nessecairy,
    170.          * increases memory but should speed up*/
    171.         if(normal_length_old != normal_length){
    172.             normal_length_old = normal_length;
    173.             for(int i = 0; i<normals.Length; i++){
    174.                 normals[i]=normals[i].normalized*normal_length;
    175.             }
    176.         }
    177.     }
    178.  
    179.     // to simulate thickness, draw line as a quad scaled along the camera's vertical axis.
    180.     void DrawQuad(Vector3 p1,Vector3 p2 ){
    181.         float thisWidth = 1.0f/Screen.width * lineWidth * 0.5f;
    182.         Vector3 edge1 = Camera.main.transform.position - (p2+p1)/2.0f;  //vector from line center to camera
    183.         Vector3 edge2 = p2-p1;  //vector from point to point
    184.         Vector3 perpendicular = Vector3.Cross(edge1,edge2).normalized * thisWidth;
    185.        
    186.         GL.Vertex(p1 - perpendicular);
    187.         GL.Vertex(p1 + perpendicular);
    188.         GL.Vertex(p2 + perpendicular);
    189.         GL.Vertex(p2 - perpendicular);
    190.     }
    191.    
    192.    
    193.     Vector3 to_world(Vector3 vec)
    194.     {
    195.         return gameObject.transform.TransformPoint(vec);
    196.     }
    197.  
    198.     /*
    199.     ████████       █▀▀▄  █▀▀▀  █▄ █  █▀▀▄  █▀▀▀  █▀▀▄
    200.     ████████       █▀▀▄  █■■   █▀▄█  █  █  █■■   █▀▀▄
    201.     ████████       █  █  █▄▄▄  █ ▀█  █▄▄▀  █▄▄▄  █  █
    202.     */
    203.  
    204.     void OnRenderObject () {
    205.         gameObject.renderer.enabled=render_mesh;
    206.         if (size >  3){
    207.             lineMaterial.SetPass(0);
    208.             GL.Color(lineColor);
    209.            
    210.             if (lineWidth == 1) {
    211.                 GL.Begin(GL.LINES);
    212.                 if(render_wiresframe){
    213.                     for(int i = 0; i<size; i++)
    214.                     {
    215.                         GL.Vertex(to_world(points_a[i]));
    216.                         GL.Vertex(to_world(points_b[i]));
    217.                     }
    218.                 }
    219.                 if(normal_length>0){
    220.                     update_normal_length();
    221.                     for(int i = 0; i<normals.Length; i++){
    222.                         Vector3 center = to_world(normals_center[i]);
    223.                         GL.Vertex(center);
    224.                         GL.Vertex(center+normals[i]);
    225.                     }
    226.                 }
    227.                 if(vertext_extention_length > 0){
    228.                     update_vertex_extension_length();
    229.                     for(int i = 0; i<vertices.Length; i++){
    230.                         Vector3 vertex = to_world(vertices[i]);
    231.                         GL.Vertex(vertex);
    232.                         GL.Vertex(vertex+vertex_extensions[i]);
    233.                     }
    234.                 }
    235.             } else {
    236.                 GL.Begin(GL.QUADS);
    237.                 for(int i = 0; i <size; i++) {
    238.                     DrawQuad(to_world(points_a[i]),to_world(points_b[i]));
    239.                 }
    240.                 if(vertext_extention_length > 0){
    241.                     update_vertex_extension_length();
    242.                     for(int i = 0; i<vertices.Length; i++){
    243.                         Vector3 vertex = to_world(vertices[i]);
    244.                         DrawQuad(vertex,vertex+vertex_extensions[i]);
    245.                     }
    246.                 }
    247.                 if(normal_length>0){
    248.                     update_normal_length();
    249.                     for(int i = 0; i<normals.Length; i++){
    250.                         Vector3 center = to_world(normals_center[i]);
    251.                         DrawQuad(center,center+normals[i]);
    252.                     }
    253.                 }
    254.             }
    255.             GL.End();
    256.         }else{
    257.             print("No lines");
    258.         }
    259.     }
    260. }
    261.  
    262.  
     
    dyupa and jason-fisher like this.