Asset authoring

Drones and hero items

The fist step for creating the hero drone and its engines was making the blocked out models with collision hulls and testing their dimensions in-game. They had to be big enough to plausibly interact with the environment, carry common household items (like wrenches or cups) but small enough to comfortably navigate in human sized, furnished rooms.


Certain parts of the engines animate when the drone is moving around (rotor cages tilt, the thrust reverser opens, etc) so I rigged them right in Modo. The logic driving the rig was simple but helped the modeling a great deal as I was able to see problems right away.

The draft of the drone with the properller engine asset authoring Asset authoring BlockedOutPropeller 300x169

When I settled on the measurements I used the block model as a base for a high definition mesh. I love Modo’s pSDS implementation so I went with that. I was modeling the drone body and the propeller engine in parallel for a while since they had to be separate models which fit together. Once their interface was done I focused on the body to find the best method to add lots of details.

Adding small details, especially holes to a SDS model can be a real pain: keeping a clean topology is often a slow and boring process which discourages experimentation. I wasn’t sure how to avoid doing that so I figured I just bite the bullet and do it the hard way. I wanted to make sure I get things right the first time so I started modeling the details as separate objects, building a “design element library”. They were to be reused on all hero drone related meshes to keep the design consistent.


I made a few of them, screws, grates, ports, and started arranging them in a grid when it occurred to me that I could render them to a texture and place that texture on the base model. As a sort of dry run, before actually modifying the geometry to get at least a rough idea how things will look like. But then I thought, why stop there: let’s go all the way and use a displacement map to actually modify the geometry.

High definition detail AO asset authoring Asset authoring DroneDecorHD ao 300x300

This made life much simpler: I modeled the design elements and rendered them into several high resolution texture maps, including a 16bit displacement map. The high definition pSDS drone model got a UV set which put the details on the surface. Editing the UVs was really easy since the pSDS mesh had a relatively simple and clean topology, playing nice with the UV unwrap tool. An approximation of the displacement was visible in the realtime viewports while the real thing showed up in the preview render (and of course during baking). (It is worth noting that displacement is a very resource hungry feature: I had to upgrade to 16 Gb RAM and could have used a much faster CPU too as preparing the realtime tessellation and displacement often lasted 2-3 minutes on an i7 4770k. Thankfully after that even my feeble GeForce GTX 760 pushed ~15M polygons at 60 fps.)

asset authoring Asset authoring DroneDetails none
asset authoring Asset authoring DroneDetails nodisp
asset authoring Asset authoring DroneDetails full
  • Base SDS mesh
  • Details no displacement
  • Details with displacement

A separate UV set was used to put paint on the surface: stripes, warning signs and the like.

And with that I had a way to quickly iterate on the objects and experiment with different designs. However there was one more problem: Modo 801 didn’t have physically based shading so I could not set up and bake the surface properties Unreal Engine 4 was expecting. My solution to this was a simple plugin, creatively named “Unreal Shader”. Although technically it’s not a shader only behaves like one: instead of implementing a shading algorithm from scratch I made it a data converter which takes the Unreal specific surface properties and produces values for Modo’s old school shading. For example Unreal’s Metallic value goes in and a pair of Specular and Reflection Amount numbers come out.

The exact logic for the remapping was made by eyeballing reference images, showing a matrix of surface types. It took a few days of tweaking but the result is, while not a 1:1 match, close enough to work without issues.


While the baking can output individual surface properties it can also save textures with properties packed into the RGB channels. Typically I baked normal, color and “meros” textures, the latter containing Metallic, Roughness and Specular. More about the plugin can be found on its project page.


On the right is a comparison of one of the test matrices. Use the slider to compare the Modo and Unreal renders.

asset authoring Asset authoring roughness metallic unreal
asset authoring Asset authoring roughness metallic modo

When the high definition meshes were done came the modeling of the in-game objects. The pSDS cage frozen at a low subdivision level provided the base which was then cleaned up. The UV generation had the following steps:


1) Unwrapping the polygons and just dumping the polygon islands on top of each other.

2) Setting resolution weights, marking the polygons to indicate relative coverage scale of the UV space. The options are 0.01x, 0.25x, 1x, 4x. For example if a polygon gets the 0.25x classification then eventually it will cover quarter number of texels of what it otherwise would.


I used a Modo preset, a bunch of shader tree nodes, used in all my scenes to visualize the weights and approximate texel size. On the right is a view of one of the Hero objects: Orange is for 0.25x, green 1x, purple is 4x. (Although not seen here 0.01x is black.)

Visualization of UV coverage weights asset authoring Asset authoring UVCoverageWeights 300x270

3) Weighted packing: The UVs are laid out properly with the coverage multipliers factored in.

When the model changed, bits added or removed then the affected areas were unwrapped, coverage weights set, the UV set repacked and textures rebaked. While an iteration this way wasn’t particularly fast, most of the time is spent by the machine rendering, the manual work was kept at a minimum. By adjusting the rendering- and micropoly displacement resolution I could adapt baking time to my needs.

I used a script to fix Modo’s clumsy baking workflow. One of its features is applying a morph map during baking: it’s used to move parts further away from each other to prevent crosstalk when bits lie too close. The script also stored baking settings in meshes and managed the baking itself so after setting up the parameters once baking was just a single click.

The export to FBX was handled by my Layer Exporter script which saves the current layer or hierarchy, names collision hulls and does a few other things to make the output ready for Unreal.


The process was the same for other hero items like the charging station or the Minitel although their design didn’t need that extensive detailing so displacement was not used on them.


The workflow for props was similar with two major differences: the high definition models didn’t use displacement based detailing and multiple objects were baked into a single texture. The aforementioned baking enhancer script and the related morph map was used to move the meshes away from the origin. I just modeled several high-def and low-def mesh pairs, UV unwrapped them, set resolution weights, ran a UV packing macro and started the baking script to get the necessary textures.


On the right is the diffuse color texture for 9 tools. This UV arrangement changes every time the UV packing is performed which necessitates the bake of all textures, the export of all meshes and the import of all changed assets in Unreal. That sounds annoying but in practice it wasn’t that bad although I did everything manually.  It would be possible to make a script to automate both baking and mesh exports and Unreal now can automatically reload changed assets so the process can be made even more comfortable.

Tools color texture asset authoring Asset authoring Tools color 300x300

I grouped similar meshes together, for instance all cardboard boxes share a texture as do all the tools. Just as before when something changed (a new object was added for example) I just re-ran the UV packing and baking. When the texture resolution became inadequate to cover the increasing number of objects in the group I just increased it in the bake settings.


The furniture in the garage had the simplest workflow of all: no normal maps, no baked textures. The geometry is dense enough so hard edges and weighted normals can add all the details necessary. Unreal’s temporal anti-aliasing made the hard edges and small polygons presentable. Without a decent AA solution these models would have looked rather ugly.

In furnitures details are added as actual geometry asset authoring Asset authoring DroneAlone31 300x150
Antialiasing helps with dense meshes asset authoring Asset authoring DroneAlone32 300x257

The surface properties come from a small material library texture: it has several areas for each material and the unwrapped polygons are just dumped in the right place. Using this low res texture set (color, meros, etc) instead of material constants in Unreal allowed me to keep Modo and Unreal in sync, since they both used the same data source for rendering the surfaces.

The material library texture asset authoring Asset authoring DroneAlone30 300x176

Since furniture was static the objects also had a second UV set for lightmaps. There I also used UV coverage weighting to optimize lightmap usage: unseen polygons got the 0.01x multiplier (I didn’t remove them to avoid light leakage), hard to see place got 0.25x, areas which were receiving more elaborate shadows got 2x.

Notice: ob_end_flush(): failed to send buffer of zlib output compression (1) in /home/zoltanec/public_html/pages/wp-includes/functions.php on line 4552

Notice: ob_end_flush(): failed to send buffer of zlib output compression (1) in /home/zoltanec/public_html/pages/wp-includes/functions.php on line 4552