Resources to learn how to make billboard assets

I am making my own custom billboard/impostor system that generates billboards at runtime based on buildings the player makes from many different parts. I can make the images needed now.

I set up a LOD group that simply goes LOD0 is the original mesh, then LOD1 is the billboard impostor. LOD1 requires a renderer and the best way to go seems to be the billboard assets. I’m having trouble making a billboard asset (which seems to be the most performant way to go). I looked at the Unity documentation on billboard assets but it is very limited. I need a bit more data to figure this out and did not find anything elsewhere that includes clear examples or example code, etc.

So two questions from this:

  1. Is billboard asset the way to go or do you recommend a different approach? (using a different type or renderer, making a custom shader, etc.)

  2. How do billboard assets get made? Any data or link to a good resource.

I’ve written some articles on how to use Unity’s Billboard Renderer and customise the shader. There isn’t one on creating Billboard Assets yet, but I’ll answer any questions you have. This is mostly worked out from experimentation.

Using a Billboard Asset handles displaying the correct texture for each direction automatically, although it’s designed for objects being viewed from the side and not above. Your billboard can have between 1 and 16 different directions, due to the texture coordinates for each one being stored in an array.

float4 unity_BillboardImageTexCoords[16];

You can set the texture coordinates either in the BillboardAsset’s .asset file or in C#. If you don’t have a billboard asset to work from, you can import a SpeedTree7 sample and use that as a reference. I believe I got mine from the old Unity Standard Assets package, but if you can’t track that down then you could look in the newer ones.

For example, if your texture is four images arranged vertically, the .asset file should have this:

imageTexCoords:
  - {x: 0, y: 0.25, z: 1, w: 0.25}
  - {x: 0, y: 0.75, z: 1, w: 0.25}
  - {x: 0, y: 0.5, z: 1, w: 0.25}
  - {x: 0, y: 0, z: 1, w: 0.25}

X and Y are the corner of the uv for each image and Z and W are their width and height.

The width, height and bottom values defined outside the imageTexCoords are for the actual size of the billboard in the game. The bottom value can be used to raise or lower the billboard, so you can have a tree billboard with its roots below the ground.

In C# you can create a Vector4 array with the texture coordinates and apply them with this:

Vector4[] texCoords;
// texCoords = new Vector4 { ... };
billboardAsset.SetImageTexCoords(texCoords);

You may need to change the indices and vertices as well. For a single rectangle made of two polygons, you can use these values:

vertices:
  - {x: 0, y: 0}
  - {x: 0, y: 1}
  - {x: 1, y: 0}
  - {x: 1, y: 1}
  indices: 000001000200010003000200

Finally, you can add a BillboardRenderer component to a GameObject and assign your BillboardAsset.

To use your texture, assign it to material on the BillboardAsset either in the editor or in C#:

billboardRenderer.billboard.material.mainTexture = texture;

Make sure not to apply it to the BillboardRenderer. This is only there because it’s inherited from Renderer and will not be used.

billboardRenderer.material.mainTexture = texture;

You can also set the bump map with this:

private static readonly int BumpMap = Shader.PropertyToID("_BumpMap"); // Define once outside a function
billboardRenderer.billboard.material.SetTexture(BumpMap, normalTexture);

Changing the BillboardAsset used by the BillboardRenderer during runtime causes issues, so if you want animation then you can store each frame as a new column in your texture and change the UV offset of the material. You’ll also need to reduce the Z value in imageTexCoords to 1.0/(numFrames)

Let me know if you run into issues or have any other questions.


Footnotes:

Articles archived for future readers: