Let’s Talk About Modularity

Imagine the following scenario: You are an environment artist for a game company. Their newest game takes place in a city, and you are tasked with building the interior of an office building. You have plans and dimensions and the level is all blocked out; now you have to build the actual assets. What do you do? Your first reaction might be to open your 3D software of choice and start building an office building. After all, that’s what they told you to do, right? But while that might seem like the easiest choice, it’s actually going to cause a lot of headaches for both you and the rest of your team. Why is that? Well, first off, environments aren’t always set in stone. What happens if a level designer comes to you and tells you he wants a hallway moved, or a window added, or an entire section of the map laid out differently? That would be pretty difficult to change for you and would, at the least, take a long time. Another reason is the textures. Modern games have staggeringly good graphics. Textures are extremely high resolution with a lot of detail. Since your entire level is one mesh, that means you either need one huge texture for the entire thing or many textures. Neither of those is an ideal answer. So what is the solution? Well I pretty much gave it away in the title of this post — the solution is modularity.

“What’s modularity,” you ask? Modularity, in the most simple of terms, is when you have a set of small pieces that can fit together to build something larger. Consider this: instead of building an entire office building, you build a set of pieces, such as walls and floors and ceilings, that can fit together to make an office interior. That way, if you were asked to extend a hallway or add a window you could simply shift a few pieces around or replace them with other pieces without having to remake any assets. It’s almost like LEGO bricks. Let’s take a look at a modular kit I made a few years ago as an example:

streets_wire
Rather than building the curved piece out to be a square, I have a separate piece that fits there that I can use to tile with the ground. But I’ve included that in a separate kit (or, rather, a separate part of the same kit) and so I’ve omitted it here to avoid confusion.

If you can’t tell, this kit is for a set of roads in a city. As you can see, all of the pieces fit together, allowing a level designer to build any street layout they desire using only seven pieces. But these pieces weren’t simply built without any forethought. The key to building a successful modular kit is to use a grid. The easiest, and most common, system for building grids is to use base-2 numbering (1, 2, 4, 8, 16, 32, etc.). This ensures that the dimensions of every piece is in a perfect ratio with every other piece, allowing them to snap together. It’s also important to be consistent in your sizing. Every piece in this kit has a 1024×1024 unit footprint (16×16 feet given this environment’s unit scale) meaning I could plan any street layout and be able to recreate it as long as I used a square 16-foot grid to do so. The height of each piece is important as well, and should be factored into the grid system, too. In this case, there are two distinct “surfaces” in my kit: street and sidewalk. Normally, that wouldn’t matter except they are at different heights. So in order to maintain my grid I have to be aware of that when changing altitudes.

Take a look at the ramp piece, in the top left. That piece has a rise, or vertical change over its length, of 192 units (again, a number that fits into our grid). That does not mean that asset is 192 units tall. Instead, it means that the sidewalk on one end is 192 units above the sidewalk on the other end, and the same thing for the street. This is important, because that piece will be matched with normal, flat pieces from this kit at both the top and bottom. So in order for it to be successful it not only needs to have the same footprint as all of the other pieces, it needs to have completely vertical edges that match up with our other pieces. Because of this I cannot simply rotate one of my existing pieces to fit that gap (though I could skew one of my existing pieces, which I did, but its important to double-check the fit of your pieces when working). I also made my street exactly 16 units lower than my sidewalk. This allows me to use my grid to snap objects onto the surface of the road.

This also brings up the issue of pivot points. If you take a look at the image below, you can see the pivot of one of my street pieces is in the corner, aligned with a vertex on the sidewalk. This is because my sidewalk is supposed to be at ground level. When building a modular kit, it is good practice to place your pivot both in a corner that contains tileable geometry (which means if you have a wall piece with relief, make sure it’s in a corner that contains an edge you intend to tile with other wall pieces and not just in a corner of the object’s bounding box that leaves it floating in space) and on ground level. This will ensure that you can position your pieces by simply snapping their pivot points to your grid instead of having to deal with manual placement or vertex snapping. For most assets this would place the pivot at the lowest point on my object, but because the street surface is below ground level I have it at the topmost position instead, which will make it easy to position the pieces in this kit with other environmental pieces.

pivot

You might also notice that I have three straight pieces in my kit, and that they don’t all seem to have the same subdivisions. In fact, why do they even have subdivisions? Couldn’t I achieve the same shape with fewer polygons? Well, yes, I could. But modularity isn’t just in the models. Our texture is modular as well, and it’s important to consider that when building your pieces. Let’s take a look at our shaded pieces to see what the differences are:

streets_texture

This is the exact same set of pieces as above, but with their textures applied. As you can see, the three straight pieces all have differences (one is normal, one has a sewer grate, and one has caution tiles in place of the regular sidewalk tiles). In addition to that, you might notice that the repetition in each piece matches up with the repetition found in our subdivisions. That’s a clue into how this modular system works. Let’s take a look at our diffuse texture:

street_diffuse

As you can see, this single image contains a texture for every surface found in our kit. We have four sidewalk variants, two edge variants, and two road surface variants. Now let’s take a look at the same texture, but with our UV grid applied:

street_grid

Ah, now the mystery is revealed. The edge of every part of this texture aligns either to a grid line or a half-grid subdivision (not shown, but take my word on it). Not only that, but any “interchangeable” pieces, such as the sidewalk tiles, have the exact same dimensions. This brings us back to the models’ subdivisions. If we compare the UV layouts for the “normal” straight road and the “caution” straight road, we can start to figure out the difference:

grids

The normal road, on the left, is split into three sections: one for the street, one for the trim, and one for the sidewalk. Each section is repeated 4 times, giving us 4 repetitions in the texture. That’s why each road segment is exactly 4 panels in length. This is where geometry is so important in creating modular kits. Rather than creating a road texture that has 4 light bars, I was able to create one with only one light bar and repeat it 4 times, thus saving myself room for other features at the cost of only a couple polygons. It also opens me up to variations. If we look at the wireframe for the caution piece, we can see that the middle two segments are subdivided into two smaller segments of their own. This is because each section of the base road object spans two sidewalk tiles. So in order to move the UVs of just one tile from each section into the UV space that contains the yellow striped texture, we subdivide that piece and separate the two tiles. Now we are left with two tiles that are independent, allowing us to position them separately. We could have, alternatively, created the pieces with more subdivisions overall and not need two tiles next to each other in the texture, but since we had room we could afford to do so and use less polygons. These types of decisions are important and will not always be the same for every project. And if you plan things well they may be negated, such as was the case with the sewer grate. Since I made the texture for that piece have the exact same dimensions as the light bar pieces, I can swap between the two without modifying my geometry. The only difference between those two road variants is the UV layout, which is nice because changing your UVs doesn’t change how costly an asset is to render.

It’s also important to consider the way your textures may be warped or stretched on your objects. Because these textures are not unique to any single asset, we have to consider differences in each mesh that may lead to unexpected variations between them. In the case of the 3- and 4-way road pieces, we have sidewalk corners that aren’t present anywhere else. These corners result in trim polygons that are irregular trapezoids, which was causing stretching in our rectangular textures. To combat this, I added edges to these polygons that broke them into rectangles and triangles. This allowed me to control the warping by only allowing it to occur on the very side of the texture, a location that is much less noticeable when deformed. It’s issues like this that are common when building modular kits and is a reason why this is one of the few cases where you will be building UVs to suit your texture and not the other way around.

Nothing about the way these assets were built is a coincidence. It’s essential to pre-plan when building a kit like this, and not just the look. The biggest rule of thumb when creating a modular kit is that you cannot set rules. You must not build a kit with the expectation that you can sit down with someone who is implementing it and tell them what pieces should and should not be put together. “Obviously,” you say, “no one is going to try and pair a street piece with a ceiling piece, so why do they need to be the same?” This may be true, but they will have to build both streets and structures in the same environment, which means they need to fit the same grid. They might even find an unorthodox use for the ceiling piece that somehow allows it to tile with a street piece. It’s things like this that make freedom essential in modular kit design. Following a pre-defined plan and incorporating freedom into that plan also allows for future developments using your kit as a base. Say I hand off my street kit to a level designer, and they realize they need a more gentle curve for part of their map. Because all of my assets are built using a grid, and because my texture is tiled in a modular way, it would be a piece of cake to create a new road piece that would tile perfectly with all of my other pieces.

It may seem daunting to create a kit such as this, but it is an essential tool in the creation of any game, movie, or other large-scale structure. The principles that go into making a set of street pieces could just as easily apply to buildings, or machines, or characters, or even two-dimensional and physical art. Modularity is a concept that is important in nearly every constructive medium and is, sadly, often overlooked when learning and developing your own workflow. The next time you have a project, take a minute before you start and consider how it can be broken down into more manageable pieces. It just might make the process a whole lot easier for you and your team.

There’s so much more to say about modular workflows such as this and everyone has their own processes, so if you have anything else to say about what is arguably one of the most important developmental tools at an artist’s disposal be sure to leave a comment.

Advertisements
Let’s Talk About Modularity

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s