3D Modelling

Introduction

This page covers the basics of 3D modelling for use in video games, please see the links on the right.




Meshes (3D models)

In any 3D game there will be a number of 3D models representing the player, other characters, items and the area itself (house, forest, etc.), for example, here is a 3D model of a cottage:

A rendering of a cottage using Blender.

A 3D model is a mesh; a collection of polygons (often triangles) connected together with lighting and shading applied along with a number of textures that form the fine detail of the model (e.g. buckles, buttons, text).  Viewing the wireframe form of a mesh, as below, gives an idea of how polygons form the base structure of a 3D model:

Over the years, hardware has improved so much that 3D models nowadays can be rendered with many more polygons and parts that were once textured (i.e. 2D) are now 3D. A good example are the eyes of a character; in older games the eyes were just textures but in more recent games the eyes are 3D objects within the model.

As to give a good illustration of how 3D models in games have improved over the years in terms of polygon count and materials please see A+Start's video 'Super Mario - Low Poly (Evolution of Characters in Games) - Episode 1':

Be sure to check out the other videos in the series.

3D models do take up a considerable amount of memory and processing time so it's very important to create meshes with as few polygons as possible as well as with as few textures that can be managed. Textures can transform a mesh greatly but require a fair amount of memory so a balance is needed between a good looking texture and taking up as little memory as possible. While textures can be compressed using the usual image formats (.jpg, .tga, .png, etc.) when they are used in the game they have to be uncompressed and thus will take up the same amount of memory regardless of the format they were saved in. Because of this, a good texture is one that has as few pixels as possible but accurately represents the surface (e.g. skin).

You can create meshes using a 3D modelling program - please see the 3D modelling software section for more details - or you can download models created by other people, but be sure to look into any attached restrictions. Also check whether the mesh you are downloading or creating is representative of something that is copyrighted - such as a well known video game character or brand - which may further limit how you can use the model.

To get you started, here are some sites with 3D model downloads:

Free3D:

https://free3d.com/

Features free/commercial models. Doesn't require site account to download models. Check each model page for use restrictions.

Turbosquid:

https://www.turbosquid.com/

Features free/commercial models. Requires (free) site account to download models. Check each model page for use restrictions.

Sketchfab:

https://sketchfab.com/

Features free/commercial models. Requires (free) site account to download models. Check each model page for use restrictions. A really nice bonus of using Sketchfab is the interactive 3D preview of the models.

Internet Archive:

https://archive.org/details/3dmodels

Free models but mainly rips/recreations from commercial games. Doesn't require site account to download models. Check each model page for use restrictions.

Mesh lists

For a game to know which 3D meshes need to be loaded for a level it could make use of a mesh list. The mesh list contains the filenames of every mesh needed in a level and only needs to be a simple text file. A mesh list is needed for each level but if you append the level number to the filename (e.g. mesh_list_1, mesh_list_2, etc.) then the game can programmatically work out the filename based on the starting part (mesh_list_) and the level number. Then, when it comes to loading a level, the game can remove (if any) existing meshes from memory and then use the mesh list to load all the meshes needed for the level. As for creating the mesh list you can either fill in the mesh lists yourself or have the game (or external editor if applicable) generate the list. If the game/editor creates the mesh lists then it can look at the objects in the level and store the filename for each unique object (including objects spawned by other objects) picking from a master mesh list that links objects with the mesh filenames.

A more complicated approach that does not need a mesh list for each level and uses just the master mesh list for the filenames is to make use of global and local mesh indices. A global mesh index is used to access a mesh filename from the master mesh list. A local mesh index, however, gives access to an actual loaded mesh object; this means we have to convert between global and local mesh indices. The reason for having global and local mesh indices is that if, for example, there were a maximum of 50 meshes for the levels to use and a particular level needed 10 of them, the global indices will be incorrect (except by chance). To help visualize the problem, let's suppose our master mesh list looked like this:

[0] door.x

[1] bridge.x

[2] car.x

[3] player.x

[4] bad_1.x

[5] bouncer.x

[6] bad_2.x

[7] boss_1.x

[8] item_1.x

[9] cat.x

[10] bus.x

Any level can load any of the above meshes, whether it needs just one or all of them. The value to the left of each mesh filename is the global mesh index.

Let's say a level used the following meshes (the value to the left is the index used to access the mesh):

[0] player.x

[1] item_1.x

[2] bus.x

Thus the level would have three mesh objects, indexed from 0 to 2, which become the local mesh indices. Yet the global mesh indices would be 3, 8 and 10. This is why we would need to convert between global and local mesh indices.

As can be seen, global mesh indices are important so that we can use the same value to represent the same mesh for all levels. That is, look-up tables, objects and so on need to use the same set of values. But when it comes to rendering or collision testing or anything else that use the mesh object, the global mesh index will need to be converted to its local value.

Ideally, converting between global and local mesh indices should be done as quick as possible but this often means needing more memory. In these kinds of situations you need to get a good balance between speed and memory. I reasoned that speed was most important as there may be many objects that need to be rendered each frame but I could save on memory by using unisgned char for the mesh indices.

When loading the level data is a good opportunity to create the global/local look-up values, assuming that the global mesh indices are stored in the level data. You will then need to create two lists, so that it's possible to convert between global and local mesh indices, and vice versa, with the greatest speed. The list for converting between global and local will has as many entries as the largest global mesh index value plus one. It needs a bool to remember whether the global mesh index is being used as well as an unisgned char for the local mesh index (which will be zero for the first mesh, 1 for the second, etc.).

At the same time as populating the first list, the second list can be added to. The second list, which is for converting between local and global, will have as many entries as there are meshes in the level and will hold an unisgned char for each unique global mesh index.

For the example scenario given above the lists would be as follows:

List 1 (global to local)

[0] false

[1] false

[2] false

[3] true 0 (player.x)

[4] false

[5] false

[6] false

[7] false

[8] true 1 (item_1.x)

[9] false

[10] true 2 (bus.x)

List 2 (local to global)

[0] 3 (player.x)

[1] 8 (item_1.x)

[2] 10 (bus.x)

Now, if we want to convert from global to local we simply index list 1 with the global mesh index and we get the local mesh index value. To get the global mesh index from a local mesh index we only have to index list 2 with the local mesh index.

Notice that depending on how many meshes are needed in a level there may be gaps in list 1 which is the cost of using more memory for better speed. Also, both lists must be reset before setting the values based on the level data.

If objects can spawn other objects (e.g., an item from an item container) then the mesh of the object to be spawned needs to be loaded. To avoid loading delays while playing the game it's best to load all meshes needed when the level is created. This means having to go through all objects and checking if they spawn other objects (e.g. by checking the object's behaviour type) and then loading those additional meshes. Depending on your game, multiple additional meshes may have to be loaded for a single object, if the object that is spawned also spawns an object.

If you game has a built-in editor which lets you modify the levels then there are a number of complications that need to be considered. If a new object is added then its mesh will need to be loaded immediately so that it will show in the editor. If the new object spawns other objects then the mesh(es) of the object(s) to be spawned can be loaded when the level is created.

It is not necessary to delete meshes that are no longer needed when using the editor. If an object is added again that uses a previously loaded mesh then the mesh will have already been loaded ready. However, this does use more memory so it's best to clear out unused meshes when possible (for e.g., when creating the level from saved level data).

While on the subject of loading meshes it is a good idea to use some form of 2D graphic (e.g., a billboarding '!') to alert the user that a mesh could not be displayed because of an invalid index or if the mesh was not loaded.

3D modelling software

If you intend to create the 3D models yourself then you will need to use a 3D modelling program of which there are many. I started by using DeleD 3D editor (the free version) but found it very limiting. However, it did have a DirectX .X mesh file importer and exporter which was of great use at the time for the game I was working on. The .X mesh file format was commonly used with computer games as it is supported by Direct3D. It supports both animated and static meshes and the file itself can be in text form or binary (which takes up less space), as well as a compressed version to take up even less space on disk.

Because I was using 3ds Max 2013 at uni and found it to be much better than DeleD, I started to use it to create 3D models for my game. However, at first I could not find a plugin that was able to use the .X mesh format correctly until I came across the kW X-port plugin (below). You can download it from:

http://mjblosser.com/

I always keep a current version of the meshes in 3ds format (.max) and then export using the X-port plugin when the mesh is ready to be used in my game.

When I returned to 3D modelling some years later I looked at the cost of buying 3ds Max as I no longer had the free copy which since had expired but there was only subscription options, which I couldn't justify due to the high cost. I had previously used Blender and although my first use of it had been that it was quite difficult to work with the reality was that part of the problem was not having enough experience 3D modelling. So I looked at Blender again, which is still free (a donation of course is much appreciated) and not only isn't actually that hard to use (at least I think so) but has gone from strength to strength, incorporating support for 2D and 3D art, scripting, and video editing. You can read more about what Blender has to offer at:

https://www.blender.org/features/

Blender is available for Windows, Mac, and Linux, is open source, and can be downloaded from:

https://www.blender.org/download/

Contrast with 3ds max which currently only runs on Windows natively and isn't open source. Of course there are other 3D modelling programs but I strongly recommend to give Blender a try, especially if you are on a budget; there are lots of tutorials online.

3D modelling basics

It can be a daunting task if you have never done any 3D modelling before but it does help to have experience with drawing in 2D, whether on paper or on a computer. Like in 2D, an object needs to be broken down into smaller, simpler shapes. Then the simple shape can be modified and detail can be added to it. In 3D, usually you start with a 3D primitive (box/cone/sphere/etc.) and then move, scale and rotate its polygons and vertices. It's quite like starting with some clay and then molding it into a shape. And quite like how you can paint a sculpture in 3D you can add textures to change the colour and add fine detail.

To assist when modelling, it's a good idea to have set up in your modelling program a number of drawings of the object you want to recreate. These drawings can be your own perhaps from scanned in pencil work, actual blueprints or photos. What is important is the object is shown from multiple views and has measurements included if possible. These drawings can be applied to a number of planes as a texture and sized so that the measurements on the drawings match those of the 3D world (by checking against a box set to the size being checked, for example). By using these reference pictures it will greatly help with getting proportion correct as well as the shape.

A typical 3D modelling program offers multiple views of the scene; usually from a number of different sides (front, back, left, right, etc.) as well as perspective view. While the perspective view allows your objects to be seen from any angle and is a great way to see how the model has turned out, generally you should manipulate objects in the side views. The reason for this is that even though the perspective view is like how we see objects in real life (objects further from the viewer appear smaller than objects that are closer), on a computer screen we are actually looking at a flat surface and it's easy to wrongly place something in a perspective view. For example, two objects may look next to each other one behind the other but are actually far apart; the view makes them look close to each other.

As with any other software it's very important to save your work often and make backups (such as onto a flash drive or external hard drive) perhaps with with a version number so you can more easily track your changes. When modelling get into the habit of naming your objects and materials so that you can find them quickly. If you decide you want to make a new version of a particular object in your scene but don't want to delete the original one then you can just change its name (e.g. box_old).

Materials

As mentioned, textures transform an object giving them colour and detail but textures are only part of a bigger picture that are materials. A material describes the surface of an object in terms of how shiny it is, how reflective, how transparent, and so on. A material can include one or more textures (images) which add colour and other detail. So, while people often use texture to mean material they are not the same; a texture is an optional part of a material. Some surfaces are more difficult to represent using materials than others. Metal is a good example; if we just used a texture for a metal object it may look quite convincing but by adding shininess and reflection it would look much much more like metal.

Since textures are just 2D images we can work with them in 2D graphics editing programs such as Paint.NET, Photoshop, etc to prepare them for use in the 3D modelling program. As well as making your own textures you can also obtain textures online but you must first check that they are available to be used in your own projects and even so there may be a cost. Always read the site's fine print to check the restrictions on the use of the textures. Just because a texture is free (doesn't cost anything) it may not be royalty-free. Royalty-free usually refers to copyrighted works that can be used without paying but again, check for restrictions.

In my early days of 3D modelling I found cgtextures.com a great resource for textures but it has since rebranded to 'textures', available at:

https://www.textures.com/

While there are many other texture websites it's worth mentioning that an alternative to such sites is to use AI to generate textures, although the results can be a bit hit-or-miss and depending on what AI program you use the results may be too low resolution but should be adequate for a lot of use cases, and can be upscaled. AI generated textures are not a substitute for professionally created images but they do provide a means to model a scene quicker, provide inspiration or a starting point for other textures.

An example of a free AI site we can use is Stable Diffusion Online:

https://stablediffusionweb.com/

Stable Diffusion can also be installed to your computer and used offline.

For example, use the prompt 'brick texture' (without apostrophes) will probably come up with some good results and you could try 'cartoon brick texture' for more, well, cartoon-like results to fit the look of your game. Using 'texture' may not always result in a top-down view, which is often what we want for a texture, so try 'top-down' instead, and similar, you can specify 'side' for a side view.

Please also see the Blender dream textures section for more information on using AI to create textures.

However you obtain the textures it will often need to be prepared for use on a 3D model, at the very least it should be adjusted to a square size, which is a power of two (such as 256x256, 512x512, etc.). The reason for this is that it's easiest for the graphics hardware to work with and some (older) systems require a square texture size. As previously mentioned, when a texture is used by a game or other application it is uncompressed and therefore will take up the same amount of memory regardless of the image file format. However, the file format is still very important as to take up the smallest amount of space on disk as possible and not all image formats support transparency, which is another consideration. Common image formats used for textures are .jpg, .png and .tga.

UVW maps

Just as polygons and vertices have a position in 3D space as an X, Y, Z coordinate, materials have their own set of coordinates known as U, V, W. Usually, only U and V are used but there are circumstances when W comes into play. We can use UVW maps to determine how materials fit to an object and to more easily control how different parts of an object look. For example, if we had a box and we wanted each face to look different we could use a different material for each face or a multi/sub-object material and give each face of the box a different material ID. But by using a UVW map we can use a single material for all faces yet each one would look different; using a multi/sub-object material is really just a collection of materials.

Usually, we first need to generate the UVW map and this is done by adding an Unwrap UVW modifier in 3ds Max. Let's take the example of a box and add an Unwrap UVW modifier to it. The next thing to do would be to select 'Polygon' under 'Selection' and then select all polygons (Ctrl-A if using Windows). Under 'Projection' select 'Box map' as that most closely resembles the box. Then, under 'Edit UVs' click 'Open UV Editor...' which will bring up the 'Edit UVWs window'. At this point you will see the UVW map but it won't look too useful. To open up the map to a better form, select Mapping->Flatten Mapping... and click 'OK' and you will see that the map now has individual faces. At this point the UVW map is good enough for our purposes so we can go to Tools->Render UVW Template... which will bring up some options. The width and height are of most importance to change but in this example will be left as they are. Click the 'Render UV Template' and another window will open up with the UVW map ready to be saved. Click the (floppy) 'Save Image' button, enter a filename and remember to select a format type before clicking 'Save'.

Now we have a UVW map which we can edit in a 2D graphics editing program (note: normally you would remove the green lines in the map). I have a simple example below:

If the above texture was then added to the box as part of a material, each face of the box would be a different colour.

There is another, related, modifier called UVW map which you can think of as a more limited form of Unwrap UVW. If you had, for example, a cylinder and you gave it a material containing a texture you will probably find it doesn't look right. But if you were to add a UVW map modifier and set the 'Mapping' to 'Cylindrical' (with the 'Cap' option selected) you would see the material correctly wrap around the cylinder.

Viewport canvas

With more complicated objects, such as the head of a character, the UVW map when used in 3ds Max may contain many parts that need to be moved and rotated and there may be duplicate parts. While duplicate parts can be placed over each other it can be very time consuming to identify every part as well as to add detail to them. Fortunately, recent versions of 3ds Max have the Viewport canvas (Tools->Viewport canvas..., see below) which lets you paint directly on a 3D model without worrying about the UVW map. However, as much as the Viewport canvas makes life much easier when it comes to working with UVW maps for complicated objects, typically you will still need to do some 2D editing to the UVW map. For example, if your character's head is to have 'drawn on' eyes, nose and mouth it will be easier to add those details to the UVW map using a 2D graphics editing program than try to draw them on using the Viewport canvas. What's important is that the UVW map parts are the right way up and to scale.

Let's now go through step-by-step how to create a UVW map for a head. It's very important that the mesh is finished before adding an Unwrap UVW modifier because if you modify the mesh (e.g., move a vertex) after adding the Unwrap UVW modifier the UVW map will have to be created again. Once you have the head finished, assign a blank material to it and then add an Unwrap UVW modifier, select 'Polygon' from 'Selection' and select all the polygons. Then choose 'Cylindrical Map' from 'Projection' (as a cylinder approximates a typical head shape) and pick 'Z' for the 'Align Options'. Next, click on 'Open UV Editor...' under 'Edit UVs' to bring up the UVW map. At this point you will probably see a map that looks something like the head but would be difficult to add paint to. Go to Mapping->Flatten Mapping... and uncheck 'Fill Holes' and 'Rotate Clusters' before clicking 'OK'. You should see a large number of parts representing different portions of the head. Since we are going to be using the Viewport canvas to add most of the detail to the head the only part of the UVW map to be concerned with is the front of the face, since that will be painted on using a 2D graphics editing program.

When you first enter the UV editor all parts of the map will be selected as well as the polygons on the 3D model. You can click and drag to select parts of the map or just click on them, you can also click on polygons, edges and vertices on the 3D model. The 'Vertex', 'Edge' and 'Polygon' icons near the bottom of the 'Edit UVWs' window determine whether vertices, edges or polygons can be selected.

Find out where the polygons making up the front of the face are in the UVW map and then rotate the polygons in the UVW map the right way up. If there are duplicates of the front of the face in the UVW map then place them on each other. If need be, move the vertices in place while the 'Snap' option (the very bottom right of the 'Edit UVWs' window) is on.

Now you can close the 'Edit UVWs' window and open the Viewport canvas (Tools->Viewport canvas...). The Viewport canvas has a number of drawing tools that you would typically find in a 2D graphics editing program. It also supports layers which can be saved as a Photoshop file (.psd) which is useful not only to allow editing of in Photoshop but to preserve the layers while working in 3ds Max.

For this example we are going to use the 'Paint' tool; click on it and select 'Diffuse Color:...' A 'Create Texture: Diffuse Color' window will open which has settings for the map that will become the UVW map. For this example we only need to click on the '...' button under 'Save New Texture To' so we can enter a file type and select an image format (BMP in this example) before clicking the 'Save button'. Then keep selecting 'OK' until you are returned to the Viewport canvas (the Layers window will show and the head mesh will change colour).

As it is not possible to erase anything on the default, 'Background' layer make sure to create another layer (click the 'Add New Layer' icon). You can name the layer by double-clicking it and entering the name in the 'Name:' box that appears and then click 'OK'. You can also turn a layer on/off by clicking the lightbulb icon to the left of the layer.

In the 'Color' section of the Viewport canvas the current colour is shown (which you can click on to pick from the full range of colours or you can pick from the preset 'Black' or 'White' options or the '

Open Color Palette' to bring up more preset colours. Other important options are found in the 'Brush Settings' some of which are only enabled for some of the tools.

Clicking the '2D View' button brings up a window showing what is essentially the UVW map. As you paint on the 3D model you will see the 2D view filled in. You can also paint on the 2D view and see the results on the 3D mesh.

When you are finished painting you can either click the tool icon again or right-click in one of 3ds Max's views. You will then be given a number of options including whether you want to flatten the layers down to one or to save in PSD format to keep the layers. For this example, we will choose the 'Flatten layers and save the current texture' option and then close the Viewport canvas.

The mesh will then use the texture we created by painting on the 3D model. If need be we can open up the texture image in a 2D graphics editing program and add more detail to it or make corrections, save the texture and then it will update in 3ds Max.

Another useful tool of the Viewport canvas is the Clone tool which lets you clone from part of an object, the active viewport, another application or even the desktop. While the first two are covered by the 3ds Max help the other two aren't. Normally, after selecting the Clone tool you choose the source to clone from with Alt-click. To clone from another application, expand the Paint Behavior of the Viewport canvas and set the 'Clone Source:' to 'Screen'. The important thing here is that the 3ds Max program but keep focus when you Alt-click to select the clone source. To do this, reduce the size of the 3ds Max application and then Alt-click the program you want to clone from. To clone from the desktop then use the same technique by have the desktop behind 3ds Max and Alt-click to select the part of the desktop you want to clone from.

You can paint using an image by going to the 'Brush Images' section and clicking on the icon to the right of 'Color:', which will bring up the 'Viewport Canvas Brush Images' window. This window has presets along with Custom Maps which are your own images. Unfortunately, there is only one directory for custom maps which you can bring up by clicking the 'Browse Custom Maps Dir' button. Place a TIFF picture file in this location (only TIFF files can be used for custom maps) and then click the 'Reload Custom Maps' button in the 'Viewport Canvas Brush Images' window for the image to show so it can be selected. This window is where masks can also be selected after clicking the icon to the right of 'Mask' in the 'Brush Images' section of the Viewport Canvas. A mask is used in combination with the 'Color' image to set its transparency. For example, the mask image could be used so only a triangle portion of the 'Color' image is used.

Mesh ordering

One problem I have found with 3ds Max is there is no way to order individual meshes. In DeleD I was able to order the parts by cutting and pasting which was slow but at least got the job done. In 3ds I have to create a new file and then import->merge each part one-by-one in the required order. The reason why the order must be set is that some game engines (such as my own) expect the parts to be in order so that the animation can apply the correct animation data to each part.

DirectX mesh viewer

Before using a 3D mesh in your game it's important to thoroughly check that it looks correct from different views. It's quite easy, for example, to accidentally move the wrong polygon and this is one of the reasons why it's important to save frequently as there are only a limited number of times you can undo. It's also a good idea to save different versions of your 3D models as different files before making big changes, so that you have something to fall back on if need be.

If you have the DirectX SDK installed on your computer then you should have the .X mesh viewer installed. By opening a .X mesh file (in Windows explorer, for example) the viewer will load the model allowing it to be checked over in a view close to how it will look in your game.

3D Modelling Projects

Please go to 3D Modelling Projects page.

Animating with 3ds Max

Please go to the Animating with 3ds Max page.

Blender dream textures

AI can be used to generate textures and if you're using Blender then you can use a free plugin called Dream Textures to produce textures within Blender, making it easier to model a scene, especially if you want to quickly put together a scene to get an idea how it looks. Please see this tutorial to get you going:

Please also see this video for some tips:

When I installed Dream Textures and tried to enable the plugin in Blender V2.8.1 I got a traceback error but found this video offering a solution:

I didn't use the solution since I wanted to try the newest version of Blender (V3.5.1 at the time) and hoped that wouldn't have the same issue, indeed, once I had installed the new version of Blender and the plugin again, I was able to enable and use the add-on in the new Blender version.

Tips

It is important to name objects in a 3D scene so that you can quickly identify parts of a scene and it also helps with distinguishing objects to be imported from other scenes.

All content of this and related pages is copyright (c) James S. 2013-2023