LUUG 14 took place a few weeks ago, and as ever it seemed to go down pretty well.
We were treated to talks from George Buckenham, who gave us a great insight into the world of shaders, something a lot of us only deal with on a ‘drop-down menu on a material’ basis, and Charles Burt from Colossal Games, who showed off the recently released Commando Jack.
We also had one of our most successful ‘open-mic’ sessions, with more volunteers than ever, and I’ll just go out there and say it, it included the best content we’ve ever had as part of our open-mic session.
A neat trick that came up involved vertex colours and dynamic batching. It’s one of those simple things that sounds more complicated than it actually is to setup, so I thought I’d just take the time to write it up and provide an example scene.
Looking worriyingly similar to a project I’ve been working on for a little while, but with added charm and character, Pop Cubes is a puzzle game where the player has to remove matching sets of coloured cubes from a series of columns and rows.
When creating a game like this, and particularly for mobile, you want to get around the issue of having lots of repeated mesh geometry that has simple colour variations.
Changing the colour properties of a material at runtime leads to Material instancing, which breaks your batching. Setting separate materials with individual colours means you can will end up batching different sets, which can be beneficial, but when it comes to a scenario where you have 6 cubes left, each of a different colour, you’re still having the same draw call overheads as you would with completely different meshes. Sure, it might not sound like a lot, but when you’ve got your head in ‘optimisation mode’ you tend to try and cut it down as much as possible. I don’t know about you, but I kind of get off on reducing draw calls…just me? Oh well… HERE’S THE SCIENCE PART.
The Magic of Vertex Colors.
What Mike is doing with Pop Cubes, is to change the vertex colors on the mesh itself, it requires a shader that will allow you to edit the vertex colours, but thankfully, you can get hold of those easily. Alternatively, you can check out Georges’ talk and then make your own, right?
What you need
- A shader that allows editing of vertex colours. There are a few on Unify
Unify VertexColor shader
- A load of gameobjects that share the same mesh and material.
- Dynamic batching enabled (Edit > Project Settings > Player).
- A script that changes the vertex color of the mesh.
- Another script to cycle through the colours and apply at run-time, just to be cool.
I’ve put everything that you need into an example tutorial scene.
The main script in this scene is called VertexColourTest.js (yes, JS, get over it).
Essentially what it does it take the mesh from the MeshFilter component, take the vertices of that mesh, then apply a colour to the mesh. Definitely more complicated that I’ve made it sound, but this is about all we need to know for now.
It’s definitely possible to apply different colours, and colour lerping based on vertices, but we’ll stick to standard colours here. You’ll notice though that the vertices are kept in an array, so if you did want to apply a colour per vertice, or lerp between colours, you need to add them dependant on their position in the array.
Based on the fact we’re passing in the colorToChangeTo, we need another script to determine what that is.
In my demo project I have it running off a different script so that we can determine what these colours are seperately, and if we wanted to, at runtime. It’s a basic built-in array with some colours assigned, and a quick colour picker using Random.Range.
It does some setup stuff on start. Essentially it just gets all the blocks, then caches a reference to the VertexColourTest script we are going to be accessing at runtime.
You can set the colorsToChooseFrom in the inspector to whatever you like.
Hitting R during at runtime should go through and change the colours without affecting draw calls.
Hitting E will cause an explosion to show objects reacting to physics, but still maintaining batching.