Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

If I have a Model that is drawn with a different effect occasionally, what is the typical approach to this?

Models have effects stored in each of their meshes, and you seem to be forced to use those.

Typically this is done:

foreach (ModelMesh mesh in model.Meshes)
{
    foreach (Effect effect in mesh.Effects)
    {
        effect.Parameters["World"].SetValue(world);
        // Other stuff related to this specific effect is done here.
    }
    mesh.Draw();
}

I want to be able to do this:

foreach (ModelMesh mesh in model.Meshes)
{
    myEffect.CurrentTechnique.Passes[0].Apply();
    mesh.Draw(); // Mesh will be drawn with "myEffect".
}

What are our options?

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

Shawn Hargreaves outlines the two options for changing which effect is used when rendering a model on his blog at http://blogs.msdn.com/b/shawnhar/archive/2006/12/07/rendering-a-model-with-a-custom-effect.aspx.

The first option is purely a run-time option: iterate over all of the model.MeshParts and directly modify the ModelMeshPart.Effect property to the new effect. I haven't tried this but I would expect it to work.

The second, and more flexible option, is to use your own custom ModelProcessor to modify the effect that is compiled into each model. If you take this approach you can write your own Effect which has several techniques, each with different shaders, Switching shaders at run-time is then just a matter of changing which technique each effect in the model will use.

foreach (ModelMesh mesh in model.Meshes)
{
    foreach (Effect effect in mesh.Effects)
    {
        effect.CurrentTechnique = effect.Techniques["CreateShadowMap"];
        // Other stuff related to this specific effect is done here.
    }
    mesh.Draw();
}
...
foreach (ModelMesh mesh in model.Meshes)
{
    foreach (Effect effect in mesh.Effects)
    {
        effect.CurrentTechnique = effect.Techniques["DrawWithShadowMap"];
        // Other stuff related to this specific effect is done here.
    }
    mesh.Draw();
}
share|improve this answer
    
"The first option is purely a run-time option: iterate over all of the model.MeshParts and directly modify the ModelMeshPart.Effect property to the new effect. I haven't tried this but I would expect it to work." Actually he's doing that at compile time (in a ContentProcessor) and you can't do that at run-time as far as I know. I think what you're trying to say is that I can assign an effect to the model and then just pick whatever technique I want in that effect at run-time. That's true but doesn't answer the question of: how do I use different effects on the same model at run-time? –  Olhovsky Mar 26 '11 at 0:38
    
I tried the first option and you can modify the effect at run-time using code like foreach (var mesh in model.Meshes) { foreach (var part in mesh.MeshParts) { part.Effect = newEffect; } } As for the second approach, doesn't the ability to change the technique at run-time give you the same functionality as changing the effect if you write a single effect that exposes the original multiple effects as separate techniques? –  Phil Dunstan Mar 27 '11 at 16:05
    
Are you using XNA 4? part.Effect = newEffect; doesn't work because part.Effect has no setter. –  Olhovsky Mar 27 '11 at 23:30
    
Oh, nevermind, you're right, you CAN change the effect that way. Thanks! –  Olhovsky Mar 27 '11 at 23:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.