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

Question Is this edge falloff effect possible through shaders, or will it need textures

Discussion in 'Shaders' started by Maldruzard, Aug 12, 2020.

  1. Maldruzard

    Maldruzard

    Joined:
    Oct 26, 2014
    Posts:
    16
    Hi there!

    I have a script that dynamically generates an aiming 'cone' for a player's ability, basically just a flat mesh of variable shape / size that shows an area where actions can happen.

    For the appearance, I'm after something like this and this, where the aiming cones of effect have that bright / solid colour at the edges, then have a falloff linearly away from the edges. While I understand that this would be quite easily possibly in a circular / spherical shape, I'm coming up empty in my research of finding a way to do this purely through a shader for non-circular shapes like the aiming arcs shown in those images.

    Will I just need to just a texture instead? I'm not sure how I could create a texture for aiming arcs like these that can change shape / size very dynamically...

    Any help would be much appreciated to point me in the right direction!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    It's entirely possible to do with only shaders and no textures. I wrote an article on doing circular & arc progress bars that could be adapted to do exactly what you're looking for.
    https://medium.com/@bgolus/progressing-in-circles-13452434fdb9

    The final shader presented at the end uses no textures. The outline can be changed to use a fixed multiplier for the interior rather than screen space derivatives so it's not a sharp edge.
     
  3. Maldruzard

    Maldruzard

    Joined:
    Oct 26, 2014
    Posts:
    16
    Wow, that is an incredibly helpful article. I will see if I can extract and adapt the techniques you've used here for the effect that I want. Thanks so much for the quick and helpful response!
     
  4. Maldruzard

    Maldruzard

    Joined:
    Oct 26, 2014
    Posts:
    16
    It has become rapidly clear that this may be slightly beyond my pay-grade haha! I think I somewhat understand that its there is an SDF that works out the distance from the edges of the arc, but I'm not clear on how I can adapt this to work with my generated polygon shape. As far as I can tell, are the distance fields not calculated based on this being a circular shape?
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    The shader doesn't know or care about the shape of the mesh. It's based purely on the UV position. The examples in that article using a SDF are all on a default Unity quad, and calculating a circle centered around the UV position (0.5, 0.5). The caps of the arc are also rotated around that same (0.5, 0.5) center.

    Using a generated mesh shape is fine, just make sure the UVs are aligned so the "center" is where the view point is, or offset that center in the shader.
     
  6. Maldruzard

    Maldruzard

    Joined:
    Oct 26, 2014
    Posts:
    16
    So I can wrap my head around how it calculates a circle as its just a simple distance/radius from that central position I think, I'm just bashing my head against the wall trying to understand how this can be applied to achieve the edge effect for the shape shown in my first post's example. I apologise for my lack of understanding, I'm very new to shaders!

    If it isn't too much to ask, could you perhaps give me a very simple explanation for how this would be adapted, for example, just for say a square shape rather than the circle? Even if its just a really basic explanation, I'd really appreciate it :)
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    That is all a circle is, a distance from a position. The final shader presented in that article has a
    circleEdge
    that's the outer edge of the entire shape, and a
    outlineEdge
    that's the inside edge of the outline. That
    outlineEdge
    is using a
    smoothstep
    and +/-
    radialGradDeriv
    which is the screen space derivative (how much it changes between one pixel and the next) to do sharp anti-aliasing. You can change the
    outlineEdge
    's
    smoothstep
    to use
    0.0, 0.1
    for the first two parameters instead of radialGradDeriv to get a fade.
     
  8. Maldruzard

    Maldruzard

    Joined:
    Oct 26, 2014
    Posts:
    16
    I believe its possible there may have been a misunderstanding / we are at cross purposes here, unless my tired brain is completely getting the wrong idea. In my initial post, I had more meant that I wanted to be able to use my generated mesh's edges to create the faded edge effect shown in the images - the aiming cone is not always circular, and can be all sorts of scales / shapes, so I was after a shader that would hopefully allow me to do the kind of outline effect you've shown, just around all edges of the mesh. As far as I can tell, the technique shown in your shader is used to render circular arcs with outlines, which would be perfect if I was just using circular / circular arc aiming shapes but unfortunately doesn't work for my use-case (I think, please correct me if I'm wrong).

    I can definitely now see from the phrasing of my initial question how it could have seemed like that was what I was after though, so I apologise for the confusion! I will continue to try regardless, and while researching into the SDF stuff from your article I did come across some potentially interesting stuff from Inigo Quilez here that looks like it creates a dynamic SDF for a polygon of N points, perhaps it can be applied to unity too
     
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Ah. Yeah, I understand what you wanted now.

    No, don't do that.

    That arbitrary polygon SDF is certainly tempting, but it's more a curiosity / fun exercise than something you'd ever want to use.

    Shaders don't know anything about the mesh as a whole. It knows about a single vertex at a time, or a single pixel and the interpolated values at that position. There's no way for a shader to know where the edge of the mesh is... unless you encoded data in the mesh that represents that.

    The cheapest way to do that would be to encode the distance to edge in the mesh data itself, like using a UV channel or vertex colors. But to do that correctly requires cutting up your mesh the right way, at which point you might as well just build the outline into the mesh via vertex colors.

    The advantage of something like my shader could be used to cheaply create arc shapes without needing any special geometry. Just slap a quad in the scene and adjust as you want. If you want to confine the mesh coverage more tightly so there's less overdraw, then create a triangle or rounded wedge shape, but let the shader do the heavy lifting of making the smooth shape. If you need other shapes than an arc / circle, then use a shader that makes the shape you want.

    The arbitrary polygon shader handles cases you'll likely never need to deal with, like intersecting geometry. But combinations of the other examples are likely more in line with what you want.
     
    Last edited: Aug 12, 2020
  10. Maldruzard

    Maldruzard

    Joined:
    Oct 26, 2014
    Posts:
    16
    Haha I appreciate the warning!

    Thanks for the followup, I'll look into the different options you've discussed and see what works for me the best. I'm not overly concerned about performance at this point as this will be a very sparingly used effect, but its always good to know the best way of doing things regardless. Definitely bookmarking that article and shader for future use too!

    Cheers :)