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

double sided material

Discussion in 'General Graphics' started by voxelpusher, Jun 7, 2017.

  1. voxelpusher

    voxelpusher

    Joined:
    Jun 7, 2017
    Posts:
    1
    Modeling some palm trees and was wondering if its possible to have a standard shader with a double sided material?
     
  2. TeohRIK

    TeohRIK

    Joined:
    Jan 22, 2014
    Posts:
    106
    You can't. You need to write your own shader for double sided or you can use this asset
    http://u3d.as/9AN
     
  3. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    From my understanding on this subject - it is better (less overhead) to have an actual double sided mesh, with polygons facing forward and back.
    This is a pretty simple 'fix' to add back side polygons. Duplicate polys, flip normals and weld verts if needed.

    Might want to research if optimal performance is import to the application.
     
    rogodoy likes this.
  4. JonPQ

    JonPQ

    Joined:
    Aug 10, 2016
    Posts:
    120

    any idea why ?... it seems like the opposite would be true... twice as many polygons to send to the renderer (extra overhead), twice as many polys to do backface cull checks on (extra overhead). and same number of pixels displayed on screen.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    There are plenty of double sided Standard shaders on the asset store, and I and others have posted several examples of how to implement it, either using two passes or one pass. There are pros and cons to both methods.
     
    TheBraxo and theANMATOR2b like this.
  6. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    From limited research more polygons are faster math than a double sided shader that commonly require an additional render pass. But I would defer to bgolus knowledge - since I believe the info I gathered included original posts authored by him. ;)
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    There's basically three ways to do double sided.

    1. Manually doubling the geometry in the mesh with flipped normals has the benefit of potentially reducing draw calls as the mesh is only rendered once. It also means it can be easily batched with "single sided" geometry. Yes it doubles the vertex count, but that's not usually a limiting factor when it comes to rendering performance unless you're using rediculously high poly geometry, or on seriously old hardware or doing VR on mobile.

    2. Two pass shaders are nice for transparent objects like glass cups as you can guarantee the order the order of rendering. Basically you generally want the inside to render before the outside so they visually sort nicely, and you can get this with method 1 too if you control the triangle order carefully, but that's not something easily exposed in a lot of modeling tools. However this is still doubling the rendered geometry so all of the negatives of option 1 still exist with basically none of the benefits.

    3. Single pass shader with culling off and using VFACE to flip the normal. This is the method I use the vast majority of the time, and is by far the fastest as it doesn't double the geometry and requires very little shader work to implement. If you're using a single texture for both sides there's no reason not to use this option apart from most people don't seem to know about it. Some people do something similar by using a dot product between the surface normal and the view direction, but this method both produces wrong results and is much more expensive!


    Other notes on option 2: As of Unity 5.6 they've changed the way multi-pass shaders are handled. It used to be when multiple objects using multi-pass materials were rendered they'd work like this:

    Object 1, Pass 1
    Object 1, Pass 2
    Object 2, Pass 1
    Object 2, Pass 2

    Now they can render like this:

    Object 1, Pass 1
    Object 2, Pass 1
    Object 1, Pass 2
    Object 2, Pass 2

    It's a subtle change, but it means in the common case of rendering a glass cup with a two pass material if there are two cups that overlap it'll render the "inside" of both of them, then the "outside" causing the outside of one glass to appear between the inside and outside of the other, where as before they would appear properly as separate cups. This updated behavior is more efficient for rendering as it'll allows for better batching, but it makes option 2 even less desirable. Going forward in cases where I might have used option 2 I'll likely try to use option 1 or 3.


    For opaque or alphatest objects there's almost no reason not to use option 3. The one case where it might not be the best option is if you're targeting a very old OpenGL ES 2.0 device and want a different to show texture on each side. On that device it might be faster to render twice the geometry with a simplier shader (one that doesn't have to read both textures and switch between them), but probably not.

    For transparent transparent objects none of the options are really perfect, though options 1 and 2 can sometimes be better than option 3.

    For soft edged but still partially opaque objects, like hair, trees, grass, etc. I still use option 3, but pair it with a "pre ZWrite" pass. Search the forums for a double sided standard shader for hair I posted that does this. Yes it doubles the geometry, but you can get proper sorting on the parts that are opaque and still get the soft edge of the alpha.
     
    Last edited: Jun 8, 2017
  8. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Does this also render correctly the lighting/shadow information on the bottom side of the mesh - like a leaf?
    Before moving on with other research - I found people experienced issues with one widely distributed double sided shader. The best example I remember was the leaf example. It was expected the leaf would be shaded on the bottom side, but instead was receiving the same lighting/shadow shading as the top side of the leaf.
     
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    That's what VFACE is for, it's a value passed to the fragment shader that says if it's the front or back side of a triangle you're viewing, and you can use that to flip the normal.

    https://forum.unity3d.com/threads/s...y-shiny-on-the-underside.393068/#post-2574717
     
    ezerai and theANMATOR2b like this.
  10. DerDicke

    DerDicke

    Joined:
    Jun 30, 2015
    Posts:
    291
    Old, but still a problem. Using GUI/TextShader in my Material solved it for me without the pain.
     
  11. nasos_333

    nasos_333

    Joined:
    Feb 13, 2013
    Posts:
    13,290
  12. skii7nix

    skii7nix

    Joined:
    Jun 2, 2020
    Posts:
    1
    This might be resurfacing an old thread, but to add a texture to both sides of a flat object for me, I just changed the rendering options for the material and set "Cull" to off. Seemed to work great for my application.

    With Cull disabled: https://prnt.sc/swvdga
    Without Cull disabled: https://prnt.sc/swve4k
     
    ericksm703 and capocchione like this.
  13. farhanWorkinman

    farhanWorkinman

    Joined:
    Apr 9, 2021
    Posts:
    4
    Set Render Face to Both in your material. Both side with be rendered :)