Цвет сетки отсутствует при использовании пользовательского эффекта, но не при использовании BasicEffect

Вероятно, это какой-то вопрос новичка, но я пытаюсь визуализировать модель fbx с ее цветами (Материалы).

Дело в том, что когда я пытался использовать BasicEffect, все прошло хорошо, и цвета были хорошо прорисованы - но сейчас я пишу собственный файл эффекта HLSL, и всякий раз, когда я пытаюсь визуализировать модель с ним, он говорит, что Модель не имеет цвета:

Текущее объявление вершины не включает все элементы, требуемые текущим вершинным шейдером. Color0 отсутствует.

Вероятно, это какая-то глупая семантическая ошибка (или что-то в этом роде), поскольку я не очень опытен в работе с HLSL. Во всяком случае, вот код (первоначально взят из учебника Riemers):

float4x4 xWorldViewProjection;

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

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

struct PixelToFrame
{
    float4 Color        : COLOR0;
};

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

VertexToPixel SimplestVertexShader( float4 inPos : POSITION0, float3 inNormal: NORMAL0, float4 inColor : COLOR0)
{
    VertexToPixel Output = (VertexToPixel)0;

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

    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();
    }
}

и используемый код XNA:

(после загрузки:)

    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();
    }
}

1 ответ

К счастью, после прочтения как комментария @AndrewRussell, так и ответа @Cole Campbell, я наконец-то сумел разобраться с проблемой (и несколькими другими ошибками, которые имел мой код).

Окончательный (рабочий) код теперь:

float4x4 xWorldViewProjection;

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

struct VertexToPixel
{
    float4 Position      : POSITION;    
    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(float4 inPosition : POSITION, float3 inNormal : TEXCOORD0)
{
    VertexToPixel Output = (VertexToPixel)0;

    Output.Position = mul(inPosition, xWorldViewProjection);
    Output.Normal = normalize(mul(inNormal, (float3x3)xWorld));    
    Output.Position3d = mul(inPosition, xWorld);

    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 = float4(DiffuseColor, 1) * (diffuseLightingFactor + xAmbient);

    return Output;
}

technique Simplest
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 SimplestVertexShader();
        PixelShader = compile ps_3_0 OurFirstPixelShader();
    }
}

...

List<Vector3> OriginalDiffuseColors = new List<Vector3>();

...

protected override void LoadContent()
{
    ...

    foreach (ModelMesh mesh in MainRoom.Meshes)
    {
         foreach (BasicEffect effect in mesh.Effects)
             OriginalDiffuseColors.Add(effect.DiffuseColor);
         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);

    roomEffect.CurrentTechnique = roomEffect.Techniques["Simplest"];

    int count = 0;
    foreach (ModelMesh mesh in model.Meshes)
    {
        foreach (Effect currentEffect in mesh.Effects)
        {
            Matrix worldMatrix = bones[mesh.ParentBone.Index] * world;
            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);
            currentEffect.Parameters["DiffuseColor"].SetValue(OriginalDiffuseColors[count++]);
        }
        mesh.Draw();
    }
}

Спасибо за помощь. знак равно

Другие вопросы по тегам