English 中文(简体)
XNA .Fbx textures
原标题:

I m using the standard .fbx importer with custom shaders in XNA. The .fbx model is UV wrapped properly and is textured appropriately when I use BasicEffect. However when I use my custom effect I have to load the texture in as a parameter, and it is not mapped correctly.

Questions: 1) How can I texture my .fbx model properly using the included texture s coordinates with custom effects? 2) Is there a way to access the texture from the loaded .fbx model object? Where does this texture go?

Note: I ve studied custom content pipelines and don t believe writing my own Fbx importer/processor will be efficient. However if someone can descriptively supply me with firsthand experience of this being the answer than I will use the custom pipeline.

Thank you for your time and for reading this post.

最佳回答

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.

问题回答

The reason it s not working is because you have to set the effect s parameters manually instead of relying on the basiceffect (which would have had the shader parameters set in the content pipeline). Now, I m not familiar with your shader so I couldn t prescribe code to solve your problem ...

To answer your second question, you can get around it in a roundabout sort of way. Because the model loads in the content pipeline with basiceffect by default, the texture is imported and assigned to the shader s parameters inside of the pipeline. So if you want to access it you d have to look at the modelmeshpart s default effect property. Here is a forum post that describes this process.

The more correct answer would be a compromise between a full on custom importer and just using the default. You can make a custom modelprocessor that inherits from the existing one. In there, you can import your own custom effect, along with your custom textures and whatever parameters you need to set. and set it on the modelcontent. There was an article (either on Shawn Hargreave s blog, or on msdn) that showed how to do this, but I m failing to find it at the moment unfortunately.

good luck!





相关问题
copying a texture in xna into another texture

I am loading a Texture2D that contains multiple sprite textures. I would like to pull the individual textures out when I load the initial Texture to store into separate Texture2D objects, but can t ...

XNA Antialias question!

I ve got problems with XNA and antialiasing. I can activate it using graphics.PreferMultiSampling = true; graphics.ApplyChanges(); however - it s only 2x antialiasing. Even if I set ...

Take screen shot in XNA

How can I take a screen shot of the screen in XNA? Is it possible without System.Drawing.Graphics.CopyFromScreen or Win32API? If it s not possible, Is there any way to draw a System.Drawing.Bitmap to ...

XNA .Fbx textures

I m using the standard .fbx importer with custom shaders in XNA. The .fbx model is UV wrapped properly and is textured appropriately when I use BasicEffect. However when I use my custom effect I have ...

Can t install XNA

I m trying to install XNA. When the installation starts I got an error that says "XNA GSE 1.0 refresh requires Visual C# 2005 express edition sp1..." I use Windows 7 and I have Visual Studio 2008 &...

Is there a 3D equivalant to clamp in XNA?

I m building a 3D game but i only plan on using a 2D perspective thus not taking the z axis into the equasion, i want to be able to limit the movement of one of my models so it doesn t move out of the ...

Fetching the vertices from the backbuffer (HLSL) on XNA

Hello and sorry for the obscure title :} I`ll try to explain the best i can. First of all, i am new to HLSL but i understand about the pipeline and stuff that are from the fairy world. What i`m ...

Simple XNA 2d physics library

Working on a 2D project and wanted some recommendations on a simple 2d physics library for use in C# with the XNA framework. I was looking at Farseer or physics2d. Anyone have any other suggestions? ...

热门标签