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

Help with billboard alpha shader

Discussion in 'Shaders' started by virror, May 23, 2013.

  1. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Hello, im trying to make a billboard shader with alpha blending but i don't know a single line of this : p
    The blending was really easy using shader lab syntax to get working and i found a billboard shader on the internet but the problem is it only works when i have one on the screen at a time. As soon as i add another one both turn invisible. Also i wonder how its possible to change the scale of the billboard and if its possible to optimize it further.

    Here is the code:
    Code (csharp):
    1.  
    2. Shader "Alpha Billboard"
    3. {
    4.     Properties
    5.     {
    6.         _TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
    7.         _MainTex ("Particle Texture", 2D) = "white" {}
    8.     }
    9.  
    10.     Category
    11.     {
    12.         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    13.         Blend SrcAlpha OneMinusSrcAlpha
    14.         AlphaTest Greater .01
    15.         Cull Off
    16.        
    17.         SubShader
    18.         {
    19.             Pass
    20.             {
    21.                 CGPROGRAM
    22.                 #pragma vertex vert
    23.                 #pragma fragment frag
    24.                
    25.                 #include "UnityCG.cginc"
    26.                
    27.                 sampler2D _MainTex;
    28.                 fixed4 _TintColor;
    29.                
    30.                 struct appdata_t
    31.                 {
    32.                     float4 vertex : POSITION;
    33.                     fixed4 color : COLOR;
    34.                     float2 texcoord : TEXCOORD0;
    35.                 };
    36.    
    37.                 struct v2f
    38.                 {
    39.                     float4 vertex : POSITION;
    40.                     fixed4 color : COLOR;
    41.                     float2 texcoord : TEXCOORD0;
    42.                 };
    43.    
    44.                 v2f vert (appdata_t v)
    45.                 {
    46.                     v2f o;
    47.                     o.vertex = mul(UNITY_MATRIX_P,
    48.                          mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
    49.                         + float4(v.vertex.x, v.vertex.y, 0.0, 0.0));
    50.    
    51.                     o.color = v.color;
    52.                     o.texcoord = float4(v.vertex.x  + 0.5, v.vertex.y + 0.5, 0.0, 0.0);
    53.                     return o;
    54.                 }
    55.    
    56.                 fixed4 frag (v2f i) : COLOR
    57.                 {
    58.                     return 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord);
    59.                 }
    60.                 ENDCG
    61.             }
    62.         }  
    63.     }
    64. }
    65.  
    66.  
     
    Last edited: May 24, 2013
  2. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Anyone?
     
  3. Elehe

    Elehe

    Joined:
    May 19, 2013
    Posts:
    14
    how do you change the values to make them invisible? Maybe you acces all elements that got that material attached.
     
  4. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    I don't want anything invisible (except for the alpha), thats the problem. As soon as i try to add another instance both will turn invisible : /
     
  5. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    Last edited: May 24, 2013
  6. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Seems like many had this issue but not a single reply from a dev or moderator : /
    If anyone could point me to another working billboard shader that would also be appreciated : )
     
  7. cician

    cician

    Joined:
    Dec 10, 2012
    Posts:
    233
    I can't check it now, but I see a few possible problems.

    First, though it's probably not your issue, change
    Code (csharp):
    1. o.texcoord = float4(v.vertex.x  + 0.5, v.vertex.y + 0.5, 0.0, 0.0);
    to
    Code (csharp):
    1. o.texcoord = float2(v.vertex.x  + 0.5, v.vertex.y + 0.5);
    as the compiler can do something unexpected with implicit truncation.

    Then the shader doesn't turn off zwite. I'm not sure if unity does it automatically if rendertype is transparent, but I gues not.
    Writing to zbuffer in transparent queue can bring to front background objects resulting in strange issues.

    Try if this helps.
    I'm writing this on a tablet :wink:
    Code (csharp):
    1.  
    2.  
    3.     Shader "Alpha Billboard"
    4.     {
    5.         Properties
    6.         {
    7.             _TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
    8.             _MainTex ("Particle Texture", 2D) = "white" {}
    9.             _Scale("Scale", float) = 1.0
    10.         }
    11.      
    12.         Category
    13.         {
    14.             Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    15.             Blend SrcAlpha OneMinusSrcAlpha
    16.             AlphaTest Greater .01
    17.             Cull Off
    18.            
    19. // important
    20. ZWrite off
    21.  
    22.             SubShader
    23.             {
    24.                 Pass
    25.                 {
    26.                     CGPROGRAM
    27.                     #pragma vertex vert
    28.                     #pragma fragment frag
    29.                    
    30.                     #include "UnityCG.cginc"
    31.                    
    32.                     sampler2D _MainTex;
    33.                     fixed4 _TintColor;
    34.                     float _Scale;
    35.                    
    36.                     struct appdata_t
    37.                     {
    38.                         float4 vertex : POSITION;
    39.                         fixed4 color : COLOR;
    40.                         float2 texcoord : TEXCOORD0;
    41.                     };
    42.        
    43.                     struct v2f
    44.                     {
    45.                         float4 vertex : POSITION;
    46.                         fixed4 color : COLOR;
    47.                         float2 texcoord : TEXCOORD0;
    48.                     };
    49.        
    50.                     v2f vert (appdata_t v)
    51.                     {
    52.                         v2f o;
    53.                         o.vertex = mul(UNITY_MATRIX_P,
    54.                              mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
    55.                             + float4(v.vertex.x, v.vertex.y, 0.0, 0.0)*_Scale);
    56.        
    57.                         o.color = v.color;
    58.                         o.texcoord = float2(v.vertex.x  + 0.5, v.vertex.y + 0.5);
    59.                         return o;
    60.                     }
    61.        
    62.                     fixed4 frag (v2f i) : COLOR
    63.                     {
    64.                         return 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord);
    65.                     }
    66.                     ENDCG
    67.                 }
    68.             }  
    69.         }
    70.     }
    71.  
    Remember semitransparency may be tricky.
     
  8. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Thanx you a lot for the help!
    Scale works very good, but ZWrite Off makes the whole thing look very strange and something is off with the depth causing some trunks to be rendered in front of some of the "leaves", but only on the left side for some reason. Works better without that flag.

    Everything works very well if i create separate materials for every mesh by instantiating everything in code, but then i cant use dynamic batching and get loads of drawcalls. Why cant i use the same material for multiple instances? Is this some kind of Unity bug?

    Also, any idea how i get lightning to update properly on the billboards? Example is day/night cycle.
     
  9. BIG-BUG

    BIG-BUG

    Joined:
    Mar 29, 2009
    Posts:
    457
    Actually the batching itself is the problem here.
    As all batched meshes are combined into a single mesh, the null point changes of course. However this billboard shader requires the null point to be in the middle of your sprite.
     
  10. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    It seems that is why all these werid things happens, could you explain more details,
    Like when would the batching happens? even if i dont create meshes as particles
     
  11. BIG-BUG

    BIG-BUG

    Joined:
    Mar 29, 2009
    Posts:
    457
    Generally if dynamic batching is enabled (Project->Player Settings) meshes with the same material (sharedMaterial) and not to many vertices will be batched (there are exceptions like non-uniform scaling, shadows and other). Batching means that all affected meshes will be merged into one big mesh which is faster to render. Local vertex coordinates and tangents will be adjusted accordingly as now the center/null point of the mesh has been moved/rotated. Subsequently vertex shader which rely on a defined center will render incorrectly (like the shader above).
     
    antislash likes this.
  12. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    You are so kind :)
     
  13. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Ahh, thats logical, thank you for your very good explanations : )
     
  14. kit

    kit

    Joined:
    Jun 16, 2011
    Posts:
    87
    Ah, it's really batching! :) I really fixed this bug, but with some "hack", I re-created a material for each sprite object :)
     
  15. loopzilla

    loopzilla

    Joined:
    Feb 16, 2015
    Posts:
    2
    Set static flag on objects - this will change batching algorithm to friendly with billboard technique.
    But in this case you will not be able to change position of objects..
     
    antislash likes this.