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.

Need tips on creating inline glow shader for 2d polygons?

Discussion in 'Shaders' started by IndieForger, Nov 29, 2017.

  1. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    So here is what I am trying to do. Given irregular polygon (on the left) I would like to be able to create a shader that would resemble Photoshop inline glow effect.


    Creating that effect for 3d is not a problem at all with Fresnel function but finding it hard to do it for a flat surface. I would appreciate any help with that.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    11,929
    Not really possible, not with a shader by itself. A Fresnel "glow" works so easily because the mesh already has data available to use to make the effect, specifically the vertex normal. If you want to do this effect you either need to find a way to add the necessary information to the mesh, or use multiple shader passes.

    The fastest way to do what you want (rendering cost wise) would be to use a Fresnel-like solution and store false normals in the mesh's vertices. Basically "make up" normals based on how close the point is to the edge of the mesh and point them either "up" or away from the center of the mesh depending on how close it is. If you're using the surface normals already you can use the tangents (if you're not using normal maps) or an extra UV channel.

    The next way to do this would be to look at how glow / bloom effects work. The short version is you render your object(s) into a render texture, then with multiple passes blur that texture before displaying it on screen.

    The much slower (again, rendering cost wise) but potentially less complicated method is to use a multi-pass shader with a grab pass. Have a pass in your shader that renders the object using a specific color, a grab pass, then the last shader pass samples multiple points in the grab pass texture and tests for that specific color. Either use the percentage of samples that are that specific color to determine the color you render, or use it to find the closest point not that color to figure out how close to the edge you are. This is a much more difficult shader to write, or to make remotely efficient.
     
  3. vetasoft

    vetasoft

    Joined:
    Nov 15, 2013
    Posts:
    431
    IndieForger likes this.
  4. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    Thanks a lot @bgolus Both solution make sense.

    Am I right thinking normals further from the center should point away and normals closer to the center should point upwards? Seems like something I could do by finding edge vertices and most inner vertices and calculate normals based on their distances.


    Now that sounds really promising but my shader knowledge unfortunately is not nearly enough right now to do that. I will give myself, however, few days to research bit more on that solution and would appreciate any more help and/or tips on how to achieve that.
     
  5. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    Thanks @vetasoft. It is nice and easy approach but it will not work for more irregular shapes like the one below.


    I can't stop thinking that I could achieve it with "Sprite shader" modifying opacity of the image adding inner glow. Do you guys have inner glow option available?
     
    Last edited: Dec 3, 2017
  6. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    Here is an image from I found which is probably the closest to what I am trying to do.
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    11,929
    Yep. Really you only need a single value if you want to make it simple. Store the distance to the closest edge in each vertex. Storing a full "normal" with some directional may behave a little nicer on very low poly meshes if you use the x and y to reconstruct the "z" in the shader, but this will be more fresnel like rather than having a constant edge glow width.

    That's going to require something along the lines of the render texture approach I described above, or some pre-calculated vertex data (UVs, normals, something else), or actually literally using Photoshop to create an inner glow. A sprite shader can (with a fairly expensive shader) do a glow because it has a texture with alpha edges that can be sampled in the shader. With just a mesh you don't have that data available, so you have to generate it somehow, at which point why not just store it in the vertex data to begin with.

    My best guess is that's being done using a low resolution distance field render texture. Render some basic gradient shapes into a very small render texture using BlendOp Max, sample in the shader using bicubic filtering, apply edge color based on distance. Looks too smooth to be purely mesh based.
     
    Last edited: Dec 3, 2017
  8. vetasoft

    vetasoft

    Joined:
    Nov 15, 2013
    Posts:
    431
    upload_2017-12-3_22-39-55.png

    We are just working on it and should be release tomorrow.
    We will also add color change and size and light intensity.

    I guess it's what you need ? :)
     
  9. vetasoft

    vetasoft

    Joined:
    Nov 15, 2013
    Posts:
    431
    Showing how we did the shader :

    upload_2017-12-4_9-13-22.png
     
    IndieForger likes this.
  10. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    Ok now that looks like something I could use. Forgive if my question is bit lame but would that work for any 2d mesh rendered at runtime? I noticed you guys pass a texture into "Source New Texture". In my case I have a 2d mesh that HAS NO texture on it. The input would be mesh itself (that changes at run-time), color and alpha.
     
  11. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    11,929
    No. Like I said before, that system explicitly works on textures, not arbitrary polygon shapes. I know @vetasoft is trying to be helpful here, but I think they’re giving you a bit of false hope. To use their stuff you’d have to have a sprite of the shape rather than using the mesh. Assuming these shapes are dynamic, that means render textures.
     
  12. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    Thanks @bgolus. Appreciated. Looks like I am going to (try to) roll with one of your suggested methods.
     
  13. vetasoft

    vetasoft

    Joined:
    Nov 15, 2013
    Posts:
    431
    Maybe with a rendertexture,

    With another camera and a Render Texture it's look like this.

    rendertexture.gif

    upload_2017-12-8_8-56-18.png
     

    Attached Files:

    bgolus likes this.