Search Unity

Billboard Geometry Shader

Discussion in 'Made With Unity' started by smb02dunnal, Feb 7, 2013.

  1. smb02dunnal

    smb02dunnal

    Joined:
    May 5, 2012
    Posts:
    439
    rboerdijk, Agent0023 and mgear like this.
  2. bfoddy

    bfoddy

    Joined:
    Mar 27, 2012
    Posts:
    85
    Does it require Unity 4? I get a long string of errors in 3.5.
     
  3. duke

    duke

    Joined:
    Jan 10, 2007
    Posts:
    763
    Much appreciated, thankyou sir.
     
  4. Nirus

    Nirus

    Joined:
    May 8, 2015
    Posts:
    1
    Thanx a lot!!!
     
  5. Alesk

    Alesk

    Joined:
    Jul 15, 2010
    Posts:
    340
    Hi,

    Just trying this cool shader on unity 5.3
    Problem : only 5 of the 8 corners of the unity cube primitive have a billboard attached to it.
    If I try with a cube exported as a fbx file from blender, then only 4 corners have a billboard... And with a plane (so 4 vertices), only one billboard is displayed in a corner of the plane.

    Any idea on the origin of this problem ?
     
  6. einraum-design

    einraum-design

    Joined:
    Jun 2, 2015
    Posts:
    1
    This shader is perfect what I'm looking for - thank you!

    A unity standart cube has just five (instead of eight) billboards at the corners - seems to be a unity optimized object.
    When I export a cube from C4D as fbx it has billboards at all eight corners
    Unity 5.4.0f3 (64-bit)
     
  7. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    There's nothing wrong with this shader or the Unity Cube, the reason people are seeing less billboards than vertices is because they're not understanding how geometry shaders work.

    Geometry shaders operate on topological primitives in the form of a finite set of vertices as input - a point is one vertex, a line is 2 vertices, a triangle is 3 etc. The set size is based on the underlying mesh topology type. This geometry shader was designed to work on point primatives hence as input it gets a single vertex at a time:

    Code (CSharp):
    1. void GS_Main(point GS_INPUT p[1], inout TriangleStream<FS_INPUT> triStream)
    However, meshes in Unity are by default fed to the GPU with a mesh topology of triangles thus when being fed through a geometry shader that works on points that triangle primative (set of 3 vertices) is being truncated to the first vertex of each triangle. This is why not all corners will have billboards. It's getting 8 vertices, but some of those triangles will share the same starting vertex and hence it's creating duplicate billboards right on top of each other at some points. This is why you see different results from the built in unity cube mesh compared to cubes generated in external 3D modelling programs. You can set the topology type of a mesh via code (this feature was added back in 4.2 or something) but Unity only supports a subset of the geometry shader primitives of points, triangles and lines. None of the GLSL/DX adjacency primitive types are supported.

    For example, with the line typology a geometry shader will get 2 vertices as input which is handy for doing things like creating quads for rendering lines. But it doesn't support the line adjacency topology which would pass in 4 points (the 2 points for the line segment and the two points either side of that as well) which is even more useful for obvious reasons if you want to do custom tessellation or hair or anything of the sort. Hopefully when geometry shaders become a little more universal across devices they'll add support for this.

    https://twitter.com/aras_p/status/287142879699292160
     
    drew55 and Alesk like this.
  8. Aaron-Meyers

    Aaron-Meyers

    Joined:
    Dec 8, 2009
    Posts:
    305
    thanks for this shader! i was wondering if anyone has any pointers on how it could be modified to get stretched billboards controlled by a velocity vector.

    -A
     
  9. unitydevist

    unitydevist

    Joined:
    Feb 3, 2009
    Posts:
    45
    I've modified the GSBillboard shader to have square billboards that are always facing the camera without curving around you or blind spots from certain angles like in the original. It also lets you add a bit of minimal size to avoid particles vanishing at long ranges.
     

    Attached Files:

  10. jimburn

    jimburn

    Joined:
    Apr 1, 2017
    Posts:
    64
    This

    float4x4 vp = UnityObjectToClipPos(unity_WorldToObject);

    Gives this error (Unity 5.6)

    Shader error in "Custom/Billboard': 'UnityObjectToClipPos': cannot implicitly convert from 'float4x4' to 'float4' at line 116 (on d3d11)
     
  11. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
  12. jean-noellevels3d

    jean-noellevels3d

    Joined:
    Apr 24, 2017
    Posts:
    4
    I have still this error too, whereas I changed for "float4" instead of "float4x4"...
     
  13. Nothke

    Nothke

    Joined:
    Dec 2, 2012
    Posts:
    112
    The automatic upgrader actually made a bit of mess

    Remove the autoupgraded line:
    Code (CSharp):
    1. float4x4 vp = UnityObjectToClipPos(unity_WorldToObject);
    and replace every following pIn.pos line:
    Code (CSharp):
    1. pIn.pos = mul(vp, v[0]);
    with
    Code (CSharp):
    1. pIn.pos = UnityObjectToClipPos(v[0]);
    That section should now look like
    Code (CSharp):
    1.  
    2.                     FS_INPUT pIn;
    3.  
    4.                     pIn.pos = UnityObjectToClipPos(v[0]);
    5.                     pIn.tex0 = float2(1.0f, 0.0f);
    6.                     triStream.Append(pIn);
    7.  
    8.                     pIn.pos = UnityObjectToClipPos(v[1]);
    9.                     pIn.tex0 = float2(1.0f, 1.0f);
    10.                     triStream.Append(pIn);
    11.  
    12.                     pIn.pos = UnityObjectToClipPos(v[2]);
    13.                     pIn.tex0 = float2(0.0f, 0.0f);
    14.                     triStream.Append(pIn);
    15.  
    16.                     pIn.pos = UnityObjectToClipPos(v[3]);
    17.                     pIn.tex0 = float2(0.0f, 1.0f);
    18.                     triStream.Append(pIn);
    19.  
     
    rboerdijk likes this.
  14. chantey

    chantey

    Joined:
    Mar 5, 2017
    Posts:
    49
    Little modification to have the billboards tilt as well as rotate by replacing the up and right vectors:

    Code (CSharp):
    1. float3 right = UNITY_MATRIX_IT_MV[0].xyz;
    2. float3 up = UNITY_MATRIX_IT_MV[1].xyz;
     
    efish likes this.
  15. CoderPro

    CoderPro

    Joined:
    Feb 21, 2014
    Posts:
    327
    Hi,
    When using this shader. Mesh position will be change. How can i use this while keep y original position of mesh ?
     
  16. LuckyMcCabe

    LuckyMcCabe

    Joined:
    Jan 7, 2022
    Posts:
    1
    Change this line
    output.pos = mul(unity_ObjectToWorld, v.vertex);

    To this.
    output.pos = v.vertex;

    That way the billboards will say on the objects vertex position despite the gameobject being move within the world.