Nerd Herder

Dean Johnson blogs about life on the XNA platform and tools team

How to set the effect (.fx) used on Model

How to set the effect (.fx) used on Model

Rate This
  • Comments 3

When you use the model processor build into the XNA Framework Content Pipeline you will notice that each ModelMeshPart on a Model has an Effect already loaded. By default this is an instance of BasicEffect with the models textures and other material properties already set. This is great when you want to get a model loaded and rendering quick but sometimes you want to set a custom effect that you have previously created.

To help show users how to load a custom effect file on a model we created a sample called Custom Model Effect found here. The sample sets the new effect file in a custom content processor before saving the model out into an .xnb file. In this post I hope to show how to can extend this idea to allow you to create a custom processor that will accept a processor parameter for the effect file. This will allow you to reuse the same processor for many of your models even if they use separate effect files.

The first step is to create a new Content Pipeline Extension Library project if you do not already have one setup for your project. You will also need to setup a reference to the new project in your content project. The XNA Docs have some great resources that show you how to do this.

Next you will need to overwrite the standard model processor.

        [ContentProcessor]
        public class CustomEffectModelProcessor : ModelProcessor

Your new class needs a processor parameter that will take in your new effect file name.

        [DisplayName("Custom Effect")]
        [DefaultValue("")]
        [Description("The custom effect applied to the model.")]
        public string CustomEffect
        {
            get { return customEffect; }
            set { customEffect = value; }
        }
        private string customEffect;

You will need to add a using statement for System.ComponentModel for the new parameter.

Next you will need to override the ConvertMaterial method of the standard model processor so we can call our new material processor. Also notice that we pass along the processor parameter we defined above.

protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context)
{
    OpaqueDataDictionary processorParameters = new OpaqueDataDictionary();
    processorParameters.Add("CustomEffect", customEffect);

    return context.Convert<MaterialContent, MaterialContent>(material, "CustomEffectMaterialProcessor", processorParameters);
}

Now our new model processor will be looking for a material processor called "CustomEffectMaterialProcessor". The next step is to create this new material processor.

[ContentProcessor]
class CustomEffectMaterialProcessor : MaterialProcessor

Our material processor needs two parts. The first is the same processor parameter as we created above for the model processor to accept the filename of the custom effect file. The other is an override of the Process method.

public override MaterialContent Process(MaterialContent input, ContentProcessorContext context)

In the process method we need to create the new EffectMaterialContent and load the custom effect from the file.

// Create a new effect material.
EffectMaterialContent customMaterial = new EffectMaterialContent();

// Point the new material at the custom effect file.
string effectFile = Path.GetFullPath(customEffect);
customMaterial.Effect = new ExternalReference<EffectContent>(effectFile);

// Loop over the textures in the current material adding them to the new material.
foreach (KeyValuePair<string, ExternalReference<TextureContent>> textureContent in input.Textures)
{
    customMaterial.Textures.Add(textureContent.Key, textureContent.Value);
}

// Loop over the opaque data in the current material adding them to the new material.
foreach (KeyValuePair<string, Object> opaqueData in input.OpaqueData)
{
    customMaterial.OpaqueData.Add(opaqueData.Key, opaqueData.Value);
}

// Call the base material processor to continue the rest of the processing.
return base.Process(customMaterial, context);

Now all you will need to do is set the Content Processor of your model to your new CustomEffectModelProcessor and set the Custom Effect to the effect file that you wish to use.

image

  • You've been kicked (a good thing) - Trackback from GameDevKicks.com

  • "OpaqueDataDictionary processorParameters = new OpaqueDataDictionar();"

    i thought it was "OpaqueDataDictionary processorParameters = new OpaqueDataDictionary();"

    am i right?

    Thanks you :)

  • @Raufan: Yep typo.

Page 1 of 1 (3 items)
Leave a Comment
  • Please add 5 and 4 and type the answer here:
  • Post
Translate This Page
Search
Archive