A massive demonic invasion has overwhelmed the Union Aerospace Corporation's Mars Research Facility, leaving only chaos and horror in its wake. As one of only a few survivors, you must fight your way to hell and back against a horde of evil monsters.

Post tutorial Report RSS How to create and set up a Doom 3 replacement player model

This is a step-by-step tutorial explaining the set up and the various commands and restrictions needed to create a plug-in player model for the game Doom 3

Posted by on - Advanced Players Modelling

Tutorial originally written by Vincent “Vahl” Joyau. Mirrored here for archival purposes.


Quick Tutorial: How to create and set up a doom 3 Replacement player model

Introduction:

Welcome in my first tutorial ever. This is a step-by-step tutorial explaining the set up and the various commands and restrictions needed to create a plug-in player model for the game Doom 3 (ID Software/Activision). I assume you already know how to create a high poly and a low poly model and that you know the rigging/skinning basics in 3D studio max. I also assume that you ALREADY have a model ready and with proportions matching the “mpplayer.md5mesh” (this is important as this tutorial uses skeletal animations)

Please note that this tutorial covers the way I imported my model and managed to make it work in multiplayer as a mod. This may not be the best way to proceed

Step 1: Rendering normal maps:

If you want to make a model for Doom3, you need normal maps to be applied to it so the engine can “fake” the highly detailed stuff in order to do that you have 4 options:

  • ORB - Open-source Render Bump: a pretty good and fast normal map renderer, pretty easy to use and with a pretty good output result.
  • ATI Normal mapper: I used to prefer that one to ORB, though you’ll need to invert the green channel of the output map, it also renders the occlusion term, has a very good output result and a lot of cool options.
  • Doom 3 built-in renderbump / renderbumpflat tool: to me the best and fastest one, the map will be a little different than in the two previous tools, showing a few artefacts but the bump will look a lot better once in-game this is the option we’ll choose in this tutorial.

A – the material File (*.mtr)

The first step is to open you Doom3 base directory and find the “materials” directory in this directory, create a blank .txt file that you’ll name after your character’s name for instance. In this *.mtr file you’ll need to make a few things:

* Define a shader name, in this example:

models/characters/players_mp/mp_male2

This is the name the game will look after when trying to texture your model, the same name that will be needed as material name on your object.

* Then you will need to define the properties of your surface, for more properties look into the *.mtr files present in the game. This is what I wrote:

noselfShadow
unsmoothedTangents
collision
forceOverlays
noshadows
transluscent

For more information about this, please consult the shader syntax on doom3world

* Now, we will give the engine the different parameters for normal map rendering:

renderbump  -size 1024 1024 -trace 0.07 -colorMap -aa 2  models/characters/players_mp/mp_male2_local.tga models/characters/players_mp/mp_male2_hi.lwo


- renderbump is the command you’ll use in the console

- -size 1024 1024 is the size width height of your normal map

- -trace 0.07 the tolerance or ray hit distance. The smaller, the more precise it is, but the less tolerant

- - aa 2 is the anti aliasing factor here , 16 samples per texel

- models/characters/players_mp/mp_male2_local.tga is the path to your normal map file, this is where the engine will create it.

- Models/characters/players_mp/mp_male2_hi.lwo is the path to your highpoly model. You may notice that the path is always the same as the shader name, I did this by convention, as ID seemed to respect this for all their shaders

* now we will define all the other parameters of the shader (diffuse, specular, bump, special effects)

diffusemap                            models/characters/players_mp/mp_male2.tga
{                               
blend                     bumpmap
map addnormals(models/characters/players_mp/mp_male2_local.tga, heightmap(models/characters/players_mp/mp_male2_h.tga, 3 ) )
// note that you do NOT put vertexColor on the bumpmap
}

specularmap                        models/characters/players_mp/mp_male2_s.tga

- diffusemap models/characters/players_mp/mp_male2.tga is the path to the color map that will be applied to your model

- blend bumpmap

map addnormals(models/characters/players_mp/mp_male2_local.tga, heightmap(models/characters/players_mp/mp_male2_h.tga, 3 ) ) This blends both the normal map and the bump/heightmap to create the final bump shader that will be applied to the model. “3” is the strength of the blend I think (to be checked).

- specularmap models/characters/players_mp/mp_male2_s.tga is the path to the specular map

you can check the *.mtr file joined with this tutorial for more information.

Once your file is done, save it as a *.mtr file

B – Setting up the model in lightwave

Both your high poly and low poly models have to be saved as *.lwo objects with smoothed normals (no smoothing groups, at least for the low poly mesh, I tend to use smoothing groups for the high poly mesh though, especially for small details). The low poly model needs to be UV mapped with as few seams and distortion as possible, though, distortion is really hard to avoid on normal mapped objects and you can be sure that you’ll need to make a Photoshop phase before using your normal map into doom3.

  • Load your low poly mesh into lightwave – (I created the models in Maya so I exported them as *.obj files)
  • Open the surface editor (ctrl + f3) and rename the shaders applied to your model to the right syntax if needed. For me the body needed the “models/characters/players_mp/mp_male2” shader. The shader is namely the same as the one you created with the *.mtr file.
  • Also give the surface a 180° smooth (at the bottom of the surface editor)
  • Save your model in the folder your shader will be looking in (so for me that was models/characters/players_mp/) as a *_low.lwo object (mine was mp_male2_low.lwo)
  • Load your high poly mesh into lightwave as a new object.
  • Smooth the normals (via the surface editor) to 180° or to the value you need.
  • Save your model as a *_hi.lwo object in the same folder as your low poly mesh and with the same name as defined in the * .mtr file (so for me: mp_male2_hi.lwo)

C – Rendering the normal maps into the Doom 3 engine

Check

  • that your paths are correct in your .mtr files
  • that BOTH your models are triangulated and smoothed correctly

Launch Doom3 once the game loaded, bring down the console (ctrl+alt+tilde) and type :

renderbump yourlowpolymodelpath.

For me that was :

renderbump models/characters/players_mp/mp_male2_low.lwo

the engine will search for the shader applied to your low poly model and will look into the *.mtr files once found it will start rendering the normals. The screen will be inverted; this is due to the way the engine calculates the normals, with the Y axis pointing downwards. The file will be saved in the same folder as your models, which is the folder where all your texture should be saved to.

D – Checking the model ingame

Now that your normal maps are rendered, you can start skinning your model. Checking it in the realtime viewport in max or maya is cool, but isn’t it even better to check it directly ingame, with realtime lighting and shaders? Sure it is!!!

To check your model ingame, put all your textures (diffuse, normal, spec, heightmap) in your model folder (with the lwo’s) then launch the game, open the console and type:

map test/test_box

to open the test map (a simple box, quickly launched and such…) then type :

testmodel yourlowpolymodelpath

So in this example:

testmodel models/characters/players_mp/mp_male2_low.lwo

The command testmodel imports the model as a static object ingame so that you can check it. Of course it’s not a fully animated PPM, but at least you can check your textures and it’s quite faster to launch it this way rather than launching a multiplayer server with cheats enabled.

Step 2: The model integration:

Now, we have our model textured and normal mapped, we want to rig it and make it available ingame. The way I found when doing the spaceman was to create a replacement model for the base marine, which needed the creation of a modification.

A – Rigging the character

First off, you need to import the original mpplayer models and skeleton. I used Der_ton’s md5 importer for max 5, which works pretty well and can be found Doom3world.org.

Install the script and run it. You’ll have to import the “mpplayer.md5mesh” file from the Doom3\base\models\md5\characters\npcs\playermoves\” folder.

In the script preferences, uncheck “see-trough model” and make sure “reorient bones” is unchecked. Then import the md5mesh.

Now you may have noticed that all the models (berserk, skeleton and marine characters are already present and merged in the same mesh. What you may want to do is to separate the marine and delete it, but I simply deleted all the meshes. You can also use the max file provided in this tutorial where the skeleton is already imported and ready to attach.

Import your model and, attach it to the skeleton using theSKIN modifier.

***IMPORTANT THING: the bones must be added in the same order as in the bones list in the mpplayer.md5mesh file, so open this file with WordPad and respect the bones order.

Personally I used the weight table rather than the envelopes, simply because I don’t like at all max envelopes and the weight table is a lot more precise, you can also paint the weights for more smoothness.

B – Importing the character into the Doom 3 engine.

Export your model using Der_ton’s md5 exporter to the name of your choice, which was “mp_male2.md5mesh” in my example. The exporter will export a *.md5anim file too, you won’t need it so you can delete it.

Now, this is a part, most people won’t be ok with, I must say that I did it this way because the SDK wasn’t out yet, and I was still in the learning stage, but it worked pretty well so I think it can be useful to talk about it. So, open your newly created *.md5mesh file anddelete the joints definitions and these lines :

MD5Version 10
commandline ""

numJoints 75
numMeshes 1

Now you only have the mesh information left, make sure the shader is applied in the “shader” part at the beginning of the mesh definition, save that part.

Search again for the mpplayer.md5mesh file and copy it in a new folder, using the same path hierarchy than your textures, but with the “doom3\base\models\md5\ ” folder as root folder instead than “doom3\base\models\” In this example this was: “doom3\base\models\md5\characters\players_mp\mp_male2\

Open it with WordPad, also open the md5msh file that contains your model data.

In the mpplayer.md5mesh file, delete the mesh info about the marine body and head and then copy the part about your model there. Save the file, don’t forget to change the numMeshes number at the beginning of the file to match the number of meshes the new model will contain.

Each mesh in this file can only have one material, so if you’re using different materials, you’ll need to repeat this sequence several times. Just don’t forget to update the numMeshes number.

C – Setting up the *.skin file.

The .Skin file is the file the engine will refer to when it will need to dynamically change the textures of your model (for the berserk or the skeleton for instance).

This is a standard renamed *.txt file. Mine was “skins_mp_players.skin”

This file is separated in different sections, named after the skin name that will be defined in the .def file (next tutorial section). By convention, the skin name is the shader path; using the skin folder as root folder instead of the model folder.

The file must also contain the skin information for the berserk, invisible, death and team colour skins.

Here’s my skin file for the Spaceman :

skin skins/characters/players_mp/mp_male2 {
                //default_effects
                models/items/powerups/blite1 textures/common/nodraw
                models/items/powerups/blite2 textures/common/nodraw
                models/items/powerups/blite3 textures/common/nodraw
                models/monsters/skeleton/skeleton01head textures/common/nodraw
                models/items/powerups/berserkerfx textures/common/nodraw
                models/items/powerups/berserkerflame1 textures/common/nodraw
                models/items/powerups/berserker textures/common/nodraw
                models/characters/male_npc/marine/stump textures/common/nodraw
                models/items/powerups/atom textures/common/nodraw
                models/monsters/skeleton/skeleton01 textures/common/nodraw
 
                //Bodies
                //models/characters/players_mp/mp_male2 textures/common/nodraw
               
                //Heads
                //models/characters/players_mp/mp_male2_head textures/common/nodraw
                //models/characters/players_mp/mp_male2_mask textures/common/nodraw
               
                //Decals
                //textures/decals/military_logo textures/common/nodraw
                //textures/decals/mixom1 textures/common/nodraw
}

As you can notice, the shaders are organized in 2 columns, the first one is the original shader you’re using, the second one, is the shader it will be replaced with when this skin will be active. As the models are all present in the md5mesh, what you may want to do is show/hide the different meshes. In order to do that, you’ll have to use the “texture/common/nodraw” shader, so the engine won’t draw the triangles this shader will be applied to.

But you may also want to assign a different team colour or an invisibility shader, in that case, you just have to assign the corresponding shader instead if the nodraw shader. For instance, here’s my invisibility skin definition.

skin skins/characters/players_mp/mp_male2_invisible {
                //default_effects
                models/items/powerups/blite1 textures/common/nodraw
                models/items/powerups/blite2 textures/common/nodraw
                models/items/powerups/blite3 textures/common/nodraw
                models/monsters/skeleton/skeleton01head textures/common/nodraw
                models/items/powerups/berserkerfx textures/common/nodraw
                models/items/powerups/berserkerflame1 textures/common/nodraw
                models/items/powerups/berserker textures/common/nodraw
                models/characters/male_npc/marine/stump textures/common/nodraw
                models/items/powerups/atom textures/common/nodraw
                models/monsters/skeleton/skeleton01 textures/common/nodraw
 
                //Bodies
                models/characters/players_mp/mp_male2 models/characters/players_mp/mp_male2_invis
               
                //Heads
                models/characters/players_mp/mp_male2_head models/characters/players_mp/mp_male2_head_invis
                models/characters/players_mp/mp_male2_mask models/characters/players_mp/mp_male2_mask_invis
               
                //Decals
                textures/decals/military_logo models/characters/male_npc/marine/mp1_invis
                textures/decals/mixom1 models/characters/male_npc/marine/mp1_invis
}

The same goes for any team color or death skin definition. Please refer to the linked files for more examples, and don’t hesitate to look at doom3 skin files.

D – Creating the mod folder.

This could have been created before, but now you really need to create your own mod folder, go in your Doom3 directory, and next to your Base directory, create a new directory with the name of your mod (for me that was “spaceman”). Then copy everything you created in this folder, make sure it respects the same folder arborescence than in the base folder.

E – Creating the .def file.

This file is where most the game features are defined. The one we’ll look into is the “mp.def”. Search it in the “base\def\” folder copy it and paste it into “yourmodfolder\def\” .

Open this file, you’ll need to modify a few things then, the mesh path, the skin file etc, here’s the original mp.def part that will be modified:

/***********************************************************************
 
 player model
 
***********************************************************************/
 
model model_mp_marine {
                inherit                                                                                                                 model_sp_marine
 
                mesh                                                                                                                     models/md5/characters/npcs/playermoves/mpplayer.md5mesh
               
                channel torso                                                                                     ( *Waist )
                channel legs                                                                                       ( *origin -*Waist SPINNER eyecontrol)
 
                skin                                                                                                                      skins/characters/player/marine_mp.skin
               
                anim run_forward                                                                             models/md5/characters/npcs/playermoves/run_270.md5anim {
                               frame 10                                                                                              rightfoot
                               frame 19                                                                                              leftfoot
                }
                anim walk                                                                                                          models/md5/characters/npcs/playermoves/jog.md5anim
                anim walk_backwards                                                                    models/md5/characters/npcs/playermoves/jog_back.md5anim
 
                anim walk_strafe_left                                                       models/md5/characters/npcs/playermoves/walk_strafe_left.md5anim
 
                anim walk_strafe_right                                                   models/md5/characters/npcs/playermoves/walk_strafe_right.md5anim
}
 
entityDef player_doommarine_mp {
                "inherit"                                                                                                             "player_base"
                "model"                                                                                                              "model_mp_marine"
                "bleed"                                                                                                               "1"
                "gib"                                                                                                                   "1" 

                "skin_dropDeath"                                                                            "skins/characters/player/marine_mp_death.skin"
                "skin_invisibility"                                                                            "skins/characters/player/marine_mp_invisible"

And here’s the modified part for the spaceman model:

/***********************************************************************
 
 player model
 
***********************************************************************/
 
model model_mp_male2 {
                inherit                                                                                                                 model_sp_marine
 
                mesh                                                                                                                    models/md5/players_mp/mp_male2.md5mesh
               
                channel torso                                                                                     ( *Waist )
                channel legs                                                                                       ( *origin -*Waist SPINNER eyecontrol)
 
                skin                                                                                                                      skins/characters/players_mp/mp_male2.skin
}
 
entityDef player_spaceman_mp {
                "inherit"                                                                                                             "player_base"
                "model"                                                                                                              "model_mp_male2"
                "bleed"                                                                                                               "1"
                "gib"                                                                                                                   "1"
 
                "skin_dropDeath"                                                                            "skins/characters/players_mp/mp_male2_death.skin"
                "skin_invisibility"                                                                            "skins/characters/players_mp/mp_male2_invisible"

As you can see I modified the mesh and skin paths. These settings will overwrite the mp.def settings when you’ll launch your mod so that you’ll be able to play with your model ingame.

Save the file.

Step 3: Last steps:

A – Compiling the mod.

Well this is not exactly compiling, but you’ll need to do it if you want the game to launch your mod the first time and even more if you want to distribute it.

Select all the stuff in your mod folder and zip it with folder information (make sure he folder information starts in the mod folder, so that the models are in the “models\mymodelpath” path for instance, not“c:\doom3\mymod\models\ymodelpath\” rename the .zip to .pk4 and make sure it is at the root of your mod folder (in “doom3\mymod\mypak.pk4”).

Launch the game open the mod tab, select your mod, launch a server with a few friends and test the model

image002

B – Polishing stuff.

Now you may want to make your character selectable in the character selection menu, in order to do this, you’ll need to modify the mainmenu.gui in the gui folder, copy it in your mod folder and modify the multiplayer character selection menu so that it launches your different skins (colors and variations) I have yet to work on this so that I can select various models, but obviously PPM ala quake 3 aren’t possible to create yet, unfortunately…

You may also want to put your own portrait, to do this, just create a portrait(256*128) and put it in the “gui\assets\mainmenu\” folder in your mod folder and name it after the skin you want to replace, for me this was:

Skin_default.tga.

Something else you may want to do is to create the lower resolution versions of all your textures. This is mainly so that people can use the lower quality settings in game. Just create a DDS folder and convert all your tga’s in DDS in that folder, respecting the arborescence (i.e.: “DDS\models\mymodelpath\”). Do this even for the GUI stuff.

Related downloads:

Doom3tutfiles.zip, contains:

*.mtr file template

*.skin file template

*.def file template

That’s all Folks!

Thanks for reading all this, I know this is not the most complete tutorial ever done, but I hope this will be used as a base for more and more PPM to come out for doom 3, this game really deserves it !

Thanks to all the polycount community that was of a big, big help, thanks to Earthquake, Chunkey, Skizot, Per128, thanks to Der_ton for his exporter, thanks to Chicoverde for his help and support.

Thanks ID software for Doom3

If you have any questions, feel free to ask at vincent_joyau@hotmail.com

Thanks again for reading this long tutorial


Vincent “Vahl” Joyau

Global-illusions.com

vincent_joyau@hotmail.com

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: