Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Resolved LWRP Outline Shader (Help Needed)

Discussion in 'Shader Graph' started by BIGO89_, Jul 15, 2019.

  1. BIGO89_

    BIGO89_

    Joined:
    Jul 31, 2017
    Posts:
    10


    Hey guys, i posted this on unity3d reddit but got no response yet :( so i'll try it over here. Here is the post:


    I'm creating a lwrp shader to make outlines for my meshes since lwrp don't support additional passes.

    The shader is set to transparent + multiply + double-sided so i can set the faces white when front faced and a property color when back faced. I could not find a way to just cull the front face in shader graph :(

    I think there might be a way to make this more simple and performante, I've been trying to achieve this solution for some time and this is the best i could get right now!

    Hope it helps somebody! And somebody could help me making this better.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    9,842
    A few thoughts:

    First, you want to use the vertex position depth, not distance. It's a subtle difference, but should keep the line width more consistent for wider FOVs. Use the absolute of the view space position z instead of the distance between the camera and the world position.

    I would set the alpha with the Is Front Face branch between 0 and 1 to hide it rather than using white and black with multiply. This will effectively cull the front faces, and while not as efficient as directly setting Cull Front, it should be better than You might need to set the Alpha Threshold value to 0.5 with a Vector1 instead of leaving it as the default since Shader Graph doesn't seem to like to enable alpha testing unless the threshold actually has a node connected.

    While multiplying by the depth (or distance) will indeed ensure the lines stay constant width regardless of depth, they will scale with FOV changes. If you want to keep the lines constant width regardless of FOV then you'll want to divide by the fov, which you can extract from the projection matrix.

    upload_2019-7-15_15-32-22.png
     
  3. BIGO89_

    BIGO89_

    Joined:
    Jul 31, 2017
    Posts:
    10
    @bgolus Thank you for the in depth response man! Really appreciate that :)

    Just one question, in your setup the shader is still set to transparent, with this method you proposed can i use it as opaque instead? (i'll test it out here)

    Another thing: I was watching a video here about creating a custom forward renderer and add a pass with a material to be added. But customizing the forward renderer here in my Unity is not working.. i click the plus sign to add a pass but nothing happens.. is it a problem with my editor or they blocked this feature for now?

    Again, thank you very much :}
     
  4. BIGO89_

    BIGO89_

    Joined:
    Jul 31, 2017
    Posts:
    10
    PS: it worked ok with surface set to Opaque and Blend to Alpha!
     
    Acre94 likes this.
  5. BIGO89_

    BIGO89_

    Joined:
    Jul 31, 2017
    Posts:
    10
    PS: Solved the Custom Forward Renderer updating my LWRP package. It was 5.7 by default, i clicked to show all the version on the package manager and upgraded it to 5.16.1 and it solved the problem (upgraded both LWRP and the shaderGraph)
     
  6. BIGO89_

    BIGO89_

    Joined:
    Jul 31, 2017
    Posts:
    10
    The only problem now, as i see it, is been unable to set the shader to proper Culling the front faces.. and it's a basic feature to be implemented i think.
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    9,842
    Yes. Either transparent or opaque works.

    Note: once you choose opaque, the Blend mode is ignored, so that setting no longer matters.

    Yep, having more control over the render state would be really nice and is a feature asked for frequently. AFAIK it's not something they've started working on yet, but is on their list. Might not show up until 2020, or ever, but it is on their list. :p

    Btw, I honestly have no idea what you're referring to here.
     
  8. BIGO89_

    BIGO89_

    Joined:
    Jul 31, 2017
    Posts:
    10
    Hey @bgolus , thanks again man

    Yeah hahaha will wait for it.

    This is what I mean:

     
  9. BIGO89_

    BIGO89_

    Joined:
    Jul 31, 2017
    Posts:
    10
    Btw, you mentioned that either transparent or opaque should work, and they do. But isn't it better to put it on the Opaque pass? Or it does not matter much? Thanks
     
  10. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    9,842
    Ah, nice. I hadn't seen that feature before.

    There's different benefits to both. Using opaque ensures it sorts properly with other objects, but unintuitively that's not always what you want. For example if you have any transparent effects on or around the character, it may visibly clip through the outline in some places. Using transparent will prevent them from clipping each other, ie: other transparent effects will always be completely behind the outline or completely on top which may better match the look you want. It might also look worse if you have larger effects, so you might try both options.

    Also the use of the alpha threshold to "cull" the front faces is slightly faster when using transparent than using opaque, but only really meaningfully so on mobile.
     
  11. BIGO89_

    BIGO89_

    Joined:
    Jul 31, 2017
    Posts:
    10
    That's great info man, can't thank you enough @bgolus !
     
  12. adrian-taylor09

    adrian-taylor09

    Joined:
    Dec 22, 2016
    Posts:
    40
    Hey there, thanks for posting this.

    I'm trying to replicate your effect in Shader Graph but I'm having some issues. I'm finding that for smooth objects (sphere, capsue) this works fine, but for hard edged surfaces there seems to be a gap at the edges (see bottom corners of cube bellow)?
    outline.png
    Here is my shader graph in case you spot something I've missed:
    outline graph.png
     
  13. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    9,842
    You’re not missing anything, that’s just how the effect works. Anything with hard edges will result in a gap in the outline.

    If you follow through what the code is doing, it makes sense. The vertices are being pushed out by their normal. When there is a hard crease in the normals, the edge will separate when pushed in those directions.

    There are a few solutions:
    1. Don’t use hard edges. At least not in the actual mesh used. If you’re using normal maps you can use hard edges in the high poly model, but not the lower poly one. If you’re not using normal maps, you can connect the hard edges with filler geometry, and there are tools to help keep the major faces flat. For example, something like this:
    http://www.scriptspot.com/3ds-max/scripts/improved-face-weighted-normals

    2. Store two sets of normals in the mesh data, one with hard edges, omg with smooth edges. Usually you have to do this in the editor as it’s not something external modeling tools are good at handling, and Unity won’t always import correctly depending on how you want to do it. There are a couple of assets on the store that do this, like Toony Colors Pro 2, which stores the smoothed normal in the mesh’s tangent. This only works if you don’t need normal maps, since that’s what the vertex tangent is for normally, but it has the advantage of getting transformed properly in skinned meshes. There are ways around this limitation, but they don’t work with Shader Graph. Alternatively you can store the smoothed normal in the vertex color or extra UVs, which still works with normal mapping.

    3. Don’t use the mesh normals, just scale the entire mesh up. Works well enough for simple mostly convex shapes like boxes and spheres. Fails horribly on everything else.
     
  14. adrian-taylor09

    adrian-taylor09

    Joined:
    Dec 22, 2016
    Posts:
    40
    Thanks for the detailed reply. Makes sense now that you’ve explained it.

    that max script look awesome, gonna try that out for sure.
     
  15. whoisj

    whoisj

    Joined:
    Jan 4, 2018
    Posts:
    26
    Another approach that has worked for me in the past is to add a custom pass to a custom forward renderer.
    Have the pass execute before post processing.
    The renderer itself creates a full screen quad that occludes the entire field of view, and applies a material to it.
    The material will use the scene depth to find the edges between surfaces.
    When the difference is large enough, draw the outline color, otherwise draw the scene color.

    Now the entire scene is outlined nicely. You can something similar with world-space normals as well if you want geometry outlining.
     
    TheSmokingGnu likes this.
unityunity