A project I have been working on in Unity for a few weeks, to give Ghost Games (EA) some ideas about new ways to customise your car in a racing game.
I used Unity3D to write scripts and shaders (over 4000 lines), 3ds Max to UV unwrap the car they had provided (and do environment modelling), and Photoshop to get other people’s sticker images to work nicely.
There are 3 very different algorithms going on for decorating the car:
The most simple is spraypainting – I raycast from the mouse along the view vector when the left mouse button is held down, and record the ray if it hits the car. When the mouse is let go, I interpolate lots of new rays from the stroke. At every point on the car a ray hits, a circle (textured quad) is placed on the UV coodinates of that point. These are all rendered to a texture and applied to the car mesh.
The robotic “factory spray” is slightly more complex – I have a vertex shader that moves the car vertices to their UV space – instead of position (x,y,z) they are (u,1,v). The world space position is passed to the fragment shader, along with a random point on the car (determined by a particle system emitting from the mesh). I colour the “UV space” vertices based on the distance between the fragment 3D point and the “paint point”. This mesh is then rendered to a texture. The problem with this approach is UV seams are visible. Some kind of bleeding/ padding would fix this.
The most difficult thing for me was the stickers – I created an entirely new mesh construction class to deal with Unity’s Mesh vertex limit of around 60,000, which the car exceeded. I have a box you drag around the car, and when you click I transform all the vertices in the mesh construction class by the the box’s model matrix. This allows me to cull the mesh easily, by checking which triangles are in the mesh and deleting them (another thing my mesh construction class was made for – Mesh triangle lists are not the easiest thing to work with!). I use the box to redo the UVs in the culled mesh, making them “projected” from the box’s z axis. I got the idea from here: http://blog.wolfire.com/2009/06/how-to-project-decals/
For the “sticking” animation, I have a uniform float in the vertex shader that allows me to lerp between the a plane on the box’s projection plane, and the final positions, using the u coordinate. The vertices are slightly offset from the car’s surface along the normals to prevent z-fighting.
The project’s not due till tomorrow, so I’ll refrain from putting the application or code up for now!