2013-08-15 6 views
0

이것은 아마도 초보자 용 질문 일뿐입니다. 그러나 색 (재료)을 사용하여 fbx 모델을 렌더링하려고합니다.사용자 지정 효과를 사용할 때 메쉬 색이 누락되었지만 BasicEffect를 사용하지 않는 경우

내가 BasicEffect를 사용해 보았을 때, 모든 것이 잘되고 색이 잘 맞았지만 이제는 사용자 정의 HLSL 효과 파일을 작성하고 있으며, 모델을 렌더링하려고 할 때마다, 현재의 정점 선언이 모든 요소 현재의 정점 셰이더에 의해 요구가 포함되어 있지 않습니다

:이 모델은 색상이 없음을 말한다. Color0이 (가) 없습니다.

HLSL로 작업 한 경험이 없으므로 어쩌면 어리석은 의미 론적 실수 (또는 이와 비슷한 것) 일 수 있습니다. 사용

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 코드 : 어쨌든, 여기에 (원래 Riemers 튜토리얼에서 가져온) 코드입니다

(...로드 :

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

당신의 HLSL에는 문제가 없지만 메쉬는 색 데이터를 지정하지 않는 것이 좋습니다. 'VertexColorEnabled = true'와 함께'BasicEffect'를 사용하면 같은 에러가 나옵니까? 이것은'COLOR0'을 사용하는 기본 효과 쉐이더의 버전을 가능하게합니다. 따라서 모델에 문제가 있는지 확인하십시오. –

+0

@AndrewRussell 예, 그게 전부입니다. _VertexColor_를 사용하면 같은 오류가 발생합니다. VertexColor를 사용하지 않고 BasicEffect를 사용하면 원래의 색상이 렌더링되므로 다른 질문이 생깁니다. 어떻게 그렇게 할 수 있습니까? (나는 Color0 대신 다른 것을 사용해야한다고 생각합니다) –

답변

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

모든 도움에 감사드립니다. =]