Character Design and Development
- This page discusses the art requirements in creating a character. For more technical details about the file requirements, see:
HeroEngine supports two types of characters:
- Static Characters - A character is made from a single mesh. It does not have interchangeable parts or textures. This is typical of most NPCs, and easiest to do. You could considered Static Characters as 'fixed' characters.
- Dynamic Characters - Characters that can be made from interchangeable parts, have optional morphing and texture variants. This approach is more complex, but leads to a tremendous variety in a character's look and dress. Any flavor of a Dynamic Charcter is used for Playable Avatars or multi tier mobs. You could consider Dynamic Characers as 'modular' characters.
Player characters are typically dynamic. One wants to adjust the facial features of one's character, his race, clothing and so forth. What is exciting about HeroEngine is that these same tools are also available for NPCs and creatures. In fact, HeroEngine makes no distinction between these because a player can control any type of character (it is left up to the designers to decide what makes sense for the game in question).
There are rendering (GPU and CPU), memory and content creation costs associated with using a dynamic character vs. a static one. Further, individual features of a dynamic character carry their own costs which must be balanced during your design stage.
Volume (How Many Characters Can You Render)
The key thing to consider when deciding how to author your characters is the issue of volume: How many characters do you want to be visible in a scene at one time (before performance is unacceptable on your target platform)? The anticipated volume of characters is critical in your decision process.
You may think this is impossible to predict because in an MMO players can do virtually whatever they want. But, as game designers, you do have control over the basic design decisions that can have a huge influence on this. For example, do you favor instanced quests, large scale raids, etc.
More characters visible is, in a simplistic sense, good. But there is a price to pay for this: the more you want, the less detailed and unique they can be. This is because consumer video cards--and PCs in general--have strict resource limitations. Properly authored and coded, a modern video card can draw hundreds of identical characters very quickly. But what if each character is a different mesh and a different texture? Or worse, a bunch of meshes and textures each? How many can it draw at a good frame rate then? Not as many as one might hope. Also, remember that characters are never the only things visible in a scene: you'll also have the world being rendered, any mirrors visible, and particles; not to mention the overhead of audio and any post-processing effects going on.
During your planning process it will be tempting to use every capability of HeroEngine's character system to it's fullest, sub-dividing your character into many little parts and so on. This, of course, comes at a rendering cost. So you must be careful to maintain balance between features, flexibility and rendering speeds.
Fortunately every feature of HeroEngine's character system is optional. You can mix and match them to suit your needs. And you can do this differently for each character specification! So you might have some particular creatures that utilize the parts system, but others that do not. And your player characters might use every feature.
Static Character Costs
A static character is one that does not use any of the dynamic features of HeroEngine. In other words, they do not use dyanmic part swapping, dynamic texture banks and so forth. This is the most typical way a creature is done in most computer games. It is the least flexible, but the most efficient for rendering, memory usage and load times. You will probably find that many of your creatures can best be done this way (with alternate versions to introduce variety without resorting to the complexities and costs of dynamic characters).
These are the main issues to consider in authoring a static character:
- Material Switches
- Polygon Count
Think of a video card as a runaway train... it's zooming down the track like a bat out of hell, rendering polygons at blazing speeds. The only thing that can stop it is the dreaded material switch! When HeroEngine (or any 3D rendering pipeline) must switch from one material to another, or one mesh to another, this causes the speeding train to come to a dead stop.
The key to rendering speed--and therefore frame rate--is to get as many polygons drawn in one go as possible. Proper authoring of your characters (or any assets for your game) is critical in maintaining good frame rate with large numbers of characters.
Unfortunately, for a video card to animate characters there is a strict limit on the number of bones that can be handled. For 2.0 shader video cards, HeroEngine can handle 75 bones. You might use different shaders than provided, however, so this number can change. If you exceed the number of bones, the animation of your character will occur on the CPU rather than the GPU and use dynamic vertex buffer updating (which is much, much slower). So keep your bones reasonable! (Note this situation is somewhat different for dynamic characters, see below)
Here is the ideal situation:
- Have only one material (that is, one diffuse texture, bump, etc.) on the character.
- Keep your polygon count reasonable (2000-3000 is an example we use in Hero's Journey, but if you want lots more characters on your screen you might consider less).
- Keep your bone count under the magic limit (75 in the default case on most video cards; less is better)
Dynamic Character Costs
Dynamic Characters utilize some or all of the cool dynamic features of HeroEngine which allows a character to vary its appearance parametrically. This includes morphing, part swapping, texture swapping, special shaders and more.
Dynamic characters are, by their nature, much more hungry for CPU, GPU and memory resources than static characters. Still, HeroEngine strives to be very smart about resource usage to minimize this impact.
For each character, you can opt to use some, all or none of the dynamic character features (if you use none, then it's a static character). Each feature has its associated costs.
- Main page: Parts Files
For a character to be classified as Dynamic, it has to use the parts system in one form or another. This system allows you to assemble a character from an inventory of parts that are designed to work together. Since each part is a separate mesh, this would lead to very poor batching for the video card, but HeroEngine will "stitch" together all of the parts that share the same material to maximize the batching potential (see the planning section below for more details). For this to be effective, you should minimize your material usage and carefully allocate your texture space. Ideally, if you can have your entire character represented on a single texture, then HeroEngine can stitch the the parts together in the most optimal way for rendering.
Unfortunately, the data for a stitched version of a character has to be stored somewhere, and since very few characters are identical, this means that each character essentially needs a unique copy of all of its meshes in memory. That is, when HeroEngine finds two separate parts with the same material, it creates a new vertex buffer and fills it contiguously with the two parts. So if a character has no common materials between any of its currently visible parts, no extra memory will be used, but there's a potential render speed hit from all the draw calls. On the other hand, if every part in the character shares the same material, that character will duplicate all of its meshes in memory, while saving big in the render speed department. This overhead is a moot point, though, if your character is using morphing, since that requires a copy of the meshes in memory anyway.
Characters can have their shape change by morphing. This is especially pertinent to player characters where customization is highly valued. For creatures, this can also be done.
Two types of overhead exist with the use of morphing (including Facial Morphing, see next section): overhead for the statistical model and overhead for mesh duplication.
The statistical model overhead (in bytes) is approximately calculated by the following formula:
[4 + (6 * numberOfVerticesInMesh)] * numberOfMorphControls
The other type of overhead is due to the fact that, for each character to look unique, mesh data must be duplicated and modified. In video card terms, this means there exists a unique mesh for each character using morphing. So if you have 100 Orcs that don't use morphing, that'll be only one mesh in video memory. But if you have 100 morphing character Orcs, that'll be 100 unique meshes in video memory. Even if your character is one giant part, you're still creating a unique mesh for each instance of that creature. In general, if you're looking to get large crowd scenes of similar-looking characters, stay away from morphing (you probably won't need that extra detail anyway).
This technology is intended specifically for player characters, although you do not have to use it for them. It is not well-suited for creatures, where you would probably use standard morph and part techniques to provide variety.
When you're designing your head or face mesh, keep in mind that the default FaceGen statistics have about 80 shape controls available. Following the cost analysis in the Morphing section above, the statistics for a 300-vertex head mesh, for example, would then take up
([4 + (6 * 300)] * 80) bytes = ~141KB
The above cost is constant for a character specification, meaning if you have twenty characters using that 300-vertex head mesh and instanced from the same character specification, there will only be one copy of the statistical data in memory (although there will be twenty copies of the head mesh in its various morphed forms unique to each character).
For player characters, this is fairly essential to providing a high level of character customization. For creatures, this is probably overkill and might be too expensive for most needs.
If parts have dynamic textures, this will impact the ability of the character to stitch together. Every material break leads to a full-stop in the rendering pipeline, which is what we want to avoid. For player characters, this is often a reasonable cost to pay. For creatures, it may not be, depending on your design.
Tintable textures are more costly to render because they require more work on the pixel shader of the GPU. This cost is fairly trivial on high end cards, but on lower ends cards it might be a burden.
Each part can reference one or more texture banks (which represents a material break). Just like with static characters, keeping your texture banks as few as possible is important. It is better to have one big 1024x1024 texture than 4 512x512 textures.
Each texture bank can have up to two texture layers, but it is significantly less costly to render just one layer on many video cards. For high end video cards, this is less of an issue, although more textures equals more video memory. If you can do it in one layer, stick with that.
HeroEngine includes a special hair shader which creates a more realistic sheen on hair than normal specular. Further, the hair shader allows for gradient tinting regions, coloring the sheen and full-color regions (for example, coloring a hair clip or other ornament).
Furthermore, since translucency in hair greatly increases its visual appearance, there are special techniques to deal with hair polygon sorting. Hair meshes, by their nature, are typically unified meshes so the inter-polygon sorting is needed for translucency to look correct. Further, hair translucency has to sort well with other translucent objects in the world (especially water).
All of this is taken care of by the hair shading system, but it comes at a cost. Hair of this nature is costlier to render, so typically you will use this only for player characters.
Although the following are presented as sequential steps, in reality they tend to be done iteratively. In other words, you do a certain amount of planning up front, then as you model a certain number of parts you add them to the specification. Test and repeat until you have a complete dynamic character. New parts can be added as you go, even when your game is "live."
Once you've determined that you need a Dynamic Character, you'll have to begin by planning out what level of customization you actually want available to the user (note that a user may not be a player; in the case of dynamic NPCs, the user may be a GM who dresses a placed NPC or might even be a script!). This step will be completely dependent on your project: a game based on Mechs may have more customization options than a game where the characters are marbles.
To define the level of customization, you want to determine what slots the character will have; that is, what sections of the character model should be switchable. This will end up having a direct correlation with how many material switches a character will have when rendered. Again, this is completely dependent on your requirements.
- For example, you may decide that your character should be split into a head, an upper body, and a lower body (3 slots). In this case, the parts selected at any given time in each slot will probably each be mapped with a different material, meaning the character will take 3 draw calls.
|Tip: For some NPCs, you may want to have a handful of very different versions of the character. For this, use only one slot and make each part in that slot a different (complete) variation of the character.|
The idea is to balance the number of options with rendering efficiency. Since a slot tends to mean a different material is being used, you want to keep the number of slots to a minimum. Here are some steps for designing your slot layout while keeping in mind performance considerations:
- Sketch out your ideal character slot layout based solely on desired features.
- Decide the maximum number of draw calls you can tolerate per character, worst-case. This will be your target number of slots.
- Determine which slots you can combine. There are a few ways of conceptually combining them:
- Merge symmetric slots.
- For example, turning two slots named Left Hand and Right Hand into a single slot named Hands so that when a player chooses a hand type, both hands change at once. This eliminates some amount of customization, but may not be too noticeable.
- Make one slot a subslot of another, forcing them to share a material.
- For example, if you have a Hip Pouch slot and a Pants slot, make the Hip Pouch a subslot. Because subslots share the texture of their parent part, you'll need to put a pouch texture somewhere on each pants texture that you want to allow the pouch to be worn with. If you decide not to have a certain Pants part allow the pouch, you can use a hides(Hip Pouch) rule on that Pants part.
- Merge symmetric slots.
- If you're still above the maximum draw call number, drop the least important slots or go back to step 2.
Note that because of stitching, the average number of draw calls may actually be less than the worst-case scenario. You can help lower this average number of draw calls by:
- Authoring content in matching "sets" of parts that map to a single material.
- For example, an artist can create a pair of matching gloves that both share a single material, then export them as two separate parts. Because they are similarly themed (and people often like symmetry), players may be drawn toward picking the same glove on both hands, allowing stitching to combine the gloves into one draw call.
- Turning off slots that have low visual impact at a distance using the lodoff() rule.
|Here's an example slot layout of a character in Hero's Journey:|
|(In the above image, green marks slot boundaries.)|
To demonstrate the stitching mechanism, look at the above image: the parts in the Lower Left Arm, Lower Right Arm, and Torso slots will all be stitched together into one draw call. While not immediately obvious, the Legs, Lower Left Leg, and Lower Right Leg parts also share a material and will become a single draw call. The head is a separate material to enable high resolution details in the face, so it'll remain in its own draw call.
You will probably have more slots than this. For example, a slot for hair, one for worn items on the head, another for a cloak, and so forth. You should also decide if a slot can be empty (bald, no cloak).
Also note that, in the case of Hero's Journey, we choose to have independent slots for the right and left arm, plus the right and left lower leg. This means that the right arm could be changed independently from the left. This decision has consequences in that it can lead to more draw calls (less effective batching). But, in our design, usually the right and left sides are known to be parts using the same dynamic textures (same materials). So, that means that usually these two symetrical sides will be stitched together. But it still allows us to split them if we really want, such as to give a character a peg leg. When that happens the two sides won't stitch and the character will be less effective at rendering.
This represents an example of the key sort of decision you need to make in your character planning. The trick is to organize your parts and textures to make it as likely as possible for stitching to occur. Depending on your game design goals, sometimes you might be willing to sacrifice flexibility in character customization for speedier character rendering. Other times you might put a premium on extreme flexibility over how many characters can be rendered at an acceptable frame rate.
Part Break Considerations
Notice also that in the example above, the arm is broken into two parts just below the elbow. And the upper parts of the legs are one part instead of two (like the arms are). There are many other ways the character could be broken into parts, and these decisions must be made during the planning of a fair representative set of the parts you intend for the character.
Where you put your breaks between parts will have a big influence over what your artists can achieve. One can achieve greater variety with more breaks (say an arm broken at the wrist, elbow and shoulder). But with different parts likely to be swapping in for a player character, this could have too negative an impact on the stitching opportunity (in other words, little to no stitching could be accomplished if a character's parts widely vary in materials) and yield more draw calls than you want to accept for a character.
A good process is to do your concept drawings such that the parts can be easily identified at that point. Experimenting in 2D before committing can save a lot of time overall.
Each part can also have subslots. A subslot is just like a slot, except it's dependent on a "parent part." The parent part and all parts in the subslot must share the same material (and by extension texture bank, if the material is dynamic). Because of this, they are guaranteed to stitch with their parent and provide a lot of geometric variation at no additional rendering cost. The limitation of using the same texture bank requires some creative use of texture space by the artist, but the trade off for more variety at no additional rendering cost makes it a very powerful concept.
In the example below, a lower body part option has two optional subslots. Notice how the artist was careful to map them onto the same texture (thus, the same dynamic texture bank, ergo the same material). Now the user can pick either of the two subslot options, both, or none.
Having designed your slots, you now need to make some actual parts to put in them.
Follow these steps to lay some groundwork reference material on which to base all parts you create in the future.
Build a base mesh
The base mesh is used as a reference to model clothing parts against in the future. It also will probably be the mean mesh if you use body morphing.
Model this mesh in its root pose, keeping in mind that all dynamic parts eventually built using this mesh as reference must line up in world space based on this mesh when they are skinned and then exported. If no part of the base mesh is to be an actual character part and is only intended for reference, there's no need to apply textures to it.
Add a skeleton
A skeleton can be a Biped rig, a 3ds Max bone rig, or a combination of the two.
- Face Character into -Y for Max; +Z for Maya.
To make life smoother, all rigs in 3ds Max should be facing in the -Y direction, which is also the default for any Biped created; +Z for Maya. This helps with consistency for the production and it also plays nicer with the scripts that have been written for the exporter.
- Name Root Bone "Bip01"
All skeletons must contain a root bone named "Bip01". If you use Biped, it will already have its root named this way. This also applies to Maya rigs.
- Add a Synthetic Root Bone (SRB)
Add a Synthetic Root Bone. The SRB is added through the Hero Export utility. In the Hero Export utility, click Character Tools, then Create SRB. The script will set up an SRB attached to any rig in your scene which has a root bone named Bip01. The COM of a biped rig will have this name by default, but the root bone of a rig built from Max bones will need to be renamed manually to "Bip01".
- Export Skeleton
The skeleton must then be exported (separate from any body mesh components) as a Dynamic Character. This can be done by choosing "Dynamic Character mode" at the top of the Hero Export utility within 3ds Max or Maya.
Break it up into parts (Optional)
If intend to use the parts system, each part needs to be a separate scene in 3ds Max or Maya. You will skin the part to the same skeleton in each. These parts are then exported individually as Dynamic Character Parts (see "Export the Part" below).
Typically the easiest way to divide a base mesh into parts after texturing and skinning is to delete geometry, then save the altered scene out to a different file, returning to the base mesh each time to single out the parts. For instance, if the entire left arm was intended to have swappable options, creating the 'base' version of that part is as easy as deleting all geometry other than the arm, then exporting it as a dynamic character part.
Adding a new part
Once the base mesh and skeleton are created, you'll want to use them as reference for creating the parts that will comprise your dynamic character. Often the easiest approach is to save out the base mesh to a new file and create the new part's geometry as needed, while leaving seams unaltered such that they match up precisely with adjoining dynamic parts. Once this is done, the part can be detached for texturing and skinning.
If you intend for your dynamic character parts to utilize dynamic materials (a dynamic material is simply a material that uses a texture bank), name materials with a
~dt2_ prefix for 3ds Max,
dt2_ prefix for Maya and without spaces (i.e.
dt_prefix is a special indicator to the engine that it's dealing with a dynamic material. If you're using static textures, materials can be named as you see fit.
HeroEngine's tinting works by taking an additional tint mask texture that tells the engine where each of the (up to) 4 colors affects the diffuse texture. It works by packing masks into a single texture, with each of the red, green, blue, and alpha channels masking the first, second, third, and fourth colors, respectively. Not all four channels are required to be used; you can use from one to four of them. Also note that the alpha channel of the tint mask texture is not actually used for transparency: the transparency of the bank is grabbed from the diffuse texture's alpha. Any pixel that is completely black in all four channels of the tint mask texture has its color taken from the diffuse texture and therefore can't be tinted by the user (a pixel that matches these criteria is called full color). Here's an example of a tint mask texture that uses all four colors, plus has a full color section:
You tell the engine how many of the channels should be used with the layer type property (Tint1 just uses the red channel, Tint2 uses the red and green, etc.).
Note that any given pixel can be represented in more than one tint mask channel. In this way you can create, say, a gradient between two user selectable colors.
If using the special hair shader, there are some additional considerations and steps:
- To use the custom hair shader, select the hair effect from the effect drop down menu on the HeroMaterial spec dialog.
- A hair texture is like a tint mask texture, but with the following differences:
- The alpha channel specifies transparency, not a fourth color mask.
- There is no separate tint mask texture: the diffuse map functions as the tint mask.
- Since there are only 3 mask channels available, the fourth color is for the sheen/specular and its coverage is determined by the position of the light and the viewer, just like any other specular term. There is no texture mask for this color's coverage.
- Hair UVs should be laid out as vertically as possible in order to be visually compatible with the hair shader. Try to make hair flow in the V (vertical) direction of the texture. The special hair shader will create proper sheens with visible hair strands when done in this way. If not, the shine of the hair will not look correct.
Example hair UVs and texture coupled with in-game appearance. Note the direction of the specularity marked by the blue arrows.
Skin layers use a special three-way blend of textures to arrive at a custom skin texture for each character. This blend actually happens in the shader on the GPU, so it's very fast to render and lowers memory requirements, since it doesn't require unique textures per character.
Content creation for skin blending is relatively straightforward. Simply create three separate skin textures of identical size:
The blending then happens dynamically within HeroEngine using HSL skin functions. Blending the above equally, for example, gives us a Caucasian-Asian-Zombie:
Export the part
If there are certain parts of your rig you do not wish to be included in the export (for example, you may want to exclude the nubs which are included by default in Biped rigs and the RootHelper the SRB script creates) hide them in the scene and export using the 'Export Unhidden' option from the Hero Export UI. Dynamic Character Part is the export mode you will need to use. Make sure the 'Move to Origin' option is selected.
Once you have some parts exported, you'll need to tell the engine where they are and what they're used for. That's where this section comes in.
Recommended Repository File Layout
For HeroEngine to properly load character specifications, some requirements must be met on where character-related assets are stored in the repository. They are:
- Character assets must be located in a subfolder under HJ named Character.
- Dynamic character assets (part and skeleton files and all data files like .par and .dyc files) must be located in a subfolder under Character named Dynamic_2.
- Texture banks and the .dds files they reference must be located in a subfolder under Dynamic_2 named TextureBanks.
Visually, the minimum required folder layout looks like this:
On top of the requirements, in Hero's Journey we found some things useful for our folder layout:
- Subfolders within Dynamic_2 for race (meaning human/orc/dwarf, not Asian/African/European) divisions.
- Separate male and female subfolders within each race folder to allow more gender-specific geometry.
- Shared_Geometry folders, one under the Dynamic_2 folder for geometry shared between races, the other inside each race folder, for geometry shared between male and female versions of that race.
Visually that looks like this:
When creating a new character from scratch use the Hero Character Tools for the basic setup of a character. The Original Manual Setup of Characters can be found on the Hero Character Tools page for reference of updating excising characters.
Adding New Content
At this point, you'll have some exported mesh files as well as the .dds files that are used to texture the parts. Make sure they're uploaded to the repository in the directories you want them in. Here's where we'll actually add them to the engine. By now, you should have gone through the Initial Setup section to have the layout files (.par, .dyc) primed.
The following steps are performed for each new part you have content for:
- In the character's .par file, do the following:
- In the [Parts] section:
- In the [Banks] section:
- Create any nonexistent texture banks that the part file references.
- See the .dtb reference page for more information.
Then do these steps just once for this batch of content:
- In the .par file, figure out what rules you'll need, and add them to the appropriate parts and slots.
- Reupload the layout files you changed (.par, .dtb, etc.).
- If applicable, integrate the meshes into the FaceGen pipeline.
Return to this section whenever you add new parts in the future.