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.

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 SimplestVertexShader(VertexToPixel input)
{
    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 OurFirstPixelShader(VertexToPixel PSIn)
{
    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
    {
        VertexShader = compile vs_3_0 SimplestVertexShader();
        PixelShader = compile ps_3_0 OurFirstPixelShader();
    }
}

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

share|improve this question
    
While importing can you access the original model's vertex elements? What does it say? –  AvengerDr 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
add comment

1 Answer

up vote 1 down vote accepted

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.

You'll need to add a parameter to your shader that represents the material color:

float4 DiffuseColor;

...and copy it from the effect that you're replacing:

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.

share|improve this answer
    
Thanks for the answer and solution! I've posted the new code as an answer to my simillar question at StackOverflow –  noamg97 Aug 16 '13 at 17:24
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.