2013-10-19 29 views
2

我一直在照明最近有一些麻煩。我發現了一個在谷歌上的源代碼,在這個例子中工作得很好。但是,當我嘗試將其實施到當前項目時,我遇到了一些非常奇怪的錯誤。最主要的是當我僅激活環境光時,我的紋理「混合起來」,這意味着模型會獲得另一個紋理you can see it thereHLSL/XNA環境光線質地混合多道照明

我對模型的每個網格使用相同的效果。我想這可能是問題所在,但我真的不知道如何「重置」新模型的效果。可能嗎?

這是我的着色器:

float4x4 WVP;

float4x4 WVP; 
float3x3 World; 

float3 Ke; 
float3 Ka; 
float3 Kd; 
float3 Ks; 
float specularPower; 

float3 globalAmbient; 
float3 lightColor; 

float3 eyePosition; 
float3 lightDirection; 
float3 lightPosition; 
float spotPower; 

texture2D Texture; 
sampler2D texSampler = sampler_state 
{ 
    Texture = <Texture>; 
    MinFilter = anisotropic; 
    MagFilter = anisotropic; 
    MipFilter = linear; 
    MaxAnisotropy = 16; 
}; 

struct VertexShaderInput 
{ 
    float4 Position : POSITION0; 
    float2 Texture : TEXCOORD0; 
    float3 Normal : NORMAL0; 
}; 

struct VertexShaderOutput 
{ 
    float4 Position : POSITION0; 
    float2 Texture : TEXCOORD0; 
    float3 PositionO: TEXCOORD1; 
    float3 Normal : NORMAL0; 
}; 

VertexShaderOutput VertexShaderFunction(VertexShaderInput input) 
{ 
    VertexShaderOutput output; 

    output.Position = mul(input.Position, WVP); 

    output.Normal = input.Normal; 

    output.PositionO = input.Position.xyz; 

    output.Texture = input.Texture; 

    return output; 
} 

float4 PSAmbient(VertexShaderOutput input) : COLOR0 
{ 
    return float4(Ka*globalAmbient + Ke,1) * tex2D(texSampler,input.Texture); 
} 

float4 PSDirectionalLight(VertexShaderOutput input) : COLOR0 
{ 
    //Difuze 
    float3 L = normalize(-lightDirection); 
    float diffuseLight = max(dot(input.Normal,L), 0); 
    float3 diffuse = Kd*lightColor*diffuseLight; 

    //Specular 
    float3 V = normalize(eyePosition - input.PositionO); 
    float3 H = normalize(L + V); 
    float specularLight = pow(max(dot(input.Normal,H),0),specularPower); 
    if(diffuseLight<=0) specularLight=0; 
    float3 specular = Ks * lightColor * specularLight; 

    //sum all light components 
    float3 light = diffuse + specular; 

    return float4(light,1) * tex2D(texSampler,input.Texture); 
} 

technique MultiPassLight 
{ 
    pass Ambient 
    { 
     VertexShader = compile vs_3_0 VertexShaderFunction(); 
     PixelShader = compile ps_3_0 PSAmbient(); 
    } 
    pass Directional 
    { 
     PixelShader = compile ps_3_0 PSDirectionalLight(); 
    } 
} 

這裏是我如何實際運用我的影響:

public void ApplyLights(ModelMesh mesh, Matrix world, 
    Texture2D modelTexture, Camera camera, Effect effect, 
    GraphicsDevice graphicsDevice) 
{ 
    graphicsDevice.BlendState = BlendState.Opaque; 

    effect.CurrentTechnique.Passes["Ambient"].Apply(); 

    foreach (ModelMeshPart part in mesh.MeshParts) 
    { 
     graphicsDevice.SetVertexBuffer(part.VertexBuffer); 
     graphicsDevice.Indices = part.IndexBuffer; 

     // Texturing 
     graphicsDevice.BlendState = BlendState.AlphaBlend; 
     if (modelTexture != null) 
     { 
      effect.Parameters["Texture"].SetValue(
       modelTexture 
      ); 
     } 

     graphicsDevice.DrawIndexedPrimitives(
      PrimitiveType.TriangleList, 
      part.VertexOffset, 
      0, 
      part.NumVertices, 
      part.StartIndex, 
      part.PrimitiveCount 
     ); 

     // Applying our shader to all the mesh parts 
     effect.Parameters["WVP"].SetValue(
      world * 
      camera.View * 
      camera.Projection 
     ); 
     effect.Parameters["World"].SetValue(world); 
     effect.Parameters["eyePosition"].SetValue(
      camera.Position 
     ); 


     graphicsDevice.BlendState = BlendState.Additive; 

     // Drawing lights 
     foreach (DirectionalLight light in DirectionalLights) 
     { 
      effect.Parameters["lightColor"].SetValue(light.Color.ToVector3()); 
      effect.Parameters["lightDirection"].SetValue(light.Direction); 

      // Applying changes and drawing them 
      effect.CurrentTechnique.Passes["Directional"].Apply(); 
      graphicsDevice.DrawIndexedPrimitives(
       PrimitiveType.TriangleList, 
       part.VertexOffset, 
       0, 
       part.NumVertices, 
       part.StartIndex, 
       part.PrimitiveCount 
      ); 
     } 
    } 

加載效果時,我也想申請這個:

effect.Parameters["lightColor"].SetValue(Color.White.ToVector3()); 
effect.Parameters["globalAmbient"].SetValue(Color.White.ToVector3()); 
effect.Parameters["Ke"].SetValue(0.0f); 
effect.Parameters["Ka"].SetValue(0.01f); 
effect.Parameters["Kd"].SetValue(1.0f); 
effect.Parameters["Ks"].SetValue(0.3f); 
effect.Parameters["specularPower"].SetValue(100); 

非常感謝您

更新: 我試圖l在繪製時爲每個模型添加效果,但似乎沒有改變任何東西。我想這是因爲XNA檢測到效果之前已經加載過,並且不想加載新效果。任何想法爲什麼?

回答

2

好吧,所以問題實際上很愚蠢。我將相同的效果應用於每個網格。我只是在加載模型時添加了一個Effect.Clone(),它工作正常!