1
\$\begingroup\$

Need to render something with GL.wireframe, this is what I have at the moment.

void OnPreRender() {
    GL.wireframe = true;
}
void OnPostRender() {
    GL.wireframe = false;
}

However the wireframe rendered is black and this will not work for my game. I've tried adding the following to OnPreRender()

GL.Color (Color.red);

Unfortunately the wireframe remains black. Does anyone know the proper way of changing this color?

\$\endgroup\$
3
  • \$\begingroup\$ As far as I know you'll have to use the full GL.Begin(GL.Lines); approach - GL.wireframe somewhat uselessly has no configurable options at all. \$\endgroup\$
    – Octopoid
    Commented Sep 12, 2015 at 22:05
  • \$\begingroup\$ That's a shame - do you know of any examples using that method? \$\endgroup\$ Commented Sep 12, 2015 at 22:14
  • \$\begingroup\$ I seem to remember there's a good very complete solution for it on the Unity forums - I'll check now :) \$\endgroup\$
    – Octopoid
    Commented Sep 12, 2015 at 22:17

1 Answer 1

3
\$\begingroup\$

Here is a MonoBehaviour written for the express purpose by Benjamin Kiesewetter. It exposes some properties for line colour and thickness and the like.

Relatively speaking quite old now, so not 100% sure it'll work in Unity5 out the box, but it shouldn't be far out if not!

It might be worth adding a [RequireComponent(typeof(MeshFilter))], as it absolutely does require one to work.

/*
wireframe update benjamin kiesewetter 2013
faster
normals
vertex extensions
*/

using UnityEngine;
using System.Collections;

public class wireframe : MonoBehaviour {

    public bool render_mesh = true;
    public bool render_wiresframe = true;
    public float normal_length = 1f;
    public float vertext_extention_length = 1f;
    public float lineWidth = 1;
    public Color lineColor = new Color (0.0f, 1.0f, 1.0f);
    public Color backgroundColor = new Color (0.0f, 0.5f, 0.5f);
    public bool ZWrite = true;
    public bool AWrite = true;
    public bool blend = true;

    public int size = 0;
    public int ignored =0;

    private Vector3[] points_a;
    private Vector3[] points_b;
    private Vector3[] vertices;
    private Vector3[] vertex_extensions;
    private Vector3[] normals_center;
    private Vector3[] normals;
    public Material lineMaterial ;

    /*
    ████████       ▄▀▀■  ▀▀█▀▀  ▄▀▀▄  █▀▀▄  ▀▀█▀▀
    ████████       ▀■■▄    █    █■■█  █▀▀▄    █  
    ████████       ■▄▄▀    █    █  █  █  █    █  
    */

    void Start () {
        if (lineMaterial == null ) {
            lineMaterial = new Material ("Shader \"Lines/Colored Blended\" {" +
                                        "SubShader { Pass {" +
                                        "   BindChannels { Bind \"Color\",color }" +
                                        "   Blend SrcAlpha OneMinusSrcAlpha" +
                                        "   ZWrite on Cull Off Fog { Mode Off }" +
                                        "} } }");
        }

        lineMaterial.hideFlags = HideFlags.HideAndDontSave;
        lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;

        // find vertices
        MeshFilter filter  = gameObject.GetComponent<MeshFilter>();
        vertices = filter.mesh.vertices;
        vertex_extensions = new Vector3[vertices.Length];

        // find wire lines and normals by triangles
        int[] triangles = filter.mesh.triangles;
        ArrayList points_a_List = new ArrayList(); //first points of wireframe lines
        ArrayList points_b_List = new ArrayList(); //second points of wireframe lines
        ArrayList normals_center_List = new ArrayList();
        ArrayList normals_List = new ArrayList();

        for (int i = 0; i+2 < triangles.Length; i+=3)
        {
            //for rEaDaBiLiTy
            Vector3 a = vertices[triangles[i]];
            Vector3 b = vertices[triangles[i + 1]];
            Vector3 c = vertices[triangles[i + 2]];

            /* Make the Lines:
                evry line may border two triangles
                so to not render evry line twice
                compare new lines to existing*/
            bool[] line_exists = new bool[]{false,false,false};
            for (int j=0; j<size; j++){
                if (points_a_List[j].Equals(a)){
                    if      (points_b_List[j].Equals(b)){
                        line_exists[0]= true;
                    }else if(points_b_List[j].Equals(c)){
                        line_exists[2]= true;
                    }
                }else if (points_a_List[j].Equals(b)){
                    if      (points_b_List[j].Equals(a)){
                        line_exists[0]= true;
                    }else if(points_b_List[j].Equals(c)){
                        line_exists[1]= true;
                    }
                }else  if (points_a_List[j].Equals(c)){
                    if      (points_b_List[j].Equals(a)){
                        line_exists[2]= true;
                    }else if(points_b_List[j].Equals(b)){
                        line_exists[1]= true;
                    }
                }
            }
            // only add lines if they dont yet exist
            if(!line_exists[0]){
                points_a_List.Add(a);
                points_b_List.Add(b);
                size++;
            } else {
                ignored++;
            }
            if(!line_exists[1]){
                points_a_List.Add(b);
                points_b_List.Add(c);
                size++;
            } else {
                ignored++;
            }
            if(!line_exists[2]){
                points_a_List.Add(c);
                points_b_List.Add(a);
                size++;
            }
            else {
                ignored++;
            }

            // Make the Normals

            //center of triangle
            normals_center_List.Add((a+b+c)*(1f/3f));
            //normal of triangle
            normals_List.Add(Vector3.Cross(b - a, c - a).normalized);
        }

        //arrays are faster than array lists
        points_a = (Vector3[]) points_a_List.ToArray(typeof(Vector3));
        points_a_List.Clear();//free memory from the arraylist
        points_b = (Vector3[]) points_b_List.ToArray(typeof(Vector3));
        points_b_List.Clear();//free memory from the arraylist

        normals_center = (Vector3[]) normals_center_List.ToArray(typeof(Vector3));
        normals_center_List.Clear();//free memory from the arraylist
        normals = (Vector3[]) normals_List.ToArray(typeof(Vector3));
        normals_List.Clear();//free memory from the arraylist
    }

    /*
    ████████       █▄ ▄█  █▀▀▀  ▀▀█▀▀  █  █  ▄▀▀▄  █▀▀▄  ▄▀▀■
    ████████       █▀▄▀█  █■■     █    █■■█  █  █  █  █  ▀■■▄
    ████████       █ █ █  █▄▄▄    █    █  █  ▀▄▄▀  █▄▄▀  ■▄▄▀
    */

    private float vertext_extention_length_old = 0;

    void update_vertex_extension_length(){
        /* asuming the length of the vertex extensions to barely change
         * only calculate this if really nessecairy,
         * increases memory but should speed up*/
        if(vertext_extention_length_old != vertext_extention_length){
            vertext_extention_length_old = vertext_extention_length;
            for(int i = 0; i<vertices.Length; i++){
                vertex_extensions[i]=vertices[i].normalized*vertext_extention_length;
            }
        }
    }

    private float normal_length_old = 0;

    void update_normal_length(){

        /* asuming the length of the normals to barely change
         * only calculate this if really nessecairy,
         * increases memory but should speed up*/
        if(normal_length_old != normal_length){
            normal_length_old = normal_length;
            for(int i = 0; i<normals.Length; i++){
                normals[i]=normals[i].normalized*normal_length;
            }
        }
    }

    // to simulate thickness, draw line as a quad scaled along the camera's vertical axis.
    void DrawQuad(Vector3 p1,Vector3 p2 ){
        float thisWidth = 1.0f/Screen.width * lineWidth * 0.5f;
        Vector3 edge1 = Camera.main.transform.position - (p2+p1)/2.0f;  //vector from line center to camera
        Vector3 edge2 = p2-p1;  //vector from point to point
        Vector3 perpendicular = Vector3.Cross(edge1,edge2).normalized * thisWidth;

        GL.Vertex(p1 - perpendicular);
        GL.Vertex(p1 + perpendicular);
        GL.Vertex(p2 + perpendicular);
        GL.Vertex(p2 - perpendicular);
    }


    Vector3 to_world(Vector3 vec)
    {
        return gameObject.transform.TransformPoint(vec);
    }

    /*
    ████████       █▀▀▄  █▀▀▀  █▄ █  █▀▀▄  █▀▀▀  █▀▀▄
    ████████       █▀▀▄  █■■   █▀▄█  █  █  █■■   █▀▀▄
    ████████       █  █  █▄▄▄  █ ▀█  █▄▄▀  █▄▄▄  █  █
    */

    void OnRenderObject () {
        gameObject.renderer.enabled=render_mesh;
        if (size >  3){
            lineMaterial.SetPass(0);
            GL.Color(lineColor);

            if (lineWidth == 1) {
                GL.Begin(GL.LINES);
                if(render_wiresframe){
                    for(int i = 0; i<size; i++)
                    {
                        GL.Vertex(to_world(points_a[i]));
                        GL.Vertex(to_world(points_b[i]));
                    }
                }
                if(normal_length>0){
                    update_normal_length();
                    for(int i = 0; i<normals.Length; i++){
                        Vector3 center = to_world(normals_center[i]);
                        GL.Vertex(center);
                        GL.Vertex(center+normals[i]);
                    }
                }
                if(vertext_extention_length > 0){
                    update_vertex_extension_length();
                    for(int i = 0; i<vertices.Length; i++){
                        Vector3 vertex = to_world(vertices[i]);
                        GL.Vertex(vertex);
                        GL.Vertex(vertex+vertex_extensions[i]);
                    }
                }
            } else {
                GL.Begin(GL.QUADS);
                for(int i = 0; i <size; i++) {
                    DrawQuad(to_world(points_a[i]),to_world(points_b[i]));
                }
                if(vertext_extention_length > 0){
                    update_vertex_extension_length();
                    for(int i = 0; i<vertices.Length; i++){
                        Vector3 vertex = to_world(vertices[i]);
                        DrawQuad(vertex,vertex+vertex_extensions[i]);
                    }
                }
                if(normal_length>0){
                    update_normal_length();
                    for(int i = 0; i<normals.Length; i++){
                        Vector3 center = to_world(normals_center[i]);
                        DrawQuad(center,center+normals[i]);
                    }
                }
            }
            GL.End();
        }else{
            print("No lines");
        }
    }
}
\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .