xna

Multiple textures (or materials) on models

Hi, this time I’ll play a little with effects (don’t worry, I’m awful at HLSL so this won’t be complicate).

Generally, the problem in multi texture effects is to decide “how much” of each material apply. There are hundreds of approaches and different algorithms. I’ll use a very simple one: We have two textures, a base texture (for example a base skin texture for a character) and a brush texture (lets say, a piece of cloth). The second texture is a transparent texture with some areas painted.

What we are going to do is, take the base texture, and remove the areas that are not transparent on the second one. Although this sound complicated, this is super easy to do. I’ll post some code of the .fx file now:

First, notice I’ll be using two samplers. One for each texture I’ll be using.

texture TextureMap;
sampler2D TextureMapSampler = sampler_state
{
    texture = (TextureMap);
    AddressU = WRAP;
    AddressV = WRAP;
    MinFilter = LINEAR;
    MipFilter = LINEAR;
    MagFilter = LINEAR;
};

texture Brush0;
sampler2D Brush0Sampler = sampler_state
{
    texture = (Brush0);
    AddressU = WRAP;
    AddressV = WRAP;
    MinFilter = LINEAR;
    MipFilter = LINEAR;
    MagFilter = LINEAR;
};

I’ll skip the vertex shader since it’s very simple. I’ll go straight to the algorithm:

  // this will remove part of the base texture in order to apply the second material
    float amount = 1 – tex2D(Brush0Sampler, input.UV).a;
   output = (tex2D(TextureMapSampler, input.UV)) * amount;
   output += (tex2D(Brush0Sampler, input.UV));  

As you see, it’s really simple. 1 means full color without transparency. I’m removing the amount of color of the second texture. Piece of cake !

Now some XNA – C# code. First I’m loading an effect and applying to the model. Since a lot of people don’t know how to do this I’ll pos it.

model = Content.Load<Model>("cube");
effect = Content.Load<Effect>("MultiTexture");

// apply the effect
foreach (ModelMesh mesh in model.Meshes)
{
    foreach (ModelMeshPart meshPart in mesh.MeshParts)
    {
        meshPart.Effect = effect;
    }
}

And now, the drawing part where we assign the textures:

Matrix View = Matrix.CreateLookAt(new Vector3(0, 2, -6), Vector3.Zero, Vector3.UnitX);

Matrix Projection = 
    Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 1, 100);

Matrix[] container = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(container);

foreach (ModelMesh mesh in model.Meshes)
{
    foreach (Effect effect in mesh.Effects)
    {
        effect.Parameters["view"].SetValue(View);
        effect.Parameters["projection"].SetValue(Projection);
        effect.Parameters["world"].SetValue(container[mesh.ParentBone.Index] 
            * Matrix.CreateRotationY(MathHelper.ToRadians(rotation)));

        effect.Parameters["TextureMap"].SetValue(baseTexture);
        effect.Parameters["Brush0"].SetValue(secondTexture);
    }
    mesh.Draw();
}  

And of course, here is the solution to download !

1254270360_page_white_visualstudio[2]

2 thoughts on “Multiple textures (or materials) on models”

  1. Hi Angel Arcoraci,
    This post is very useful for me. I’m having problem with multi texturing and your post may help me. But I’m still not understand it clearly without source code. So can you re-upload the source code?
    Thanks you so much!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s