Wednesday, January 5, 2022

Color to vertex color

For some of the assets in our game we use a wave shader to give the illusion of wind. We use a basic setup which uses a gradient starting from the pivot up to scale the wave amount. But some objects were a bit more complex and needed a custom gradient. If the texture didn't need alpha we could use the alpha channel to store the gradient, but that could mean we would have to add an additional uv set and above all, some did use alpha so the channel was already taken. We decided to start using vertex colors to store our gradient in.


So how to get the colors onto the vertices? Creating a texture and sampling from there was a possibility, but a lot of manual work creating an extra uv set and a texture would be needed. Since the gradient often aren't that complex, we decided to create the color set based on a ramp node which could be removed after the sampling.

After the artist selects the object they want to assign the vertex colors to, a temp node system is set up around the existing material. A controllable blend node is added because our artists wanted to be able to switch back to the original texture before committing to the vertex colors.

Version 1.0 hooked up the network and then gave the user a confirmation dialog telling them to do their changes and run the script again, which would detect the presence of the temp nodes and proceed to convert the colors to vertex colors. But that meant artist had to dive into the channel box, find the nodes, open the texture window and set the correct settings etc. So for version 2.0 we added a bit more control, the user can edit the blend, the ramp type and the ramp color as well as launch the texture editor from a single window. 

The script also creates a temp uv set based on the camera. These can be tweaked afterwards. I can imagine version 3.0 also has a button to create uvs from camera at any moment since it's easy to miss when you start the tool. After the user presses the Transfer color to vertexColor button the script loops over all vertices and gets the corresponding uv values and then samples the color at that point and assigns it to the vertex
               
    float $color[] = `colorAtPoint -u $UVvalues[0] -v $UVvalues[1] $rampNodeName`;
    polyColorPerVertex -r $color[0] -g $color[0] -b $color[0] -a 1 -cdo $vertex;


After that the temp nodes are removed and the original color node is hooked back up. Below a video of the flow and the result in Unity








No comments:

Post a Comment