Search Unity

Unity 5 Fade Render mode Sort Order issue

Discussion in 'Shaders' started by CatDixon, Apr 13, 2015.

  1. CatDixon

    CatDixon

    Joined:
    Sep 17, 2014
    Posts:
    4
    Hi there,

    I'm having some ugly sort order problems with the render Fade mode in the unity 5 standard shader. When it is opaque I can see various interior faces related to sorting issues, but does still fade out completely. (Ive also tried Transparent, it has the same sorting issues)

    I have some slightly fancy gears/cogs, that have centrally located sensible pivots that cant be changed. I dont have time to break the items up because of the time it would take, and eventual issues with draw calls given the volume and complexity of the scenes.

    I have a old non pbr shader that I transitioned with my project from 4 that works fine, but I moved to 5 to push the visual quality forward.

    If anyone can help I'd be very grateful, if an old shader can do it I'd really hoped that the new ones would cope fine.

    Apologies if anyone else has had the same issue I cant find anyone posting with the same issue
     
  2. silentslack

    silentslack

    Joined:
    Apr 5, 2013
    Posts:
    395
    I have the same issue - did you solve?
     
  3. UnityGuillaume

    UnityGuillaume

    Unity Technologies

    Joined:
    Mar 16, 2015
    Posts:
    123
    It's actually the same problem than here : http://forum.unity3d.com/threads/st...esnt-display-correctly-on-rigged-mesh.313786/

    Long story sort it's a limitation of transparency sorting. I guess your "old" shader was writing to depth (which create huge problem when fading in front of other transparent object, like fog, particles etc...but could be acceptable in your particular case). But since it's a corner case, Fade don't set it. We could maybe put a tickbox to enable zWrite though indeed.


    You'll have to set zwrite manualy throught a script. Just do :

    Code (CSharp):
    1. theMaterial.SetInt("_ZWrite", 1);
    theMaterial being a reference to your material with the "fade" mode.
     
    harunucan, Semilhas and CatDixon like this.
  4. Cascho01

    Cascho01

    Joined:
    Mar 19, 2010
    Posts:
    1,347
    Yes please!
     
  5. ArchVizPRO

    ArchVizPRO

    Joined:
    Apr 27, 2014
    Posts:
    457
    it try with this script:

    var myMaterial = GetComponent.<Renderer>().material;
    function Start () {
    myMaterial.SetInt("_ZWrite", 1);
    }
    function Update () {
    }

    But i still get trasparency not work with DOF.
    How to have a standard shader (transparent) to work correct with DOF ?
    Please i realy need it.
    Thank you
     
  6. UnityGuillaume

    UnityGuillaume

    Unity Technologies

    Joined:
    Mar 16, 2015
    Posts:
    123
    Well that become a LOT harder and not sure it's possible.

    Reason :

    - DOF rely on the DepthTexture from the camera. And that DepthTexture is resolved (saved to a texture to be used in other shader) BEFORE the translucent pass. So even with ZWrite on, the depth buffer have the object drawn into it, but the depthtexture don't have it, so for DOF the object don't exist

    - if you move the translucent object to a queue BEFORE the transparent one (before 2500) then it "erase" the skybox (skybox are drawn after opaque pass to save a lot of fillrate)

    So I don't see any solution to that =/ Apart writing a very shader that render depth into a texture AFTER the translucent pass and bind that to the _CameraDepthTexture (maybe this can be done with a COmmandBuffer actually, look at doc)
     
  7. vargata

    vargata

    Joined:
    Nov 26, 2013
    Posts:
    120
    ok, i have the same problem. if i set a shader transparent with cull off zwrite off, the effect looks good, i can see both side of the translucent object, but if there is an opaque object inside, there is a sorting problem. if i set zwrite on, there is no sortorder problem but i cant see the backfaces of the translucent object. it was working perfectly with 4x shading. could we have it back as a legacy option?
     
  8. UnityGuillaume

    UnityGuillaume

    Unity Technologies

    Joined:
    Mar 16, 2015
    Posts:
    123
    Well all legacy shader are still here, in the Legacy Shader submenu of the shader dropdown selection.

    But that it worked with 4.x shader is strange, as all that sorting problem was still there... If you have a repro scene I would be curious to see that to understand what is happening!

    Got a screen of the problem of the opaque mesh inside a transparent mesh ? As the opaque one write into the depth buffer, it should have any sorting problem
     
  9. vargata

    vargata

    Joined:
    Nov 26, 2013
    Posts:
    120
    i know the legacy shaders are there, i was more talking about the old way of alpha shading in custom surface shaders. sadly i've udated all my old files but in u4x when i had this very same shader with #pragma surface surf Lambert alpha, if i put an opaque object inside a semitransparent and i set the alpha to 100%, then the semitransparent object completely covered the opaque, but if i pushed the alpha down, looking through the semitransparent object i saw both the front and backside of it as well as the opaque object inside. now if i push the alpha on the transparent object to 100% i can still see the opaque object inside (just its edges, but still, it can be seen). if i try to solve it with zwrite on, then this problem goes away, but in exchange i cant see the effects on the backside of the transparent object :/
    this is how it looks now with alpha:fade cull and zwrite off.
     
  10. UnityGuillaume

    UnityGuillaume

    Unity Technologies

    Joined:
    Mar 16, 2015
    Posts:
    123
    Hum the effect on the video is the "correct" one (The depth buffer contain the opaque geometry, part behind it are cliped, hence never blended, that's the expected behaviour).

    What is strange is that legacy apha blending did work, it shouldn't have...The only reason I can think of why it wasn't doing that effect was if ZTest was off. That way back-face would have been drawn on top of the already present geometry. But that also mean your shield would be visible through walls that are between the camera and the shield...
     
  11. vargata

    vargata

    Joined:
    Nov 26, 2013
    Posts:
    120
    how would this be correct? a transparent object with 100% alpha should be opaque and whatever is inside or behind shouldnt be visible... and thats how it was working in u4x and it wasnt visible behind other objects
     
    Harinezumi likes this.
  12. CatDixon

    CatDixon

    Joined:
    Sep 17, 2014
    Posts:
    4

    Hi UnityGuillaume,

    Thanks for the reply. We've added Zwrite into the shader, it seems to work fine for how I need it! Thanks!
     
  13. UnityGuillaume

    UnityGuillaume

    Unity Technologies

    Joined:
    Mar 16, 2015
    Posts:
    123
    The problem you have is a classic translucent ordering problem :

    alpha (or new alpha:fade) does alpha blending, which mean the formula :

    colorInBackBuffer * (1 - drawnAlpha) + drawnColor * drawnAlpha

    But there is no way to order triangles drawing, as it depends on the (fixed) index buffer.
    So even with 100% alpha, if the backface are drawn after the front face, the formula is

    frontFaceColor * 0 + backfaceColor * 1

    so your backface appear in front, even if the object have a 1 alpha. If some mesh (e.g unity cube) don't seems to have this problem, it's because back face are culled (there is no duplication of vertex/normal, nor is cull disabled in the shader), so they never even get drawn.

    What seems to happen in your video is : where there is no opaque object, backface are drawn after front face, "overriding"
    them, but fail ztest where the opaque geometry is, so the "front face" are visible in those place.

    What seems to validate that theory is the effect is visible even in part when the opaque geometry is not :
    (circled in red the palce where the opaque geometry is, and in blue part where the problem is too)

    sorting.png

    That's because that blue part is drawn AFTER the part behind, so the front face override the backface. I'm pretty sure that even if you remove the opaque object from inside the sphere, problem will persist on part of it (and it should disappear at 50% translucency, as the two part, whatever the order they are drawn, will be mixed 50/50)

    Now why it wasn't working like that in 4.x is a mystery =x Maybe something different was happening, I may be wrong on all that, I'm not into every change that happen in the renderer =/ But translucency on concave objects in 3D is hard =(
     
  14. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    472
    Is it possible to have the Standard shader render a non-convex Combined Mesh with 5 materials in Fade mode with ZWrite 1 and not see any overdraw in that combined mesh, but only the faces that would render in Opaque mode? I have tried this by setting the mode to Fade for all 5 materials and then setting _ZWrite 1 for all 5 materials, but I am seeing faces that should be hidden by faces on the same object that are closer to the camera.

    Do I need to alter the Standard shader to do a ZWrite pass before all the other passes, for this effect, as in Shader "Transparent/Diffuse ZWrite" on Unity/Editor/Data/Documentation/en/Manual/SL-CullAndDepth.html?
     
  15. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    472
    I tried the "Transparent/Diffuse ZWrite" shader, and it has the same problem of showing faces that should be hidden by faces closer to the camera, at least with a Combined Mesh and multiple materials.

    What's the simplest way to have all the materials do a z write on all faces of a Combined Mesh? Or, is there is another technique that could render the same faces as the Opaque Standard shader, but be transparent with respect to other objects behind it in the scene?
     
  16. Bunzaga

    Bunzaga

    Joined:
    Jan 9, 2009
    Posts:
    202
    I ran into a similar issue, as all of the above. The only way I was able to get the results I wanted, was to modify the standard shader to have ZWrite On in the Base forward pass, set the Material to Opaque in the editor, and then manually change the material of the objects I wanted like so:

    Code (csharp):
    1.  
    2. ZWrite On ZTest LEqual
    3.  
    Code (csharp):
    1.  
    2. Material mat = (UseSharedMaterial ? r.sharedMaterial : r.material);
    3. mat.SetFloat("_Mode", 2);
    4. mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
    5. mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    6. mat.SetInt("_ZWrite", 0);
    7. mat.DisableKeyword("_ALPHATEST_ON");
    8. mat.EnableKeyword("_ALPHABLEND_ON");
    9. mat.DisableKeyword("_ALPHAPREMULTIPLY_ON");
    10. mat.renderQueue = 3000;
    11.  
    After I was done messing with the alpha, and wanted it to be opaque again, I reset it back:
    Code (csharp):
    1.  
    2. mat.SetFloat("_Mode", 0);
    3. mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
    4. mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
    5. mat.SetInt("_ZWrite", 1);
    6. mat.DisableKeyword("_ALPHATEST_ON");
    7. mat.DisableKeyword("_ALPHABLEND_ON");
    8. mat.DisableKeyword("_ALPHAPREMULTIPLY_ON");
    9. mat.renderQueue = 2000;
    10.  
    The problem I was running into, is that if I put all the materials I wanted to Fade, then the object would fade, but leave a 'cut out' stencil of where it was in the other meshes.

    By doing it like this, we're forcing the draw order of the faded objects only, so they are drawn 'on top of' the Opaque ones.

    It's hacky, but like I said, it is the only thing that worked.
     
  17. Steviebops

    Steviebops

    Joined:
    Apr 9, 2013
    Posts:
    132
    Do you have the full code for that shader?