Materials

Engine Nine ships with 5 basic materials that can be used across all supported platforms: BasicMaterial, SkinnedMaterial, EnvironmentMapMaterial, AlphaTestMaterial, DualTextureMaterial.

Screenshot 0001 Screenshot 0000
BasicMaterial BasicMaterial, DiffuseColor=”1,0,0”
Screenshot 0005 Screenshot 0008
BasicMaterial, Texture=”Stone” BasicMaterial, EmissiveColor=”0,1,1”
Screenshot 0002 Screenshot 0015
BasicMaterial Alpha=”0.5” EnvironmentMapMaterial
Screenshot 0009 Screenshot 0016
EnvironmentMapMaterial EnvironmentMapAmount=”0.5” DualTextureMaterial
 

Custom HLSL Material

CustomMaterial allows you to create materials from HLSL directly. The HLSL uses standard annotations to bind to the environment properties provided by the engine, such as world/view/projection transforms, light properties, viewport properties, etc..

Screenshot 0002

 

<Model Source="{ContentReference Assets/Tank}">
    <Model.Material>
        <CustomMaterial xml:space="preserve">
            <![CDATA[
            float4x4 WVP:WORLDVIEWPROJECTION;
            texture Diffuse:DIFFUSE;
            sampler2D DiffuseSampler = sampler_state
            {
                Texture = <Diffuse>;
            };

            void VS(float3 Position:POSITION, float2 UV:TEXCOORD0,
                out float4 oPosition:POSITION, out float2 oUV:TEXCOORD0)
            {
                oPosition = mul(float4(Position, 1), WVP);
                oUV = UV;
            }

            float4 PS(float2 UV:TEXCOORD0):COLOR
            {
                return float4(UV, 0, 1) * tex2D(DiffuseSampler, UV);
            }

            technique t0
            {
                pass p0  
                {        
                    VertexShader = compile vs_2_0 VS();
                    PixelShader = compile ps_2_0 PS();
                }
            }]]>
        </CustomMaterial>
    </Model.Material>
</Model>

 

 

MaterialGroup

All the above materials treat a material or a shader as a whole. When the number of shader required increases, the number of combinations of each feature increases exponentially, causing the number of shader permutations to explode. MaterialGroup strives to solve the problem by decomposing each feature into a MaterialPart that can be represented using a single HLSL function. Material parts can then be combined and reused to create the fully functional shader. The following example demonstrates the use of combining a DiffuseMaterialPart, a SkinnedMaterialPart and a DirectionalLightMaterialPart to simulate the SkinnedMaterial:

Screenshot 0001

<Model Source="{ContentReference Assets/Dude}">
    <Model.Material>
        <MaterialGroup>
            <DiffuseMaterialPart />
            <SkinnedMaterialPart />
            <DirectionalLightMaterialPart />
        </MaterialGroup>
    </Model.Material>
</Model>

 

There are a dozen of built-in material parts located under Nine.Graphics.Materials.MaterialParts namespace:

AlphaTestMaterialPart Clips a pixel based on alpha value.
ColorMatrixMaterialPart Changes the final color based on a color transform.
DeferredLightsMaterialPart Lights the object using deferred lighting.
DetailMaterialPart Adds an additional detailed texture layer.
DiffuseMaterialPart Shows the diffuse texture.
DirectionalLightMaterialPart Applies a forward directional light.
DualTextureMaterialPart Blends the diffuse color with another texture.
EmissiveMaterialPart Applies emissive color and emissive mapping.
FogMaterialPart Applies fog.
InstancedMaterialPart Used for model instancing.
NormalMapMaterialPart Enables normal mapping technique.
ShadowMapMaterialPart Enables shadow mapping technique.
SkinnedMaterialPart Enables hardware skinning.
SpecularMaterialPart Applies specular color and specular mapping.
TextureTransformMaterialPart Changes the texture coordinates based on a transform.

 

Custom HLSL MaterialPart

In addition to the built-in material parts listed above, CustomMaterialPart allows you to create any material part in an HLSL function. However, there are some limitations:

  • The name of the function has to be VertexShader or PixelShader.
  • Function parameters has to use the in/out/inout semantics.
  • The name of the function parameters is fixed to enable linking between material parts.
  • Function return values are not supported.
  • Structures are not supported.
  • Traditional /* … */ style comments are not supported.

The following example shows how to change the texture coordinates of the model based on time, and how to use together with other material parts:

Screenshot 0004

<Model Source="{ContentReference Assets/Dude}">
    <Model.Material>
        <MaterialGroup>
            <CustomMaterialPart xml:space="preserve">
                <![CDATA[
                    float Time:TIME;
                    void PixelShader(inout float2 uv:TEXCOORD0)
                    {
                        uv += frac(Time * 0.05f);
                    }
                ]]>
            </CustomMaterialPart>
            <DiffuseMaterialPart />
            <SkinnedMaterialPart />
            <DirectionalLightMaterialPart />
        </MaterialGroup>
    </Model.Material>
</Model>

Last edited Sep 26, 2012 at 7:50 AM by yufeih, version 12

Comments

No comments yet.