Search Unity

Billboard sprite shader

Discussion in 'Shaders' started by kit, May 7, 2013.

  1. kit

    kit

    Joined:
    Jun 16, 2011
    Posts:
    87
    Hi,

    I tried a technique described here: http://en.wikibooks.org/wiki/Cg_Programming/Unity/Billboards, but if i create two sprites in the scene, positions of the sprites are wrong:

    $wrong_billboard.PNG



    Also I tried to create billboard shader that will rotate my sprite here, but cannot finish it.

    Please help me fix this problem. I create sprite from Unity3d script, but there are a lot of objects in my scene, and when i try to rotate each sprite on each update, application performance is very low. So I want to create a shader that will rotate object (plane), around his center, so he is always visible to camera.

    Here is the shader code, that should implement this:

    Code (csharp):
    1.  
    2. float3 look = normalize(ObjSpaceViewDir(v.vertex).xyz);
    3. float3 up = float3(0.0f, 1.0f, 0.0f);
    4. float3 right = normalize(cross(look, up));
    5. float4x4 rotationMatrix =
    6. float4x4(float4(right.x, up.x, -look.x, 0), float4(right.y, up.y, -look.y, 0), float4(right.z, up.z, -look.z, 0),  float4(v.vertex.xyz, 1));
    7. float4 finalposition = mul(rotationMatrix, v.vertex);              
    8. float4 pos = float4(finalposition.xyz, 1);
    9. o.vertex = mul(UNITY_MATRIX_MVP, pos);
    10.  
    But it doesn't works. Please point me to bug in this code.

    Thanks in advance.
     
    Last edited: May 9, 2013
  2. kit

    kit

    Joined:
    Jun 16, 2011
    Posts:
    87
    Nobody knows?
     
  3. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    It is more likely that you'll get help if you ask a specific question. That way the solution might also helpful to other people visiting the forum.
    If you want someone to fix the shader for you, you could consider requesting help on the commercial forum.

    [Edit] Your edited first post looks better now.
     
    Last edited: May 9, 2013
  4. kit

    kit

    Joined:
    Jun 16, 2011
    Posts:
    87
    Thank you for your answer, but i have found some similar question, and of course solutions for this issue. But i really can't find any solution that works. I just try to change position of my sprite, and sprite appears in some strange locations. So I tried to implement this shader by myself, and when i understand that i can't get good implementation, i decided to ask the question here. Also i put my implementation here, and i hope that a lot of people knows solution for this issue. So, i of course do not need someone to create shader for me from A to Z.
     
  5. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    if you care more about performance hit,should check some thing else,like collider...
     
  6. kit

    kit

    Joined:
    Jun 16, 2011
    Posts:
    87
    I thinks that, setting world matrix for 999999 object on each frame on update is not the best solution. And even removing colliders will not help :) in this situation
     
  7. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    Never know what exactly what you want,here is my code,which will keep mesh size based distance to camera,and rotation
    Code (csharp):
    1.  
    2. Shader "Tut/Project/Billboard_2" {
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.     }
    6.     SubShader {
    7.         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    8.         pass{
    9.         Cull Off
    10.         ZTest Always
    11.         Blend SrcAlpha OneMinusSrcAlpha
    12.         CGPROGRAM
    13.         #pragma vertex vert
    14.         #pragma fragment frag
    15.         #include "UnityCG.cginc"
    16.         sampler2D _MainTex;
    17.         struct v2f {
    18.             float4 pos:SV_POSITION;
    19.             float2 texc:TEXCOORD0;
    20.         };
    21.         v2f vert(appdata_base v)
    22.         {
    23.             v2f o;
    24.             float4 ori=mul(UNITY_MATRIX_MV,float4(0,0,0,1));
    25.             float4 vt=v.vertex;
    26.             //vt.y=vt.z;
    27.             float2 r1=float2(_Object2World[0][0],_Object2World[0][2]);
    28.             float2 r2=float2(_Object2World[2][0],_Object2World[2][2]);
    29.             float2 vt0=vt.x*r1;
    30.             vt0+=vt.z*r2;
    31.             vt.xy=vt0;
    32.             vt.z=0;
    33.             vt.xyz+=ori.xyz;//result is vt.z==ori.z ,so the distance to camera keeped ,and screen size keeped
    34.             o.pos=mul(UNITY_MATRIX_P,vt);
    35.  
    36.             o.texc=v.texcoord;
    37.             return o;
    38.         }
    39.         float4 frag(v2f i):COLOR
    40.         {
    41.             return tex2D(_MainTex,i.texc);
    42.         }
    43.         ENDCG
    44.         }//endpass
    45.     }
    46. }
    47.  
     
  8. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    Never know what exactly what you want,here is my code,which will keep mesh size based distance to camera,and rotation
    Code (csharp):
    1.  
    2. Shader "Tut/Project/Billboard_2" {
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.     }
    6.     SubShader {
    7.         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    8.         pass{
    9.         Cull Off
    10.         ZTest Always
    11.         Blend SrcAlpha OneMinusSrcAlpha
    12.         CGPROGRAM
    13.         #pragma vertex vert
    14.         #pragma fragment frag
    15.         #include "UnityCG.cginc"
    16.         sampler2D _MainTex;
    17.         struct v2f {
    18.             float4 pos:SV_POSITION;
    19.             float2 texc:TEXCOORD0;
    20.         };
    21.         v2f vert(appdata_base v)
    22.         {
    23.             v2f o;
    24.             float4 ori=mul(UNITY_MATRIX_MV,float4(0,0,0,1));
    25.             float4 vt=v.vertex;
    26.             //vt.y=vt.z;
    27.             float2 r1=float2(_Object2World[0][0],_Object2World[0][2]);
    28.             float2 r2=float2(_Object2World[2][0],_Object2World[2][2]);
    29.             float2 vt0=vt.x*r1;
    30.             vt0+=vt.z*r2;
    31.             vt.xy=vt0;
    32.             vt.z=0;
    33.             vt.xyz+=ori.xyz;//result is vt.z==ori.z ,so the distance to camera keeped ,and screen size keeped
    34.             o.pos=mul(UNITY_MATRIX_P,vt);
    35.  
    36.             o.texc=v.texcoord;
    37.             return o;
    38.         }
    39.         float4 frag(v2f i):COLOR
    40.         {
    41.             return tex2D(_MainTex,i.texc);
    42.         }
    43.         ENDCG
    44.         }//endpass
    45.     }
    46. }
    47.  
     
  9. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    Hope this would be help
    and here is a more simple code,just size in view sapce will keeped,not rotation
    Code (csharp):
    1.  
    2. v2f vert(appdata_base v)
    3.         {
    4.             v2f o;
    5.             float4 ori=mul(UNITY_MATRIX_MV,float4(0,0,0,1));
    6.             float4 vt=v.vertex;
    7.             vt.y=vt.z;
    8.             vt.z=0;
    9.             vt.xyz+=ori.xyz;//result is vt.z==ori.z ,so the distance to camera keeped ,and screen size keeped
    10.             o.pos=mul(UNITY_MATRIX_P,vt);
    11.  
    12.             o.texc=v.texcoord;
    13.             return o;
    14.         }
    15.  
    just worked for mesh has pivot in center,like default plane
     
    Last edited: May 9, 2013
    GrenadeMadness likes this.
  10. kit

    kit

    Joined:
    Jun 16, 2011
    Posts:
    87
    Thanks, Lulucifer.

    I'll try it.
     
  11. kit

    kit

    Joined:
    Jun 16, 2011
    Posts:
    87
    Thanks again, Lulucifer. Shader works fine. The only restriction, i should mention in your shader, that you cannot assign the SAME material for objects, user need to create separate materials for each object. I think this is the issue of the Unity3d. But, thank you a lot! :)
     
  12. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    I know that, I had asked why,but didnt get answers :(
    I have try again, and they(billborads) are fine now, dont know why.
    maybe something cached by unity
     
    Last edited: May 10, 2013
  13. kit

    kit

    Joined:
    Jun 16, 2011
    Posts:
    87
    Ah, you have got the same issues too. So, now i can say that even this works nice, if i create separate materials for objects. So, yes, there is some mega bug :D
     
  14. Deleted User

    Deleted User

    Guest

    Did you guys managed to fix the intance issue? For now I just wrote a simple script that update rotation of a mehs on Update, but it seems overkill with a lot of sprites and would rather use a shader for that. Also is possible to not rotate on Y in the shader? Sorry for question I'm kinda noob when comes to shaders.
     
  15. Lulucifer

    Lulucifer

    Joined:
    Jul 8, 2012
    Posts:
    358
    related to dynamic batching, disable that,it will work
     
  16. Deleted User

    Deleted User

    Guest

    Yeah it works, but as you can expect drawcalls raise and the benefit to have one single material is just gone. But I guess isn't fixable.
     
  17. AR_Rizvi

    AR_Rizvi

    Joined:
    Aug 12, 2013
    Posts:
    40
    Hi guys i am working with ur shader and its working awsmly but some of my trees r disappear and the appear agian i dnt knw what is this its like a lights blinking effect can u guys guide me that what i am doing worng
     
  18. ltethe

    ltethe

    Joined:
    Jan 21, 2014
    Posts:
    5
    Is there a solution to this at all? I'm generating billboards procedurally, and I need a solution that works in shader. Like the posters before me, the code here works as long as the billboards do not overlap, if they do, they translate to the inverse of their transform, not helpful.

    Again, as mentioned, using separate shaders fixes this issue, but I'm generating hundreds of billboards, to keep my draw count manageable, hundreds of materials is not going to work.
     
  19. Aldrick

    Aldrick

    Joined:
    Feb 19, 2014
    Posts:
    64
    Decent,lulucifer.
     
  20. hungtaikei

    hungtaikei

    Joined:
    Mar 31, 2017
    Posts:
    3
    i'm interest