Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Shader To Draw Edges

Discussion in 'Shaders' started by atmuc, Jun 11, 2018.

  1. atmuc

    atmuc

    Joined:
    Feb 28, 2011
    Posts:
    1,125
    I have solid models like chair, table. I want to draw just edges with a shader. I want to write my own shader. What is the idea to draw edges for a shader? I can prepare additional maps with my 3d editor.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,230
    Define what you mean by "just edges".

    Do you mean something like an outline around the object with nothing in the interior, like Unity's scene view selection?

    https://forum.unity.com/threads/free-open-source-outline-effect.314362/

    Do you mean something that draws a line at the normal discontinuities, like an edge detection image effect?

    https://forum.unity.com/threads/image-effect-edge-detect-normals-colours-rel.310280/

    Do you mean the mesh wireframe, like what Unity's selection mode was in the past?

    https://forum.unity.com/threads/free-open-source-generic-wireframe-shaders.473968/

    Lots of different ways to go about all of these kinds of effects.
     
    anonymous-vae and garrettstrobel like this.
  3. atmuc

    atmuc

    Joined:
    Feb 28, 2011
    Posts:
    1,125
    I mean the second example "Do you mean something that draws a line at the normal discontinuities, like an edge detection image effect?"

    this example is screen effect. I need a shader for a geometry. I will change line color and thickness for each game object. I have amplify shader editor. I started to learn this tool and shader commands. I will examine second example's shader code. I am not sure if I can change it to a surface shader.

    I want to learn how to draw just edges with shader commands. I use Modo and Substance Painter. I guess I can create extra texture map to define hard edges. If someone has experience about this, I need his/her help.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,230
    It has to be done as a post process of some kind, or by encoding data into the mesh / special texture before hand.

    The basics of the effect are to find where there are discontinuities in the normals of different surfaces. Shaders by their nature do not know anything about other triangles. There's no way to ask what the normal of the triangle next to them is, so you have to bake this out to a texture.

    The easiest way I can think to do it would be done like the silhouette highlight / outline effect. The short version is:
    1. Render out the surface normals for object(s) you want to outline into a temporary render texture.
    2. Apply edge detection filter using this render texture as the source.
    3. Render outlines back into the scene, or by reading the resulting edge texture in the object's shader.

    You can also do it similar to the wireframe shader, but it would have to be done by storing a "distance to edge" value in the vertices, which gets more complicated than it might initially seam when you have complex shapes. For Planetary Annihilation (not a Unity engine game) I stored the distance to edge in a texture. I actually stored it in the alpha of the albedo as a local space distance to the closest edge.
     
    garrettstrobel likes this.
  5. atmuc

    atmuc

    Joined:
    Feb 28, 2011
    Posts:
    1,125
    Thanks @bgolus I will examine all you wrote. I am new to shaders. I expected more simple way to draw edges. I thought that; with wireframe shader, you draw all edges. If I set some hard edges that will be drawn as a line, in Modo i can write a shader to draw those lines. Afaik I can set vertex values in extra maps. If I can set a weight map for edges, and if I can read those values in a shader, and if there is a shader command that draws lines for those edges, I will be happy :) I will also examine curvature map that baked by substance painter. Maybe this map will help me.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,230
    It's probably more accurate to say in Modo it provides a texture with information about the edges which you can use in a shader to draw the edges from. Unity does not provide this, nor does it have any built in tools for generating it. A curvature map from substance would indeed get something like what you want.
     
  7. ireth_86

    ireth_86

    Joined:
    May 18, 2016
    Posts:
    23
    Hi @bgolus,

    I also need to achieve this result.
    I was somehow able to write the normals on a render texture (following this tutorial).
    But I really don't understand how am I supposed to apply the edge detection filter on a render texture.

    Thanks!
     
    Last edited: May 27, 2020
  8. ArminJohansson

    ArminJohansson

    Joined:
    Jan 8, 2019
    Posts:
    14
    @bgolus I vaguely remember openGl being able to draw lines and verts! Is there any way of drawing lines and verts in unity shaders?
     
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,230
    OpenGL supports line and point rendering, yes. This is something usually defined in the draw, not the shader. Technically the same basic shader can be used by a mesh rendered as triangles, lines, or points as neither the vertex nor fragment shader stages actually care what topology is being rendered.

    To do this in Unity, you can use the
    GL.wireframe
    setting if you want to render objects manually, or you can modify a mesh’s topology to be Lines or Points which can change how it renders.
    https://docs.unity3d.com/ScriptReference/GL-wireframe.html
    https://docs.unity3d.com/ScriptReference/MeshTopology.html

    However native line rendering on most consumer hardware can be stupidly slow. This is intentionally hobbled on consumer hardware so professional GPUs have another advantage.* And it’s not supported by OpenGLES officially. Point rendering on modern desktop GPUs is a mixed bag as well as it’s a feature almost no one actually uses. In both cases either the mesh doesn’t render at all, or renders as a regular triangle mesh... at least it tries to as the data for a line or point topology isn’t usually setup the same as a triangle mesh so you end up with seemingly random triangles.

    Using a mesh with barycentrics data encoded into the vertex colors or an extra UV works on everything and is way, way cheaper.

    (* On some consumer GPUs in the early 00’s you could solder a wire onto your GPU and increase line rendering speeds by 1000%. Now that “wire” is in the chip.)