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

Billboard Shader only rotate around Y axis

Discussion in 'Shaders' started by VinnieH01, Jun 16, 2017.

  1. VinnieH01

    VinnieH01

    Joined:
    Sep 3, 2014
    Posts:
    32
    Ive got a billboard shader but it roatates around all axes but i would like it to just rotate around the Y axis, how would I do that?

    https://en.wikibooks.org/wiki/Cg_Programming/Unity/Billboards

    Code (CSharp):
    1. Shader "Cg shader for billboards" {
    2. Properties {
    3. _MainTex ("Texture Image", 2D) = "white" {}
    4. _ScaleX ("Scale X", Float) = 1.0
    5. _ScaleY ("Scale Y", Float) = 1.0
    6. }
    7. SubShader {
    8. Pass {
    9. CGPROGRAM
    10.  
    11. #pragma vertex vert
    12. #pragma fragment frag
    13.  
    14. // User-specified uniforms
    15. uniform sampler2D _MainTex;
    16. uniform float _ScaleX;
    17. uniform float _ScaleY;
    18.  
    19. struct vertexInput {
    20. float4 vertex : POSITION;
    21. float4 tex : TEXCOORD0;
    22. };
    23. struct vertexOutput {
    24. float4 pos : SV_POSITION;
    25. float4 tex : TEXCOORD0;
    26. };
    27.  
    28. vertexOutput vert(vertexInput input)
    29. {
    30. vertexOutput output;
    31.  
    32. output.pos = mul(UNITY_MATRIX_P,
    33. mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
    34. + float4(input.vertex.x, input.vertex.y, 0.0, 0.0)
    35. * float4(_ScaleX, _ScaleY, 1.0, 1.0));
    36.  
    37. output.tex = input.tex;
    38.  
    39. return output;
    40. }
    41.  
    42. float4 frag(vertexOutput input) : COLOR
    43. {
    44. return tex2D(_MainTex, float2(input.tex.xy));
    45. }
    46.  
    47. ENDCG
    48. }
    49. }
    50. }
     
    Last edited: Jun 29, 2017
  2. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    412
    You are using this shader with a particle system?
    What data are you feeding it?
    Looking at the shader it should be drawing in screen space.
    And unless the local coordinates vertex are changing I am not sure how you are seeing rotations.
    But vertex will depend on what you are rendering with it.
     
  3. Phantom_X

    Phantom_X

    Joined:
    Jul 11, 2013
    Posts:
    313
  4. VinnieH01

    VinnieH01

    Joined:
    Sep 3, 2014
    Posts:
    32
    Thank you YanVerde
     
  5. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,589
    'localpos' is data that has been encoded in the mesh in a very specific way and is not just available using Unity built-in functionality.

    You probably have to read the conversation between @Peter77 and @Riderfan in this thread to get the idea how localpos is generated and used.
     
  6. VinnieH01

    VinnieH01

    Joined:
    Sep 3, 2014
    Posts:
    32
    @YanVerde @Peter77 The shader doesnt work with pointlights and I kinda need this. I implemented the "billboard" part of the shader into the transparent/Bumped shader and it worked but I had other problems like some objects being rendered in front of others when they shouldn't and no shadows were being cast or received.

    This is what the shader code looks like :

    Code (CSharp):
    1. Shader "Legacy Shaders/Transparent/Bumped Diffuse" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5.     _BumpMap ("Normalmap", 2D) = "bump" {}
    6. }
    7.  
    8. SubShader {
    9.     Tags
    10.     {
    11.         "Queue"="Transparent"
    12.         "IgnoreProjector"="True"
    13.         "RenderType"="Transparent"
    14.         "DisableBatching"="True"
    15.     }
    16.     LOD 100
    17.  
    18. CGPROGRAM
    19. #pragma vertex vert
    20. #pragma surface surf Lambert alpha:fade noinstancing
    21.  
    22. struct appdata_t
    23. {
    24.     float4 vertex : POSITION;
    25.     float3 normal : NORMAL;
    26.     half4 color : COLOR0;
    27.     float2 texcoord : TEXCOORD0;
    28.     float2 texcoord1 : TEXCOORD1;
    29.     float2 texcoord2 : TEXCOORD2;
    30.     float4 tangent : TANGENT;
    31. };
    32.  
    33. sampler2D _MainTex;
    34. sampler2D _BumpMap;
    35. fixed4 _Color;
    36.  
    37. struct Input {
    38.     float2 uv_MainTex;
    39.     float2 uv_BumpMap;
    40. };
    41.  
    42. void Billboard(inout appdata_t v)
    43. {
    44.     const float3 local = float3(v.vertex.x, v.vertex.y, 0); // this is the quad verts as generated by MakeMesh.cs in the localPos list.
    45.     const float3 offset = v.vertex.xyz - local;
    46.  
    47.     const float3 upVector = half3(0, 1, 0);
    48.     const float3 forwardVector = UNITY_MATRIX_IT_MV[2].xyz; // camera forward
    49.     const float3 rightVector = normalize(cross(forwardVector, upVector));
    50.  
    51.     float3 position = 0;
    52.     position += local.x * rightVector;
    53.     position += local.y * upVector;
    54.     position += local.z * forwardVector;
    55.  
    56.     v.vertex = float4(offset + position, 1);
    57.     v.normal = forwardVector;
    58. }
    59.  
    60. void vert (inout appdata_t v, out Input o)
    61. {  
    62.     UNITY_INITIALIZE_OUTPUT(Input, o);
    63.     Billboard(v);
    64. }
    65.  
    66. void surf (Input IN, inout SurfaceOutput o) {
    67.     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    68.     o.Albedo = c.rgb;
    69.     o.Alpha = c.a;
    70.     o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    71. }
    72. ENDCG
    73. }
    74. }
    How do I fix these two problems? (Shadows not working and objects being rendered on top of each other when they shouldn't)
     
  7. Phantom_X

    Phantom_X

    Joined:
    Jul 11, 2013
    Posts:
    313
    The shadow issue is because this is a transparent shader and it can't receive or cast shadows ( there is a bunch of threads about that). The other issue is probably due to z-ordering because it's a transparent shader too. If you don't need semi-transparency you could use an Alpha-Test shader instead this would solve both problems
     
  8. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    412
    If changing it to alpha test doesn't help your depth problems.
    I think you might not be transforming your z correctly for the depth buffer to work.
    It looks like it might always be 0 or vertex.z.
     
  9. Phantom_X

    Phantom_X

    Joined:
    Jul 11, 2013
    Posts:
    313
    You can use the pragma addshadow to fix this
     
  10. VinnieH01

    VinnieH01

    Joined:
    Sep 3, 2014
    Posts:
    32
    @daxiongmao @YanVerde changing it to alpha test helped with the depth problems I was having but it didnt fix the shadows. This is my code :

    Code (CSharp):
    1. Shader "Custom/BillboardY" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5.     _BumpMap ("Normalmap", 2D) = "bump" {}
    6.     _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    7. }
    8.  
    9. SubShader {
    10.     Tags
    11.     {
    12.         "Queue"="AlphaTest"
    13.         "IgnoreProjector"="True"
    14.         "RenderType"="TransparentCutout"
    15.         "DisableBatching"="True"
    16.     }
    17.     LOD 100
    18.    
    19. CGPROGRAM
    20. #pragma vertex vert
    21. #pragma surface surf Lambert alphatest:_Cutoff noinstancing
    22.  
    23. struct appdata_t
    24. {
    25.     float4 vertex : POSITION;
    26.     float3 normal : NORMAL;
    27.     half4 color : COLOR0;
    28.     float2 texcoord : TEXCOORD0;
    29.     float2 texcoord1 : TEXCOORD1;
    30.     float2 texcoord2 : TEXCOORD2;
    31.     float4 tangent : TANGENT;
    32. };
    33.  
    34. sampler2D _MainTex;
    35. sampler2D _BumpMap;
    36. fixed4 _Color;
    37.  
    38. struct Input {
    39.     float2 uv_MainTex;
    40.     float2 uv_BumpMap;
    41. };
    42.  
    43. void Billboard(inout appdata_t v)
    44. {
    45.     const float3 local = float3(v.vertex.x, v.vertex.y, 0); // this is the quad verts as generated by MakeMesh.cs in the localPos list.
    46.     const float3 offset = v.vertex.xyz - local;
    47.     const float3 upVector = half3(0, 1, 0);
    48.     const float3 forwardVector = UNITY_MATRIX_IT_MV[2].xyz; // camera forward
    49.     const float3 rightVector = normalize(cross(forwardVector, upVector));
    50.     float3 position = 0;
    51.     position += local.x * rightVector;
    52.     position += local.y * upVector;
    53.     position += local.z * forwardVector;
    54.     v.vertex = float4(offset + position, 1);
    55.     v.normal = forwardVector;
    56. }
    57.  
    58. void vert (inout appdata_t v, out Input o)
    59. {  
    60.     UNITY_INITIALIZE_OUTPUT(Input, o);
    61.     Billboard(v);
    62. }
    63.  
    64. void surf (Input IN, inout SurfaceOutput o) {
    65.     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    66.     o.Albedo = c.rgb;
    67.     o.Alpha = c.a;
    68.     o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    69. }
    70. ENDCG
    71. }
    72. }
    What am I doing wrong?
     
  11. VinnieH01

    VinnieH01

    Joined:
    Sep 3, 2014
    Posts:
    32
    addshadow fixed it! Thank you
     
  12. Phantom_X

    Phantom_X

    Joined:
    Jul 11, 2013
    Posts:
    313
    Try changing this:
    #pragma surface surf Lambert alphatest:_Cutoff noinstancing
    to this:
    #pragma surface surf Lambert alphatest:_Cutoff noinstancing addshadow