这可能是一些新手问题,但我正在尝试使用其颜色(材质)渲染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();
}
}
答案 0 :(得分:1)
很高兴,在阅读了@AndrewRussell的评论和@Cole Campbell 's answer后,我终于设法解决了问题(以及我的代码中的一些其他错误)。
最终(工作)代码现在是:
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();
}
}
感谢所有帮助。 =]