Dynamic Texture Banks

From HEWIKI
Jump to: navigation, search

Contents

Dynamic texture banks are optionally used with dynamic characters to allow for texture swapping and tinting on character parts. A texture bank is a collection of texture sets, each set representing a swappable "piece". Sets are comprised of a diffuse map, a normal map (optional) and a tint map, and may be organized into two layers - a base layer and an optional detail layer. Dynamic texture banks are described by .dtb files.

Note: Only textures associated with characters need to be in texture banks. Other textures are stand-alone files. Note: Your uv's on the model must be with in 0-1 space. If they are outside of 0-1 space then they will not tint properly.


Creating a new texture bank

  1. Create a new folder in the Character\Dynamic_2\Texturebanks\ directory of the repository and give it the name of the texture bank.
    • The name of a texture bank used by a material is determined by taking the material name and removing the "~dt2_" prefix for 3dsMax, "dt2_" for Maya, (so a mesh mapped with a material named ~dt2_lower_body or dt2_lower_body will use a texture bank named lower_body). The "~dt_" and "dt2_" prefix is what tells the engine that it's dealing with a dynamic material.
  2. Create a .dtb file (also named after the texture bank) in the texture bank directory you just created.
  3. Add the [Root] section.
  4. Add the one or two layers for this texture bank to the [Layout] section. (remember: the base--or bottommost layer--is specified first).
  5. Add the [Layers] section.
    • For each layer you added in the previous step, do the following:
      1. Add the layer name in {}.
      2. Add the layer Type property.
      3. Add the layer Region property.
      4. (Optional) Add the {Settings} section and any appropriate settings for the layer.
      5. Add the {Files} and fill it with the paths to the appropriate .dds files for this layer.
        • It makes a lot of sense to put the .dds files you reference in the texture bank directory. However, there may be cases where multiple texture banks share a texture, calling for a shared texture directory. This should be rare, though.
        • See the {Files} section reference for more in-depth coverage of how to specify the .dds files.
      6. Add the {Pieces} and fill it with piece names of the content you're adding.
        • For Detail layer, add the Empty piece first if you want to allow empty as an option (this works only for the detail layer since the base layer cannot be empty).
      7. (Optional) Add Type to the pieces you added in the last step for Tint, HairShade, or Skin.
  6. Go back and add in any layer and/or piece {Rules} (see Designing Rules for more information, just replace slot with layer and part with piece).


Download Sample Files

Download Link: DynamicCharacterSampleFiles.zip

This zip file contains a set of .dtb files in the Character\Dynamic_2\TextureBanks folder


Format reference

.dtb files have a few things in common with parts files:

!
! Texture bank definition
!
[Root]
Character\Dynamic\TextureBanks\human_female_ranger_upper_body_shirt\

[Layout]
-Shirt
-Leather Armor

[Layers]
{Shirt Base}
   Type=Tint4
   Region=(0,0,511,511)
   {Rules}
!  This is where rules go, but this one happens to be commented out
!    % hides(Leather Armor)
   {Settings}
     Palette1=Human Ranger Cloth 1,Human_Palette_1.dds
     DefaultColor1=#.2,.27,.15,1.0
     Palette2=Human Ranger Studded Leather 1,palette_leather.dds
     DefaultColor2=#.35,.29,.22,1.0
     Palette3=Human Ranger Detail 1,palette_metallics.dds
     DefaultColor3=#.86,.62,.14,1.0
     Palette4=Human Metal 1,palette_metallics.dds
     DefaultColor4=#.37,.37,.37,1.0
   {Files}
     (512,512)
     human_female_ranger_upper_body_shirt_1_d.dds,human_female_ranger_upper_body_shirt_1_n.dds,human_female_ranger_upper_body_shirt_1_t.dds
   {Pieces}
     Default

{Leather Armor}
   Type=Tint2
   Region=(0,0,511,511)
   {Settings}
     Palette1=Human Ranger Studded Leather 2,palette_leather.dds
     DefaultColor1=#.35,.29,.22,1.0
     Palette2=Human Ranger Detail 2,palette_metallics.dds
     DefaultColor2=#.85,.74,.21,1.0
   {Files}
     (512,512)
     studded_vest_1_d.dds,studded_vest_1_n.dds,studded_vest_1_t.dds
     leather_corset_1_d.dds,leather_corset_1_n.dds,leather_corset_1_t.dds
     mail_shirt_1_d.dds,mail_shirt_1_n.dds,mail_shirt_1_t.dds
   {Pieces}
     Empty
     Studded Vest
     Leather Corset
        Type=Tint4
        Palette1=Human Ranger Corset 1,palette_leather.dds
        DefaultColor1=#.35,.29,.22,1.0
        Palette2=Human Ranger Studded Leather 8,palette_leather.dds
        DefaultColor2=#.35,.29,.22,1.0
        Palette3=Human Ranger Detail 8,Human_Palette_1.dds
        DefaultColor3=#.86,.62,.14,1.0
        Palette4=Human Ranger Detail 9,palette_metallics.dds
        DefaultColor4=#.86,.62,.14,1.0
     Mail Shirt
        Type=Tint3
        Palette1=Human Ranger Studded Leather 9,palette_leather.dds
        DefaultColor1=#.35,.29,.22,1.0
        Palette2=Human Metal 1,palette_metallics.dds
        DefaultColor2=#.37,.37,.37,1.0
        Palette3=Human Ranger Detail 10,Human_Palette_1.dds
        DefaultColor3=#.86,.62,.14,1.0
        AdjustableShininess=True


[Root]

This is the directory where the .dtb file that you're editing should be, and where piece DDSs will be searched for if the texture specified isn't a complete path (that is, if it's textureName.dds instead of Character\SomeDirectory\textureName.dds).


[Layout]

Layers are specified in reverse vertical order, so that the layers that come at the top of the Layout section are visually on the bottom of the layer stack. Think Photoshop, but upside-down.

-Wristwatch
-Shirt

Anything in the shirt layer will be drawn over whatever's in the wristwatch layer (again, it's upside-down from Photoshop).

Guidelines


[Layers]

This section is where individual layers are described in more detail. A layer is specified by putting its name in {}. Layer names must be unique; no two layer names in any bank should be the same. A layer's specification is divided up into several subsections, which are:

All but the Type and Region are delineated by the section name in {}, i.e. {Files} and {Rules} (see above example .dtb).


Type

The type determines, among other things, the number of colors available to the user and the shader used to render the piece.

Current allowed types are

The Tint1, Tint2, Tint3, and Tint4 layers have 1, 2, 3, and 4 colors available, respectively. They color using a simple multiply algorithm (final color = texture color * user color).


Regions

Note: Regions should match the texture file size.

The region property specifies the rectangle that encompasses the layer. Its format is as follows:

(left,top,right,bottom)

If the texture files are 512x512, then type this line:

Region=(0,0,511,511)


{Rules}

Available rules here are

Note: You cannot use the substitutes() rule to affect a skin layer.

Evaluation order begins with the base layer and works its way up the layer stack until it gets to the topmost layer. Layer rules are evaluated first this way, then rules for currently selected pieces are evaluated in the same way.


{Settings}

There are a few properties available to each layer in the {Settings} section:


Palettes

Palettes are textures that define what colors are available to the user for a given layer or piece.

HSL can tell the engine where on a palette the user clicked (via SetTexturePieceColor), and the engine will sample the texture to determine what color was picked. It can also bypass that and set the color directly (SetTexturePieceColorDirectly). You can also use a combination of the two functions to implement a "color theme" where colors from palettes are collected and reused over multiple pieces.

There are two kinds of palettes: Shared and Non-Shared.

A shared palette is specified like so:

Palette1=SharedPaletteName,paletteFileName.dds

And a non-shared palette looks like this:

Palette1=paletteFileName.dds

You can specify a different palette for each available color in the layer or piece type. The number in "Palette1" tells which color this palette corresponds to. The layer or piece type determines the number of colors available for assigning palettes and default colors (so a Tint2 layer can have a Palette1 and/or a Palette2 defined). If a palette isn't specifically defined, the engine uses the default palette, which is currently located at Character\Dynamic\TextureBanks\Palettes\palettedefault.dds.

paletteFileName.dds is the palette's texture name. This can be a full path, or just the file name. If it's just a file name, the palette is assumed to be in a "palettes" subdirectory of the current "texturebanks" directory

The thing that makes shared palettes special is that any place where there's a palette with that name (in the above example, SharedPaletteName), the colors are automatically synched. This is nice for color coordination. For example, you may choose to have pants and socks share a palette, so that you never have the problem of characters with dark pants and white socks (perish the thought!). It's a balance, though, because forcing colors means less customization for the user.

Here's an example palette that's appropriate for picking colors for metal objects:

Palette sample.png


Default Colors

(Read the Palettes section before you tackle this, and beware that skin is handled a little bit differently.)

Default colors are specified like so:

DefaultColor1=#Red,Green,Blue,Alpha

Notes:

It's not required, but probably a good idea that you get your default colors from the palettes available for the piece, for consistency's sake (you don't want the user to start out with a white staff if they can never manually pick that color themselves).


{Files}

This is where the actual textures go that are used for all of the pieces. It follows this format:

(texture_width,texture_height)
first_diffuse_map_d.dds,first_normal_map_n.dds,first_tintmask_map_t.dds
second_diffuse_map_d.dds,second_normal_map_n.dds,second_tintmask_map_t.dds

Note: If a Part will be swapped out for a larger Part that needs a Piece which uses a larger texture file size, make sure the Region is set for the largest file size expected as well as the files section.

You do not need to setup multiple (texture_width, texture_height) lines above the list of {Files} if the are different sizes per piece.


There's a naming convention that the engine uses to know what each texture functions as: diffuse maps should have _d right before the extension, normal maps should have _n, and tint mask maps should have _t (see above example).

You can bundle up multiple pieces per texture if you'd like; the engine can automatically calculate where and in what texture a specific piece is located based on the layer region and the texture dimensions provided in the {Files} section. When doing this, though, watch out for a couple of things:


{Pieces}

Pieces are specified one per line in the {Pieces} section, and must be unique only within a layer (so layer A and layer B can both have a piece named "leather glove").

The first piece specified becomes the default piece, which is the piece that's selected in the layer when the layer first becomes visible.

You can allow for nothing to be selected in a layer by specifying an empty piece, which is simply a piece named "Empty" (without quotes). There are two requirements for the empty piece:

Layer settings (properties in the {Settings}) are automatically applied to all pieces in the layer; however, you can have a piece override any or all of the settings.


HSL Usage

Palettes (with the exception of skin palettes) are sampled using the HSL function SetTexturePieceColor(). Pass in an x and y pixel offset from the top left corner of the texture and HeroEngine automatically samples the palette and assigns the color at that location to the piece you specify. Areas that have an alpha of 0 are not sampled, and the current color is returned.


Skin

HeroEngine features a special 3-way texture blending for layers with a type of Skin. This allows more control over skin than a simple color tint.


Skin Color Concepts

Skin works by blending between 1 to N number of textures (called components: current technology limits N to 3 components) based on blend weights passed in through the HSL functions SetSkinComponentBlend(s). In general, the blend amounts of the skin components should add up to 1.0 to get a smooth blend between the different textures, though you might experiment with values that don't add up to 1 to see what different effects you can get.

As an example, to get the Caucasian-Asian-Zombie here (equal blends of each) you'd give each skin component a weight of .333 by batching them together in a single list of floats and passing them to SetSkinComponentBlends.

Naturally, setting the weight for a single component to 1 and all other component weights to 0 will give a result as if the character were textured with just that single component texture. Also, take care that your components sum to at least your alpharef value or else your character will become invisible.

Note that because a character has only one "skin," you don't have to worry about specifying banks, layers, or pieces with skin functions. In fact, don't try: the standard bank/layer/piece functions won't work with skin.


Specifying Skin in a .dtb

To hook up skin, first create a new texture bank file with the Skin type.

A {Pieces} for a skin layer has some additional detail to it. Here's a sample one:

   {Pieces}
      (Diffuse)
        Blends=3
         Caucasian
           DefaultBlend=.333
         African
           DefaultBlend=.333
         Asian
           DefaultBlend=.333
         Zombie
      (Normal)
        Blends=2
         Human
           DefaultBlend=.5
         Zombie Bump
           DefaultBlend=.5

Three things make this section special from other {Pieces} sections:

In the above example, a new character's diffuse texture would be an equal blend between the Caucasian, African, and Asian diffuse textures. Its normal map would be an equal blend between the Human and Zombie Bump textures.

Note: Make sure that any Palettes, skin options, piece numbers and piece names between skin layers in different banks are exactly the same; otherwise, undefined behavior will result. The easiest way to do this is to make a "master" skin layer in one bank and copy and paste it into all other banks that need skin layers, changing the layer name and filenames as appropriate. If done correctly, all character parts with a skin blend applied will blend synchronously.

Skin Palettes

Since skin is handled different from other layer types, HeroEngine doesn't directly sample palettes for it. However, for user interface purposes it may be useful to display a palette to the user.

Since a linear blend requires all components to sum to 1.0, an excellent palette to use for a 3-way blend is a triangle with each pixel's color being determined by using the Barycentric coordinates of the point in the triangle as weights for blending between three corner colors. Here's what it looks like using pure red, green, and blue as the three corner colors:

Barycentric triangle.png

Tip: You can easily customize the above palette for your own needs by bringing it into Photoshop and using the red, green, and blue channels as masks to determine where to fill in your own colors.

Display the palette in a GUI control (call GetSkinPalettes to get all palette texture names for the character) and when the user clicks on the control, convert their mouse position from (x,y) to a Barycentric coordinate. Pass the Barycentric coordinate components as a list of floats to SetSkinComponentBlends to update your character's look.

Using the Caucasian/Asian/Zombie example here, here's how clicking in various places will give different blends:

Barycentric actions.png


Troubleshooting

Two layers' pieces are tinting the same color, but they don't share a palette.

Double-check that the two offending layers don't have the same name. Remember, all layer names must be unique!

A bunch of pieces are black!

Pieces are always white by default, even though I've specified DefaultColors.

Make sure that the components of your DefaultColor are between 0.0 and 1.0. If you're accidentally missing decimal points, you can easily have 213 instead of .213.

One tint channel seems to effect the entire map instead of one specified portion

Make sure your tint texture wasn't inadvertently saved out with a full white alpha channel.

All portions of a character using a skin blend are invisible

Check to make sure that all texture banks used by the character that specify a skin blend share the exact same settings, palettes, and piece names.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox