Search Unity

Question Fake round edges with Shader Graph

Discussion in 'Shader Graph' started by Passeridae, Feb 25, 2020.

  1. Passeridae

    Passeridae

    Joined:
    Jun 16, 2019
    Posts:
    395
    Hi everyone!

    Is it possible to create fake round edges for hard surfaces using only shader graph?
    Meaning, no additional edges or other pre made geometry.
    Here's an example of what I'm talking about:

    It's widely used in offline renderers (For example, V-ray and Corona both have built-in features for such cases), but seems to be a very hard thing for a game engine to do.
     
  2. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    Not shadergraph but lool at the top answer here: https://stackoverflow.com/questions/25105571/shader-to-bevel-the-edges-of-a-cube

    Do come back and share your progress. I'm interested in this too.

    If it helps I have a piece of the jigsaw:

    1. I can generate meshes from a halfedge data structure (which knows about non-triangular faces
    2. I can use this extra info (whether an edge is "real" or not) and store it in a spare UV channel
    3. I've got a shader graph that can use this info to determine "distance from an edge". I've used this for various effects such as true hidden line wireframe shaders etc.

    I have a feeling that this same edge info could do the bevelling. The normals should be fairly easy but I'm not sure how you'd change the actual profile - i.e. set the opacity of a pixel when viewing a corner from the side so you can see past it.
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    I mean, once you're getting to the point of generating special data for the mesh, you could just generate a normal map that would work even better with a lot less hassle.

    The TLDR version of the original question is no. It is not possible to do with only Shader Graph. It requires data that the GPU does not give to the shaders about the mesh, so this isn't limited to Shader Graph but real time rendering in general, hence why it's not something you see in game engines.

    Many offline renderers can do this because they have full control over what mesh data the renderer does or doesn't have, and information about adjacent faces and their normals are the kind of thing they've choosen to let their "shaders" have access to. Technically you can bake a lot of that information into meshes, as @andybak was alluding to above, but that has to be done using a c# script or in an external application.

    Which again, using a normal map would end up being much easier to implement and faster to render.
     
    M995 and Passeridae like this.
  4. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    As I mentioned above the normals are the easy bit. Whether you generate normal maps in advance or store edge adjacency in the vertices and do it on the fly - this gets you part of the way there (which one is easier probably depends on what else you're doing with your maps).

    The bit I can't wrap my head around is the model's profile. i.e. corners should not look sharp when viewed from the side and edges should be slightly inset.

    Is this actually necessary or would softening the edges with normals be sufficient? It might depend on the amount of bevel and what kind of meshes you're using it on.
     
  5. Passeridae

    Passeridae

    Joined:
    Jun 16, 2019
    Posts:
    395
    Okay, I guess, there's no way around using normal maps or adding some specific information to the geometry itself.

    But what if I have a mesh like this:

    With supporting loops and Curvature values (or at least something that 3Ds Max calls "Curvature" in Data Channel Modifier) baked into Vertex Color.

    Of course, I can just calcaulate normals from angle > 90 in Unity, which gives me exactly what I want:


    Except for one thing: fillet radius is now fixed. It equals the distance between the edge and the supporting loop. And I can't use it per material also, since it affects the whole mesh. Not very useful for meshes with more than one material where onle some of them are supposed to have fake round edges.

    So, I wonder if it's possible to use curvature data from Vertex Color to simulate round edges and get some control over their radius?

    I can use "Normal from Height" node to get some sort of chamfers:


    Now I can (!) control the radius, but it lacks roundness (I get chamfers instead of fillets).

    I can modify Vertex Color in many ways, but I always end up with fillets "protruding" from the surface of geometry (like shown in the screenshot below). Like some sort of planks were attached to the edges of the cube. Or with chamfers. Or with a weird mix of both.


    I can't get nice and even round edges. And of course there are hard edges of the geometry itself visible through the fake ones (I went back to importing normals instead of calculating them from angle before using Vertex Color).

    Is it possible to use this curvature information from vertex colors to create the kind of round edges I want and hide hard edges (at least to some degree) at the same time?
     
  6. KAPOOOW

    KAPOOOW

    Joined:
    Sep 5, 2014
    Posts:
    2
    Hi there!

    I'm actually really interested in that hard edges version of the shader you created in SG. For some reason i'm not able to achieve this with normal from height. Would you please share your file?

    I'm using URP, is this maybe the reason it's not working?

    Thanks a bunch :)