Search Unity

Cutout shader with ZWrite On

Discussion in 'Shaders' started by seno, Jul 20, 2011.

  1. seno

    seno

    Joined:
    Aug 5, 2010
    Posts:
    17
    Hello.

    I am battling with shader to make Alpha Blending with ZWrite working together without using
    Alphatest for Android iPhone.
    I used SpriteManger2 for animating GameObject and I combined GameObjects to several
    SpriteManger components which is basically same with the CombinedMesh. I did this, because of
    the performance issue. Also, the combined GameObjects are sharing same material.

    Here is a screenshot from the Unity3D Editor


    and I used following shader code
    Code (csharp):
    1.  
    2. Shader "Transparent/Depth Ordered Unlit" {
    3.  
    4.     Properties {
    5.         _Color ("Main Color", Color) = (1,1,1,1)
    6.         _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    7.     }
    8.  
    9.     Category {
    10.         Lighting off
    11.         Cull off
    12.         Tags {"Queue" = "Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    13.  
    14.                
    15.  
    16.         SubShader {
    17.             ZWrite On
    18.             Alphatest Greater 0
    19.             Blend SrcAlpha OneMinusSrcAlpha
    20.  
    21.             Pass {
    22.                 SetTexture [_MainTex] {
    23.                     constantColor [_Color]
    24.                     Combine texture * constant
    25.                 }
    26.             }
    27.         }
    28.     }
    29. }
    30.  
    The problem of this shader is using Alphatest to remove pixels with alpha value 0.
    Most of you know, Alphatest eats lots of CPU/GPU power of Android/iPhone. So,
    I need to figure out other ways to get same visual without using Alphatest.


    so, I decided to simply not to use Alphatest
    Code (csharp):
    1.  
    2.             ZWrite On
    3.             //Alphatest Greater 0
    4.             Blend SrcAlpha OneMinusSrcAlpha
    5.  
    and I got result following which was not good



    It's because the flowers and the funny looking structures are not combined to same mesh.
    I mentioned of using SpriteManger2's Sprite component and combined structures per kind using SpriteManager component. Problem is that each CombinedMesh is decided to be drawn in order of
    the distance from MainCamera to the center of its bounding box in Unity3d. Right?
    And because of ZWrite On the drawing order is correct, however Blend is not working correctly.

    How do I solve this problem without using Alphatest?

    Thanks in advance.

    Danny
     

    Attached Files:

  2. brn

    brn

    Joined:
    Feb 8, 2011
    Posts:
    320
    If you wrote the shader using shader model 2 you could use the clip() function to mask your alpha's but i would try the solution below first.

    Is it possible for you to remove the alpha test and turn Zwrite Ztest to off? , Based on a still screen shot its hard to tell what the camera is doing but if they are drawn in the right order you wont need to alpha test at all.

    If it is as you say and you need Zwrite on to force the draw order within the transparent queue, with Ztest (zread) off its going to ignore the Zbuffer anyhow.

    Cheers
    Bruno
     
  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    No need for cutout here. The problem is likely that your sprites have their anchor point (-> 0,0,0) at the wrong position. it needs to be where its meant to be seen in depth to correctly draw, z write wouldn't change that going by the visual error there.

    If I had to guess I would assume that your 0,0,0 points are by error in the middle of the sprites, not bottom center or close to bottom center where it "visually" would have its ground point thus failing.

    And yes, the center of object ( the 0,0,0 point) decides about the depth point of the object for drawing if it uses alpha, they are not per pixel / tri depth sorted.

    One question though: Did you ensure that your ground layer is significantly behind the "on top" layer with the building? with a depth delta of 5 units such problems shouldn't appear either normally, not even on the lower end android gpus :)
     
    Last edited: Jul 21, 2011
  4. seno

    seno

    Joined:
    Aug 5, 2010
    Posts:
    17
    Thanks for reply!

    First of all, I didn't mention that I am usnig the orthographical camera for the game.;)

    Brn, ok, clip function. By the way, do you know same of usage of the function? I barely went
    through Unity3d Share lab tutorial recently. ;)
    You means that I need to control the draw order with something like following shader code?
    Code (csharp):
    1. Tags {"Queue" = "Transparent" }
    In that case, I think I can't, because the GameObjects in the game are many as progressing the game.

    Dreamora, yes, I did. See the picture following.
    This is a still shot from the editor's scene window.


    and see the following picture which is the scene's game screen.


    Each layer of the GameObjects has different 5 delta y(Y difference 5 for each layer). So, I am sure that
    I made geometrically right order for each layer.

    Actually, this game drew fine before I merged all GameObjects with Sprite component to several SpriteManager
    component. Following picture will give you hint how each SpriteManager component look like.


    The center of the SpriteManager component on the screen is the center of the yellow bounding box. Problem. :mad:
     

    Attached Files:

  5. crafTDev

    crafTDev

    Joined:
    Nov 5, 2008
    Posts:
    1,820
    Hey, just checking in to see if you solved this. I am having the same problem right now and currently using sprite manager with a 3d top down view of sprites. Lemme know thanks.
     
  6. Paradoks

    Paradoks

    Joined:
    Oct 13, 2009
    Posts:
    436
    Same as jrricky.
    Do you guys found a solution ?
     
  7. seno

    seno

    Joined:
    Aug 5, 2010
    Posts:
    17
    It's been a while since I didn't log in this forum. I was little bit busy.

    It was not perfect, but I found a solution for the problem. By using this, I gained about 10 ~ 15 frames up for
    mobile devices. I hope it gives same benefit for you guys.

    Code (csharp):
    1.  
    2. Shader "Transparent/Unlit/Without Alphatest" {
    3.     Properties {
    4.         _Color ("Main Color", Color) = (1,1,1,1)
    5.         _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    6.     }
    7.  
    8.     Category {
    9.         Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
    10.         Lighting Off
    11.         Cull Off
    12.         ZWrite On // To keep the correct Z order
    13.         Blend SrcAlpha OneMinusSrcAlpha // Doing Alpha Blending
    14.        
    15.         SubShader {
    16.             Pass {         
    17.                 SetTexture [_MainTex] {
    18.                     constantColor [_Color]
    19.                     // Mixing the color and the alpha
    20.                     Combine texture * constant, texture * constant
    21.                 }
    22.             }
    23.         }
    24.     }
    25. }
    26.  
     
  8. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Might want to try 3.5.3's new sort mode if you're using perspective camera anywhere:


    Code (csharp):
    1. function Start ()
    2. {
    3.     gameObject.camera.transparencySortMode = TransparencySortMode.Orthographic;
    4. }