2013-10-19 5 views
2

조명과 관련하여 최근에 문제가있었습니다. 내가 예제를 꽤 잘하고있는 구글 소스를 발견했다. 그러나 현재 프로젝트에 구현하려고하면 매우 이상한 버그가 발생합니다. 주된 하나는 주변 조명을 활성화 할 때 내 텍스처가 "혼합"된다는 것입니다. 즉, 모델이 다른 하나의 텍스처를 가져옵니다. you can see it there.HLSL/XNA 주변 조명 텍스처가 다중 통과 조명과 섞여 있습니다.

내 모델의 모든 메시에 동일한 효과를 사용하고 있습니다. 나는 이것이 문제가 될 수 있다고 생각하지만 새로운 모델의 효과를 "재설정"하는 방법을 모른다. 가능한가?

내 쉐이더는 다음과 같습니다.

float4x4 WVP;

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

매우

감사 : 효과를로드 할 때 나는이 적용하고

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

: 여기

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

그리고 내가 실제로 내 효과를 적용하는 방법입니다 업데이트 : 내가 해보려고 했어. 드로잉 할 때 각 모델에 대한 효과는 있지만, 아무 것도 변경하지 않은 것처럼 보입니다. 나는 XNA가 효과가 이미 이전에로드되었고 새로운 것을로드하고 싶지 않음을 감지했기 때문에 그럴 것이라고 생각합니다. 왜 그런가?

답변

2

좋아, 문제는 실제로 실제로 매우 바보 같았습니다. 모든 메시에 동일한 효과를 적용하고있었습니다. 모델을로드 할 때 단순히 Effect.Clone()을 추가하면 효과가있었습니다!