Creating MaterialGroup programmatically.

Dec 6, 2012 at 10:07 AM

Hello again :)

I'm afraid It's silly question, but how to create MaterialGroup object programmatically? There is no constructor.

Let's say I want write this in C# code:

<Model Source="{ContentReference Assets/Tank}" Transform.Scale="0.05,0.05,0.05">
    <Model.Material>
        <MaterialGroup>
            <DiffuseMaterialPart />
            <DeferredLightsMaterialPart />
        </MaterialGroup>
    </Model.Material>
</Model>

Thank you.

Coordinator
Dec 6, 2012 at 10:37 AM
You can’t. Because MaterialGroup relies on dynamic shader compilation, which is not supported in XNA runtime.
Dec 6, 2012 at 10:54 AM
Edited Dec 6, 2012 at 10:55 AM

You could define some Material groups in xaml and load them like any other content. i.e.

<MaterialGroup xmlns="http://schemas.microsoft.com/nine/2011/xaml">
    <InstancedMaterialPart  />
    <DiffuseMaterialPart Texture="{ContentReference ../Textures/blank}" DiffuseColor=".2, .7, .2" />
    <DirectionalLightMaterialPart />
</MaterialGroup>
var node = new Sphere(game.GraphicsDevice) { Material = game.Content.Load<Material>("Material/DebugMaterial") };
Dec 6, 2012 at 10:55 AM

ok, so how to set DeferredLightsMaterialPart for Deferred lighting (PointLight, SpotLight...) to programmatically created models and primitives?

Dec 6, 2012 at 10:56 AM

Oh, you were faster :D THX for tip.

Dec 6, 2012 at 11:20 AM

Works great. Solved. THX.

Dec 21, 2012 at 7:11 AM
Edited Dec 21, 2012 at 7:13 AM

Ok... This solution leads to another problem. When I use Content.Load<MaterialGroup>() method I got same instance of object. My Material group contains DiffuseMaterialPart for changing difuse color programmatically. I can't use Basic material, because I need DeferredLightsMaterialPart for deffered lighting.

Can someone help me to solve this problem:
- I have several primitive Boxes.
- I want to chage its color programmatically (e.g. by Color class) separately for each box.
- I need deffered lighting because PointLights and SpotLights.

Thank you.

Coordinator
Dec 21, 2012 at 9:30 AM

The recommended approach is to embed the material inside the box like:

<Box>

<MaterialGroup>...</MaterialGroup>

</Box>

To create a new box instance, use "Scene.Add(new Instance("Box"))".

 

Here is a walkaround to create a new instance of MaterialGroup:

new Instance("mat").CreateInstance(scene.ServiceProvider)

Dec 21, 2012 at 10:35 AM

One of the most valuable thing in this project is fast and clear support ;)
Works like a charm. THX.