This is an old question, but I had to figure this out myself yesterday so I thought I d post a followup:
If you re using the default FBX content processor and have the DefaultEffect
property set to BasicEffect
, you can get the Texture2D
for the object via:
texture = ((BasicEffect)model.Meshes[0].Effects[0]).Texture;
Note that the each mesh in the model may have a different texture.
The texture coordinates are stored in the MeshPart
sVertexBuffer
along with position, etc. I ve seen two vertex declarations. For a model/mesh that used a single texture (bitmap material in 3DS Max), the vertex declaration was VertexPositionNormalTexture
.
For a model that had two textures (a bitmap and an opacity/alpha map), the declaration had the elements:
Position
Normal
Texture (usage index 0)
Texture (usage index 1)
or, wrapped into an IVertexType
structure,
public struct VertexPositionNormalTextureTexture : IVertexType
{
public Vector3 Position;
public Vector3 Normal;
public Vector4 Texture0;
public Vector4 Texture1;
public static VertexDeclaration VertexDeclaration
{
get
{
return new VertexDeclaration
(
new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.Position, 0)
,
new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.Normal, 0)
,
new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 0)
,
new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 1)
);
}
}
VertexDeclaration IVertexType.VertexDeclaration
{
get { return VertexDeclaration; }
}
}
and the equivelant HLSL structure:
struct VertexPositionNormalTextureTexture
{
float3 Position : POSITION0;
float3 Normal : NORMAL0;
float4 Texture0 : TEXCOORD0;
float4 Texture1 : TEXCOORD1;
};
Note that I changed .Position
and .Normal
from Vector4
and Vector3
to float4
and float3
before I posted this, and haven t tested it. It s possible that they may need to be changed back to Vector4
and float4
.
Of course, you ll need a sampler and some basic logic in your pixel shader to read each texture. Assuming you ve set two effect parameters xTexture0 and xTexture1 to Texture2D
objects containing your color texture and opacity map,
// texture sampler
sampler Sampler0 = sampler_state
{
Texture = (xTexture0);
};
sampler Sampler1 = sampler_state
{
Texture = (xTexture1);
};
and here s a simple two-texture pixel shader. If you only want one texture, just read from the first sampler and return the value, or apply lighting, etc.
float4 TwoTexturePixelShader(VertexPositionNormalTextureTexture input) : COLOR0
{
float4 texel0;
float4 texel1;
float4 pixel;
// check global effect parameter to see if we want textures turned on
// (useful for debugging geometry weirdness)
if (TexturesEnabled)
{
texel0 = tex2D(Sampler0, input.Texture0);
texel1 = tex2D(Sampler1, input.Texture1);
/// Assume texel1 is an alpha map, so just multiple texel0 by that alpha.
pixel.rgb=texel0.rgb;
pixel.a=texel0.a;
}
else
/// return 100% green
pixel = float4(0,1,0,1);
return pixel;
}
The relevant points here are that the texture coordinates are already present in the FBX and are already stored in each MeshPart
s VertexBuffer
, so all you need to do is extract the texture, pass it into your shader as a global effect parameter, and proceed as normal.