Search Unity

[Need Help] Billboarding Geometry Shader

Discussion in 'Shaders' started by CoderPro, Feb 26, 2020.

  1. CoderPro

    CoderPro

    Joined:
    Feb 21, 2014
    Posts:
    327
    Hi everyone,

    I want to make a billboard geometry shader to all tree mesh will be face towards camera positon. But i don't have experience with shaderlab, i hope someone can help me fix for me.

    Below is billboard geometry shader code that i am using:
    i get from here:
    https://forum.unity.com/threads/billboard-geometry-shader.169415/

    Code (CSharp):
    1.  
    2. Shader "Custom/GS Billboard"
    3. {
    4.    Properties
    5.    {
    6.       _SpriteTex ("Base (RGB)", 2D) = "white" {}
    7.       _Size ("Size", Range(0, 10)) = 1
    8.    }
    9.  
    10.    SubShader
    11.    {
    12.       Pass
    13.       {
    14.          Tags { "RenderType"="Opaque" }
    15.          LOD 200
    16.  
    17.          CGPROGRAM
    18.             #pragma target 5.0
    19.             #pragma vertex VS_Main
    20.             #pragma fragment FS_Main
    21.             #pragma geometry GS_Main
    22.             #include "UnityCG.cginc"
    23.  
    24.             // **************************************************************
    25.             // Data structures                                    *
    26.             // **************************************************************
    27.             struct GS_INPUT
    28.             {
    29.                float4   pos      : POSITION;
    30.                float3   normal   : NORMAL;
    31.                float2  tex0   : TEXCOORD0;
    32.             };
    33.  
    34.             struct FS_INPUT
    35.             {
    36.                float4   pos      : POSITION;
    37.                float2  tex0   : TEXCOORD0;
    38.             };
    39.  
    40.             // **************************************************************
    41.             // Vars                                             *
    42.             // **************************************************************
    43.  
    44.             float _Size;
    45.             float4x4 _VP;
    46.             Texture2D _SpriteTex;
    47.             SamplerState sampler_SpriteTex;
    48.  
    49.             // **************************************************************
    50.             // Shader Programs                                    *
    51.             // **************************************************************
    52.  
    53.             // Vertex Shader ------------------------------------------------
    54.             GS_INPUT VS_Main(appdata_base v)
    55.             {
    56.                GS_INPUT output = (GS_INPUT)0;
    57.  
    58.                output.pos =  mul(unity_ObjectToWorld, v.vertex);
    59.                output.normal = v.normal;
    60.                output.tex0 = float2(0, 0);
    61.  
    62.                return output;
    63.             }
    64.  
    65.             // Geometry Shader -----------------------------------------------------
    66.             [maxvertexcount(4)]
    67.             void GS_Main(point GS_INPUT p[1], inout TriangleStream<FS_INPUT> triStream)
    68.             {
    69.                float halfWidth = _Size / 2.0f;
    70.                
    71.                
    72.                float3 planeNormal = p[0].pos - _WorldSpaceCameraPos;
    73.                planeNormal.y = 0.0f;
    74.                planeNormal = normalize(planeNormal);
    75.  
    76.                float3 upVector = float3(0.0f, 1.0f, 0.0f);
    77.                float3 rightVector = normalize(cross(planeNormal, upVector));
    78.                rightVector = rightVector * halfWidth;
    79.                upVector = float3(0, _Size, 0);
    80.  
    81.                float4 v[4];
    82.                v[0] = float4(p[0].pos - rightVector, 1.0f);
    83.                v[1] = float4(p[0].pos + rightVector, 1.0f);
    84.                v[2] = float4(p[0].pos - rightVector + upVector, 1.0f);
    85.                v[3] = float4(p[0].pos + rightVector + upVector, 1.0f);
    86.  
    87.  
    88.                FS_INPUT pIn;
    89.                pIn.pos = UnityObjectToClipPos(v[0]);
    90.                pIn.tex0 = float2(1.0f, 0.0f);
    91.                triStream.Append(pIn);
    92.  
    93.                pIn.pos = UnityObjectToClipPos(v[1]);
    94.                pIn.tex0 = float2(0.0f, 0.0f);
    95.                triStream.Append(pIn);
    96.  
    97.                pIn.pos = UnityObjectToClipPos(v[2]);
    98.                pIn.tex0 = float2(1.0f, 1.0f);
    99.                triStream.Append(pIn);
    100.  
    101.                pIn.pos = UnityObjectToClipPos(v[3]);
    102.                pIn.tex0 = float2(0.0f, 1.0f);
    103.                triStream.Append(pIn);
    104.             }
    105.  
    106.             // Fragment Shader -----------------------------------------------
    107.             float4 FS_Main(FS_INPUT input) : COLOR
    108.             {
    109.                return _SpriteTex.Sample(sampler_SpriteTex, input.tex0);
    110.             }
    111.  
    112.          ENDCG
    113.       }
    114.    }
    115. }
    116.  
    I want to using this shader for my combined tree mesh (which have many individual child mesh) like below:

    This is screenshot when i using standard shader for it.

    But, when i using above GS Billboard shader for it, the position and scale of original mesh was changed like below:


    As you can see, when apply to GS billboard shader, all position and scale was changed.
    I want to keep original position and scale of all individual tree mesh like when i using Standard Shader, but i don't known how i can fix it and fix from where.
    I hope someone can help me fix this shader !

    Thank in advanced !
     
    Last edited: Feb 26, 2020