New effects in the Content Pipeline

This article is prerecorded. Shawn is away (on honeymoon). Replies to comments will be delayed.

In previous XNA versions, the Content Pipeline imported materials like so:

  • If an FBX or X model directly references a .fx effect, the importer creates an EffectMaterialContent, which becomes a custom Effect when loaded into your game.

  • Otherwise the importer creates a BasicMaterialContent, which is loaded as a BasicEffect.

  • BasicMaterialContent properties such as texture, diffuse color, and specular power are set from the source FBX or X material.

  • If the source has other material properties that BasicEffect does not support, these are stored in BasicMaterialContent.OpaqueData, in case a custom processor wants to do something cool with them.

To use custom effects that are not directly referenced by a model, you have two options:

  • Use a custom processor to apply the effect (see this sample).

  • Or you can do it at runtime (see the ChangeEffectUsedByModel method from this sample).

Game Studio 4.0 works the same way, but adds a new processor parameter for choosing which of the five built-in effects is selected by default (if the source model does not directly reference a .fx material):


Along with this parameter come new design-time material types, so BasicMaterialContent is joined by SkinnedMaterialContent, EnvironmentMapMaterialContent, etc.

Depending which effect you choose, some additional work may be needed to configure it:

  • If you use SkinnedEffect, you must call SetBoneTransforms to set the current animation state.

  • If you use EnvironmentMapEffect, you must provide a suitable cubemap. You can do this either at runtime or in a custom content processor, but just setting the Default Effect processor parameter to EnvironmentMapEffect will not do this for you, because it has no way to know which cubemap you want to use.

  • If you use DualTextureEffect, the second texture can be automatically imported from FBX materials. If the FBX does not specify a second texture, you must set it yourself, either at runtime or in a custom content processor (see the DualTextureProcessor from this example).

Comments (5)

  1. tom says:

    EnvironmentMapEffect has a bug.

    1. dynamic generate TextureCube.

    2. use EnvironmentMapEffect

    3. Tex reverses X

  2. Calvin says:

    Thanks! This looks useful…

  3. Andrew says:

    I tried to use those "other material properties", but can't find them. In the MaterialContent.OpaqueData I only see the properties that the BasicMaterial uses.

    If I change the Default Effect to EnvironmentMapEffect, the additional properties are still ignored, including those that the EnvironmentMapEffect knows.

    I'm using XNA 4.0

  4. ShawnHargreaves says:

    Andrew: the way materials work in the pipeline is to have a strongly typed class (eg. BasicMaterialContent, or EnvironmentMappedMaterialContent), which has certain properties that it knows about, plus a bag of any other unknown property values in case a custom processor wants to do something with them. The input from the model importer will always be a BasicMaterialContent, never an EnvironmentMappedMaterialContent.  The Default Effect property lets you specify that the input material should be converted to some other type, but if you have custom behaviors or extra property values that you want to apply while doing this, you need to write a custom processor to do that conversion. The default one only knows about the standard BasicMaterialContent properties, and has no idea what to do with any extra custom values that you might have stored in the opaque data property bag.

  5. Andrew says:

    I wrote a custom ModelProcessor, and overrode the ConvertMaterial function. At that point the extra properties are already missing from the MaterialContents OpaqueData dictionary.

    Can I access the imported material earlier?

    Or may be the problem is that it's a Windows Phone 7 app, where custom shaders are not supported?

    What I'm trying to do is to select a material from the built-in ones and set up it's properties using only the imported fbx file.