0
\$\begingroup\$

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

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

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the answer and solution! I've posted the new code as an answer to my simillar question at StackOverflow \$\endgroup\$
    – noamg97
    Aug 16, 2013 at 17:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .