Starting to Model for TDM
Most modelers on the team use Lightwave or Blender. Anything that can save in either .lwo (prefered) or .ase format is acceptable. However, there is an ASE exporter available for Blender at the Doom3World forums, and katsbits.com has some import/export scripts for Blender, otherwise ask somebody in the Dark Mod Forums. 3ds Max can be used to model and import/export .ase files.
Making the Model
You will need to make, for each individual object:
- a highpoly model. There's no poly limit to this--make it as detailed as possible.
- a lowpoly version of the same size and basic shape (see dimensions below).
The detailed version is used, by Doom 3, or another tool such as ORB or xnormals, to generate a normalmap with all the details on it. This normalmap is then used with the lowpoly model to fake higher detail. See Renderbump for more information on using D3 to generate normalmaps.
- Lightwave: Your model needs to be tripled before being used in game ( + ), or D3 will spit out tons of warning messages.
- Blender: The ASE exporter will automatically convert all your faces to triangles.
- 3dsMax: turn to poly, max sides 3, turn to edit mesh before export.
Model and Texture Dimensions
Aim for less than 5000 polys for significant AI, and less than 500 for most common objects. Testing has shown that rendering polys does not slow down FPS much if they don't cast shadows. It is therefore ok to have a higher poly model if you create a low-poly shadowmesh built into it (a 1000 poly model can often have a decent shadowmesh for 300 polys). Generally, objects that might only be used once in a scene (like a well) can have higher polys, but objects that might appear many times (like lights or chairs) should have less than 500. Round objects (vases, plates, etc) should have a minimum of 8-10 sides (depending on the size of the object) to appear fairly smooth. Less important parts of an object (like the legs of a stool) can have fewer sides to keep polys down.
About 200-300 polys is the average for most smallish size props, like weapons or lights. Even our wide bookshelf model is less than 250 polys, so it's not always dependent on size.
You don't generally need to sacrifice detail just to get a model less than 300 polys, however.
Texture sizes go in powers of two: 2, 16, 32, 64, 128, 256, 512, 1024, 2048. D3 will automatically rescale TGA textures that are not in powers of two, which could stretch your texture and waste processing time (and look blurry as well). Note that the dimensions of DDS textures absolutely have to match powers of two, otherwise they appear black in-game.
The following convention should be used for naming all new model additions to TDM (many existing models do not follow this convention, and over time effort will be made to update them). Following this convention will make it easier for mappers to find the models they want in a long list--if they are looking for a chest, they want to look under "c" for chest, not "w" for wooden_chest.
- Object Type descriptor first. Mappers are generally going to search by object, so they will want to find all objects of a similar type grouped together. It's a window, a plate, a chest, etc. Don't bother duplicating the name of the folder, however. If your object is inside the "lights" folder, then you don't need to call it "light_torch_wood".
- Material descriptor next. This may be appropriate, but remember that different textures can be used on the same model, so calling something "statue_marble" could be misleading if it also has a metal texture.
- Size descriptor next. This is primarily useful if there are multiple versions of the same mesh, like "statue_lion_large" and "statue_lion_small".
- Quality descriptors next. Optional. Remember that skins might exist. However, descriptors like ornate, plain, etc, can help mappers.
- Number Increment next. Adding a number to the end is useful if there are likely to be more versions of the same kind of object.
If establishing precedent (creating a new Size descriptor, e.g., "huge"), try to avoid ambiguity and unnecessary overlapping with other descriptors (e.g., "enormous"), and set a good example others will follow.
This name omits all but the mandatory descriptors. If valuable information about the object can help differentiate it from others, optional descriptors may be added. If it is indeed generic, this name is fine.
This highly descriptive name omits a Size descriptor.
It should be noted that a given descriptor can use more than one word if needed, for example, lamp_wall_ (uses two object descriptors), as long as it either follows precedent or establishes a good one.
Where to Save your Model and Textures
Models should be saved in the models/darkmod tree. See Model Folder Structure for specific information about where to put things.
Grid Alignment and Origin
Please make sure your models are grid-aligned (the bottom of the object rests on a grid line in your modelling software). If they don't, it can be difficult to get the model to sit on the floor or other surfaces in the editor. If the object is likely to have other things placed on top of it (tables, shelves, etc) then it is also helpful if the top surface is grid-aligned as well.
Keep this in mind for all objects. The back of a door handle should sit very close to flush with the grid so it'll align well with doors. The back of a torch should be right on the grid so it doesn't sink into or float away from a wall. objects like chests are made of three different models; A chest, a lid and a lockbar. The chest can be flush to the floor, but the top might not align to the grid, it's best to move the verts to the closest grid line in this case. The lid's pivot needs to be at 0 in the z plane, so the bottom of the lid also needs to hit a grid line so it can sit flush with the top of the chest and not leave a gap. The lock bars pivot also need to be flush with 0 in the z plane (for rotation pivot) but it need sto also align on the grid so it'll match up closely to the lockbox.
Re:Grid size, testing in your 3d program: An easy way to check your grid is to open a new file in DarkRadiant, choose a large grid size and drag out a cube brush, choose the next smaller grid size and drag out another brush, do this with 3-4 grid sizes. Make each cube as small as possible for that grid size. No need to texture them, place them all close to each other. Now select all of them and choose file/export as obj, this will make them an obj file that can be imported into most 3d programs, if not you can convert it with a program like Accutrans into a 3ds mesh and import that. Now these cubes are in your 3d program, do they align to the grid? Don't move them, if they don't align, instead adjust your grid size to match them. In 3ds Max you do this by choosing the customize menu/grid and snap settings/home grid tab/ and for grid settings use a number in the power of 2, 4, 8,16... (you can use 1, or .5, or0.25 for smaller grids). This sets the alignment equal to DR's grid. 3ds Max is natuarally set at 10 which doesn't DR grid at all. You can set the major grid lines to something you are comfortable with, 4, 8, ect...That just makes a darker grid line every 4 or 8 lines. Now any verts placed on a grid line will match the grid in DR.
Re: Origins. D3 uses the origin of the model to determine physics for movement--moveable objects will rotate around the origin when they are bouncing around. Any model that will likely be made into a moveable object (basically any unattached object smaller than a chair) should have its origin where its center of gravity would be. The frob trace is also done to an object's origin. Typically a player will look at the center of an object to frob it, not the bottom, so having the origin in the center of moveables makes them easier/more realistic to frob.
Large objects that are not likely to be moveables, like desks or wardrobes, can have their origin at the bottom of the object, for easy placement on the floor. An exception would be something like trees that an author might possibly sink into the ground far enough to reach outside the world. In this case have a centered origin would be best so the origin stays inside world.
Objects that might be designed to swing or rotate (like a hanging sign) should have their origin at the point of rotation.
Collision models should be used on most objects for several reasons. They can help simplify pathfinding databases for AI and weapons, they also simplify the shape of the object so it can be moveable. If an object is going to be static and not move, like a pillar, it's collision model can be as complex as you want, however this defeats the purpose of a collision mesh. Generally you want to make the collision mesh as simple as possible while retaining the basic shape of the model. This will guaranty that arrows will bounce off of it, or stick to it in a realistic way. If the mesh doesn't match the original object close enough you will get things like arrows bouncing off the air next to the model, or arrows that go through the model.
Collision models must be exported with the original object mesh. This makes them hard to see in the editor, but the collision surface can be toggled so it's not a problem. Collision meshes won't be seen in game, nor will their effects if done properly.
A static object can use one or more collision models, the purpose of this is to apply different materials to the colllision model. For instance, the generic Doom collision sounds like stone when an arrow bounces off of it, and arrows will always bounce off of it. However Dark Radiant allows the use of material specific collision shaders. So a chest can be made of metal and wood, an arrow will bounce of the metal parts and stick into the wood parts. The number of collision meshes on a static object is undetermined but should be limitless. This is a good way to simplify collision while retaining the objects material types. A collision model overrides an objects shader properties (the image will be the same but noise and collision props will not work), so if you export with collision try to seperate it into materials.
Examples of collision shader names: //base/tdm_collision_wood, //base/tdm_collision_ceramic
Moveable objects must have collision models unlike static objects. These meshes have to be very simple. Currently the exact specs of a moveables collision mesh are under debate. You will often see these specs stated as less than 16 polys, no concave polys, ect... But it is possible to make workable collision models with both of the above rules broken, however it is very unlikely and you are lucky if it works. Most of the time if you do break those rules you will get an unstable mesh that will fly across the room when frobbed, sometimes even resulting in SHAS (Sudden Heart Attack Syndrom) when the player dies without warning. So sticking to those guidlines is usually best and can still result in a decent collision model in most cases. Multiple collision meshes have been successfully exported also, however they only use the material type of the first collision model loaded, this can also lead to instability. Generally simple shapes work best, just try to make it fit your object as close as possible.
Shapes that work well for moveable collision models are cubes, pyramids and cylinders (up to 7 sides seems to work well). An L-shape of 2 collision meshes has proven to work with chairs (basically 2 cubes).
For an idea what will work look at models in the model viewer. Of course a crate has a cube, a gear will have a cylinder, a lamp might have a pyramid. Objects that use unconventional shapes that defy the rules above are keys and the silver teapot.
Shadow meshes are similar to collision meshes. Basically they are just to simplify shadow casting, this can have great benefits to maps, especially if there are multiple lights hitting the object. Doom 3 can handle an enormous amount of polys on screen without flinching, however throw in a couple lights and you can bring it to its knees. This is where the importance of shadow meshes really counts. Doom3 calculates how each triangle is hit by a light and what shadow that triangle will cast, this is no big deal with one triangle, or one light but in a map you are sure to have many lights and many polys. These calculations are done every frame.
We have done tests with 100,000 polys and one light, FPS will be around 60. Add a second light and the FPS will drop to 45, add a 3rd light and FPS will drop to 30 (rough estimates)... So if your objects are 100,000 polys but your shadow meshes only equal 50,000 polys you have already cut the lag in half.
All materials and/or objects (including game created func_static meshes) can have noshadows set to 1. While this really helps performance it can look very bad and have bad effects on gameplay. Darkmod is a game set in very shadowy places and the player uses shadows for stealth, the major gameplay component, hence the importance of shadow meshes once again.
When modeling the shadow mesh try to match the basic shape of your object as close as possible while using as few triangles as possible. Say you have a pipe object that has 20 sides and is very round. You could make a shadow mesh with only 4 sides and for the most part the shadow would look the same, the noticable difference would be that the ends would cast sharp corners, but often times these can be hidden within another shadow and wont be noticeable in game at all. Even the shape of the pipe going into a wall would mask the bad edges of the shadow.
Shadow meshes must be exported with objects and their collision models. Unlike collision shaders the shadow shaders do not override the objects shadows. So when making a model that uses a shadow mesh you need to use material shaders for the object with noshadows on it, this has to be set in the material file (materials/.mtr). However do not go and start adding noshadows to all the materials as some objects or terrain might need shadows. Instead copy/paste the shader deffinition into a new .mtr file, give it a new name and add noshadows to it, that way the original material doesn't change. You should also use NoSelfShadow which will stop the material from casting shadows on itself.
There are 2 material shaders for shadow meshes, they can be combined and both used for one model at the same time. They are textures/common/shadow and textures/common/shadow2. Shadow material casts shadows and self shadows (on the object the mesh is exported with, it is all considered one object although the collision and shadow meshes are not seen in game). Shadow2 casts shadows (on terrain and other objects) but does not cast shadows on itself. This is very handy for things like apples where the player really won't notice if the stem casts a shadow on the apple. Remember, this is one of the most important considerations for performance so if an object can live without shadows, or without casting shadows on itself then use that option first.
Weird lighting issues due to shadow meshes. .Ase files from 3ds max have an issue with shadow meshes clipping outside of an objects mesh which can cause weird shadow fragments on the objects they belong to. The cure for this is to make sure that the shadow mesh is entirely inside the objects mesh. If it sticks out anywhere you will get a weird shadow. A workaround I have found that works good is to model large parts of a shadow mesh that are easy to hide, this can cut down alot of shadow casting polys on an object. Then I will split small details off of the object and give them a material that has shadows, then I don't have to mess with the very hard areas but have still done some good. (example: a small pot with tiny handles, the pot will cast no shadows but will have a shadow mesh to do that, The tiny handles will themselves cast shadows so there is no weird shadow mesh clippling - both use the same base material, but the noshadows and noself shadow lines are removed from a copy of the original shader). There seems to be no issue with lwo files, I am not sure why this is, but if you are making these files it seems you can be a bit more lax in the overall shape/clipping of your shadow mesh.