Search Unity

  1. Unity 2020.1 has been released.
    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

Dark back-facing normals while using two-sided shader

Discussion in 'General Graphics' started by Radishface, Nov 8, 2017.

  1. Radishface

    Radishface

    Joined:
    May 4, 2017
    Posts:
    12
    Hello!

    We are currently experiencing an issue with back-facing mesh normals being too dark, regardless of the lighting conditions. The same issue occurs in all the two-sided shaders I could get my hands on (Alloy, UBER, free two-sided shader package, etc.).

    We've also tried different ways of adjusting mesh normals (by projecting them from the dome, perpendicular to the ground, etc.), but seems like it doesn't make much difference. Perhaps this is a Unity issue, and nothing to do with the shaders themselves? We are currently on Unity 5.6.1 but the same issue is present on 2017.2 as well.

    Here's how the mesh in question looks like with UBER two sided shaders (although the same issue occurs with other two-sided shaders):



    And here's how mesh normals look in 3ds Max:



    And here's how the same mesh looks like when imported into Unity, without textures. Notice how dark the back facing normals are:



    I really hope somebody could provide some assistance. I thank you all in advance!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    9,004
    It looks like you're using some post process effects? Try disabling those and see if the issue remains.

    You can also try using the frame debugger and step through rendering to see if the issue presents itself when the grass is initially rendered or later in the pipeline. However I suspect it's a post process effect having a problem due to not overriding the depth normal replacement shader.
     
    Radishface likes this.
  3. Radishface

    Radishface

    Joined:
    May 4, 2017
    Posts:
    12
    Hey, thanks for the reply. Initially, I also thought that it was a post-process effect messing normals up, but disabling all the effects didn't help. I even tried a fresh install of Unity 2017 without any plugins, apart from the UBER and Alloy shader, but the issue still was present. So there must be something else...

    Good suggestion about the frame debugger, I will try and see if that helps.
     
  4. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    289
    does the shader take into account the normal direction? does it look at vface somewhere else maybe or flip/not flip the normal for the backfaces.

    its not just a simple N dot L problem on the back faces?
     
    Radishface likes this.
  5. Radishface

    Radishface

    Joined:
    May 4, 2017
    Posts:
    12
    Thanks for your insight! I've actually gotten in touch with both Alloy and UBER devs regarding the issue, perhaps they will know. I can't wrap my head around their code, since those shaders are powerful and complicated.

    The only workaround I've found so far, is to let Unity calculate normals and tangents for the mesh, but it is not an optimal solution. There has to be a way to use custom normals and two-sided shaders in tandem, just like in other engines.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    9,004
    Aha! I understand the issue now.

    UBER, Alloy, and most two sided shaders are designed to be used on thin, solid objects with the assumption that the vertex normal is aligned to the surface facing. That normal is inverted when viewing the back face so it aligns with the viewed surface. Since you're using a custom normal that in no way relates to the surface that inversion is pointing the normal down, which is clearly not what you want. What you need is an option to do nothing to the normals and just disable back face culling.

    This is a more common practice for "foliage" shaders as the technique of using custom normals is more prevalent for that case ... just like your example.
     
    theANMATOR2b and Radishface like this.
  7. Radishface

    Radishface

    Joined:
    May 4, 2017
    Posts:
    12
    Holy crap, that makes perfect sense! How come I didn't realize this myself? You guys really did it... solved the issue I was having that is. Thank you, really! It was driving me crazy, and yet solution was so simple :D
     
    theANMATOR2b likes this.
  8. AdminArdagor

    AdminArdagor

    Joined:
    Feb 6, 2018
    Posts:
    39
    How did you solve it exactly? Could you please explane? I face the same problem and can't fix it - how did you do it?
     
    M_R_M likes this.
  9. edwardoo22edward

    edwardoo22edward

    Joined:
    Apr 25, 2019
    Posts:
    2
    However I suspect it's a post process effect having a problem due to not overriding the depth normal replacement shader.
     
  10. Gillissie

    Gillissie

    Joined:
    May 16, 2011
    Posts:
    106
    I am also very interested in the exact solution to this. The concept explained by bgolus makes sense, but I don't know how to implement that.
     
  11. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    289
    You need to try and found out where in the pipeline your normals are different than what is expected.
    If its a model thing you can change in the model or have unity import them.
    If its a shader thing and it only works with backface culling but you need custom normals you will have to modify the shader. What you would have to modify would depend on what the problem is and the shader.

    The normal will be calculated in the shader where depends on what kind of shader. So you have the chance to change something. Flip it etc. You can also determine if the face is a front or back side in the shader.

    It sounds like in the previous problem he was using the normals for something other than lighting or doing something special with it. So when the shader was rendering a back face it was probably inverting the normal direction. Because the normals usually come from the front side. And in his case the normals were all pointing up. So when rendering the backface it was negating it and making it point down. Probably away from his light source so it was becoming black.

    If that was the case, he probably just disable the logic to invert the normal for back faces.
    There should be an input semantic vface i think in hlsl for the pixel shader that will tell you which side is being drawn. I think its same for unity.
     
unityunity