# XNA & HLSL - rendering a model with its original materials (colors)

I am currently trying to code my own HLSL effect file, in order to render an FBX model I made with Autodesk maya, and to which I have applied some materials (colors).

before trying to write an effect file, I have tried using XNA's BasicEffect, which rendered the model as expected with the materials I had set in maya. Now though, when I'm using my own HLSL effect file, there's always an error saying that my model doesn't have any colors:

The current vertex declaration does not include all the elements required by the current vertex shader. Color0 is missing.

My HLSL effect file (partially leared from riemers.net):

float4x4 xWorldViewProjection;

float4x4 xWorld;
float3 xLightPos;
float xLightPower;
float xAmbient;

struct VertexToPixel
{
float4 Position     : POSITION;
float4 Color        : COLOR0;
float3 Normal        : TEXCOORD0;
float3 Position3D    : TEXCOORD1;
};

struct PixelToFrame
{
float4 Color        : COLOR0;
};

float DotProduct(float3 lightPos, float3 pos3D, float3 normal)
{
float3 lightDir = normalize(pos3D - lightPos);
return dot(-lightDir, normal);
}

{
VertexToPixel Output = (VertexToPixel)0;

Output.Position =mul(input.Position, xWorldViewProjection);
Output.Normal = normalize(mul(input.Normal, (float3x3)xWorld));
Output.Position3D = mul(input.Position3D, xWorld);
Output.Color = input.Color;

return Output;
}

{
PixelToFrame Output = (PixelToFrame)0;

float diffuseLightingFactor = DotProduct(xLightPos, PSIn.Position3D, PSIn.Normal);
diffuseLightingFactor = saturate(diffuseLightingFactor);
diffuseLightingFactor *= xLightPower;

Output.Color = PSIn.Color* (diffuseLightingFactor + xAmbient);

return Output;
}

technique Simplest
{
pass Pass0
{
}
}


And my XNA code:

foreach (ModelMesh mesh in MainRoom.Meshes)
foreach (ModelMeshPart meshPart in mesh.MeshParts)
meshPart.Effect = roomEffect.Clone();


...

private void DrawModel(Model model, Matrix world)
{
Matrix[] bones = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(bones);

foreach (ModelMesh mesh in model.Meshes)
{
foreach (Effect currentEffect in mesh.Effects)
{
Matrix worldMatrix = bones[mesh.ParentBone.Index] * world;

roomEffect.CurrentTechnique = roomEffect.Techniques["Simplest"];
currentEffect.Parameters["xWorldViewProjection"].SetValue(worldMatrix * camera.view * camera.projection);
currentEffect.Parameters["xWorld"].SetValue(worldMatrix);
currentEffect.Parameters["xLightPos"].SetValue(lightPos);
currentEffect.Parameters["xLightPower"].SetValue(lightPower);
currentEffect.Parameters["xAmbient"].SetValue(ambientPower);
}
mesh.Draw();
}
}


I'm fairly new to HLSL (but not to XNA though), any help would be nice.

EDIT: I have also tried rendering a different model with materials, but it just gives the same error.

Solution: Thanks to Cole Campbell's answer and, the full working code can be found here

• While importing can you access the original model's vertex elements? What does it say? – TheWanderer Aug 16 '13 at 9:39
• @AvengerDr what do you mean by that? And how can I do this? – noamg97 Aug 16 '13 at 10:30

You're getting this error because your HLSL effect requires a color channel on the vertex data:

struct VertexToPixel
{
float4 Position     : POSITION;
float4 Color        : COLOR0;
float3 Normal        : TEXCOORD0;
float3 Position3D    : TEXCOORD1;
};


...but your models don't have that channel on their vertices. Which channels exist on a model is a function of how they're exported from the program that created them.

The built-in XNA BasicEffect is intelligent enough to choose a different technique depending on the vertex format of the model being rendered, which is why it doesn't run into this problem.

The specific problem which you face arises from a misunderstanding of what Color0 constitutes. Material colors are different from vertex colors. Material colors should be specified as a parameter in the shader. Vertex colors are part of the vertex data.

float4 DiffuseColor;

myEffect.Parameters["DiffuseColor"].SetValue(oldBasicEffect.DiffuseColor);

...and then use that to produce the final color for your vertex, and remove the float4 Color: COLOR0 declaration from your vertex data entirely.