Search Unity

Need Help Fixed-Size Billboard

Discussion in 'Shaders' started by a0950212, Jun 1, 2019.

  1. a0950212

    a0950212

    Joined:
    Sep 28, 2014
    Posts:
    7
    Hi, I try to create a fixed-size(ignore view distance) billboard shader for quad.
    Does anyone know how to achieve it?

    Here is my billboard shader code.
     
  2. AlexHell

    AlexHell

    Joined:
    Oct 2, 2014
    Posts:
    167
    May be you need not a billboard but sprite of fixed width-height in the world canvas?
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Code (CSharp):
    1. Shader "Unlit/Constant Scale Quad"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.         Tags { "RenderType"="Opaque" }
    10.         LOD 100
    11.  
    12.         Pass
    13.         {
    14.             CGPROGRAM
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.          
    18.             #include "UnityCG.cginc"
    19.  
    20.             struct v2f
    21.             {
    22.                 float4 pos : SV_POSITION;
    23.                 float2 uv : TEXCOORD0;
    24.             };
    25.  
    26.             sampler2D _MainTex;
    27.          
    28.             v2f vert (appdata_base v)
    29.             {
    30.                 v2f o;
    31.  
    32.                 // extract world pivot position from object to world transform matrix
    33.                 float3 worldPos = unity_ObjectToWorld._m03_m13_m23;
    34.  
    35.                 // extract x and y scale from object to world transform matrix
    36.                 float2 scale = float2(
    37.                     length(unity_ObjectToWorld._m00_m10_m20),
    38.                     length(unity_ObjectToWorld._m01_m11_m21)
    39.                     );
    40.  
    41.                 // transform pivot position into view space
    42.                 float4 viewPos = mul(UNITY_MATRIX_V, float4(worldPos, 1.0));
    43.  
    44.                 // apply transform scale to xy vertex positions
    45.                 float2 vertex = v.vertex.xy * scale;
    46.  
    47.                 // multiply by view depth for constant view size scaling
    48.                 vertex *= -viewPos.z;
    49.  
    50.                 // divide by perspective projection matrix [1][1] if you don't want camera FOV to displayed size
    51.                 // the * 0.5 is to make a default quad with a scale of 1 be exactly the height of the view
    52.                 // vertex /= UNITY_MATRIX_P._m11 * 0.5;
    53.  
    54.                 // along with the perspective projection divide by screen height if you want the scale to be in screen pixels
    55.                 // vertex /= _ScreenParams.y;
    56.  
    57.                 // add vertex positions to view position pivot
    58.                 viewPos.xy += vertex;
    59.  
    60.                 // transform into clip space
    61.                 o.pos = mul(UNITY_MATRIX_P, viewPos);
    62.  
    63.                 o.uv = v.texcoord;
    64.                 return o;
    65.             }
    66.          
    67.             fixed4 frag (v2f i) : SV_Target
    68.             {
    69.                 fixed4 col = tex2D(_MainTex, i.uv);
    70.                 return col;
    71.             }
    72.             ENDCG
    73.         }
    74.     }
    75. }
    76.  
     
    Last edited: Nov 3, 2023
  4. a0950212

    a0950212

    Joined:
    Sep 28, 2014
    Posts:
    7
    Yes! World canvas is one of solutions.
    But I want to achieve it by shader in this case.

    Thank you for the prompt reply.
     
  5. a0950212

    a0950212

    Joined:
    Sep 28, 2014
    Posts:
    7
    Wow! It works!
    I really appreciate your help. (I am a new hand in shader. lol)
     
  6. AlexHell

    AlexHell

    Joined:
    Oct 2, 2014
    Posts:
    167
    Please explain why do you want to achieve this by a shader, but not a sprite in specific world pos (projected to screen)? I'm curious of the use case. If it's of fixed-size then it's UI element, as I undestand.
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    If you want something to interact with the world, like be occluded by objects or otherwise be sort with transparencies, or if you're doing VR, UI elements aren't that useful. Canvases can come with some performance overhead that's unnecessary.
     
    kirbygc00 likes this.
  8. Wayne-wyj1994

    Wayne-wyj1994

    Joined:
    Nov 13, 2019
    Posts:
    30

    In HDRP 10.x ,Unity 2020.2f , I use this shader to 3D TextMesh or SpriteRenderer .It did work as billboard and kepp fixed-size,but x/y uv looks like reversed.
    upload_2021-1-18_17-11-12.png
     
  9. Wayne-wyj1994

    Wayne-wyj1994

    Joined:
    Nov 13, 2019
    Posts:
    30
    I think that there should be "vertex *= -viewPos.z;" , which works for me.
     
  10. Cenly

    Cenly

    Joined:
    May 30, 2022
    Posts:
    16
    I search this shader for three days, so excited to find this thread after changing tons of search keywords....