2011-12-14 5 views
0

실제로 Apphub에서 찾은 다른 사람의 수정 프로그램을 사용하고 있습니다. (질문했을 텐데 분명히 질문을하기 위해 구독료를 지불해야합니다.) 어떤 방법 으로든이 사용자는 Skinned Model 효과를 Cel-Shading 효과와 병합했습니다. 그들은 Effect 코드를 게시했지만 사용 방법의 스 니펫이 아니므로 올바르게 구현하고 있는지 확신 할 수 없습니다. 스크린 상에 모델을 그려 넣을 수는 있지만 (셀 셰이더가 생성하는 컬러 윤곽선을 사용하더라도), 모델은 단색 검정색입니다. 모델의 텍스처를 올바르게 설정하지 않았을 수도 있습니다.XNA Skinned Model Cel-Shading이 모두 검은 색으로 표시됩니다.

여기에 다른 사람의 개조되지 않은 셀 쉐이딩 효과가 있습니다. 여기

//--------------------------- BASIC PROPERTIES------------------------------ 
#define MaxBones 60 
float4x3 Bones[MaxBones]; 
// The world transformation 
float4x4 World;  // The view transformation 
float4x4 View;  // The projection transformation float4x4 
Projection;  // The transpose of the inverse of the world 
transformation, // used for transforming the vertex's normal 
float4x4 WorldInverseTranspose; 

//---------------------------DIFFUSE LIGHT PROPERTIES ------------------------------ 
// The direction of the diffuse light 
float3 DiffuseLightDirection = float3(0, 0.5, 0.5); 
// The color of the diffuse light 
float4 DiffuseColor = float4(1, 1, 1, 1); 
// The intensity of the diffuse light 
float DiffuseIntensity = 5.7; 

//---------------------------TOON SHADER PROPERTIES ------------------------------ 
// The color to draw the lines in. Black is a good default. 
float4 LineColor = float4(0, 0, 0, 1); 
// The thickness of the lines. This may need to change, depending on the scale of 
// the objects you are drawing. 
float4 LineThickness = 0.12; 

//--------------------------- TEXTURE PROPERTIES ------------------------------ 
// The texture being used for the object 
texture Texture; 
// The texture sampler, which will get the texture color 
sampler2D textureSampler = sampler_state 
{ 
    Texture = (Texture); 
    MinFilter = Linear; 
    MagFilter = Linear; 
    AddressU = Clamp; 
    AddressV = Clamp; 
}; 

//--------------------------- DATA STRUCTURES ----------------------------- 
// The structure used to store information between the application and the 
// vertex shader 
struct AppToVertex { 
    float4 Position : SV_Position; 
    float3 Normal : NORMAL; 
    float2 TexCoord : TEXCOORD0; 
    int4 Indices : BLENDINDICES0; 
    float4 Weights : BLENDWEIGHT0; 
}; 

// The structure used to store information between the vertex shader and the 
// pixel shader 
struct VertexToPixel { 
    float4 Position : POSITION0; 
    float2 TextureCoordinate : TEXCOORD0; 
    float3 Normal : TEXCOORD1; 
}; 

//SKIN Metod 
void Skin(inout AppToVertex vin, uniform int boneCount) 
{ 
    float4x3 skinning = 0; 

    [unroll] 
    for (int i = 0; i < boneCount; i++) 
    { 
     skinning += Bones[vin.Indices[i]] * vin.Weights[i]; 
    } 

    vin.Position.xyz = mul(vin.Position, skinning); 
    vin.Normal = mul(vin.Normal, (float3x3)skinning); 
} 

//--------------------------- SHADERS ------------------------------ 
// The vertex shader that does cel shading. 
// It really only does the basic transformation of the vertex location, 
// and normal, and copies the texture coordinate over. 
VertexToPixel CelVertexShader(AppToVertex input) 
{ 
    VertexToPixel output; 
    Skin(input, 4); 

    // Transform the position 
    float4 worldPosition = mul(input.Position, World); 
    float4 viewPosition = mul(worldPosition, View); 
    output.Position = mul(viewPosition, Projection); 

    // Transform the normal 
    output.Normal = normalize(mul(input.Normal, WorldInverseTranspose)); 

    // Copy over the texture coordinate 
    output.TextureCoordinate = input.TexCoord; 

    return output; 
} 

// The pixel shader that does cel shading. Basically, it calculates 
// the color like is should, and then it discretizes the color into 
// one of four colors. 
float4 CelPixelShader(VertexToPixel input) : COLOR0 
{ 
    // Calculate diffuse light amount 
    float intensity = dot(normalize(DiffuseLightDirection), input.Normal); 
    if(intensity < 0) 
     intensity = 0; 

    // Calculate what would normally be the final color, including texturing and diffuse lighting 
    float4 color = tex2D(textureSampler, input.TextureCoordinate) * DiffuseColor * DiffuseIntensity; 
    color.a = 1; 

    // Discretize the intensity, based on a few cutoff points 
    if (intensity > 0.95) 
     color = float4(1.0,1,1,1.0) * color; 
    else if (intensity > 0.5) 
     color = float4(0.7,0.7,0.7,1.0) * color; 
    else if (intensity > 0.05) 
     color = float4(0.35,0.35,0.35,1.0) * color; 
    else 
     color = float4(0.1,0.1,0.1,1.0) * color; 

    return color; 
} 

// The vertex shader that does the outlines 
VertexToPixel OutlineVertexShader(AppToVertex input) 
{ 
    VertexToPixel output = (VertexToPixel)0; 
    Skin(input, 4); 

    // Calculate where the vertex ought to be. This line is equivalent 
    // to the transformations in the CelVertexShader. 
    float4 original = mul(mul(mul(input.Position, World), View), Projection); 

    // Calculates the normal of the vertex like it ought to be. 
    float4 normal = mul(mul(mul(input.Normal, World), View), Projection); 

    // Take the correct "original" location and translate the vertex a little 
    // bit in the direction of the normal to draw a slightly expanded object. 
    // Later, we will draw over most of this with the right color, except the expanded 
    // part, which will leave the outline that we want. 
    output.Position = original + (mul(LineThickness, normal)); 

    return output; 
} 

// The pixel shader for the outline. It is pretty simple: draw everything with the 
// correct line color. 
float4 OutlinePixelShader(VertexToPixel input) : COLOR0 
{ 
    return LineColor; 
} 

// The entire technique for doing toon shading 
technique Toon 
{ 
    // The first pass will go through and draw the back-facing triangles with the outline shader, 
    // which will draw a slightly larger version of the model with the outline color. Later, the 
    // model will get drawn normally, and draw over the top most of this, leaving only an outline. 
    pass Pass1 
    { 
     VertexShader = compile vs_1_1 OutlineVertexShader(); 
     PixelShader = compile ps_2_0 OutlinePixelShader(); 
     CullMode = CW; 
    } 

    // The second pass will draw the model like normal, but with the cel pixel shader, which will 
    // color the model with certain colors, giving us the cel/toon effect that we are looking for. 
    pass Pass2 
    { 
     VertexShader = compile vs_1_1 CelVertexShader(); 
     PixelShader = compile ps_2_0 CelPixelShader(); 
     CullMode = CCW; 
    } 
} 

그리고 내가 CEL-음영 효과가

public void Draw(Matrix viewMatrix, Matrix projectionMatrix) 
    { 
     Matrix[] boneTransforms = AnimPlayer.GetSkinTransforms(); //new Matrix[model.Bones.Count]; 
     Matrix worldMatrix = Orientation * Matrix.CreateTranslation(Position); 

     foreach (ModelMesh mesh in Model.Meshes) 
     { 
      foreach (ModelMeshPart part in mesh.MeshParts) 
      { 
       part.Effect = celshader; 
       part.Effect.CurrentTechnique = part.Effect.Techniques["Toon"]; 
       part.Effect.Parameters["Bones"].SetValue(boneTransforms); 
       part.Effect.Parameters["World"].SetValue(worldMatrix); 
       part.Effect.Parameters["View"].SetValue(viewMatrix); 
       part.Effect.Parameters["Projection"].SetValue(projectionMatrix); 
       part.Effect.Parameters["WorldInverseTranspose"].SetValue(Matrix.Transpose(Matrix.Invert(worldMatrix))); 
       part.Effect.Parameters["DiffuseLightDirection"].SetValue(new Vector3(.5f)); 
       part.Effect.Parameters["DiffuseColor"].SetValue(Color.White.ToVector4()); 
       part.Effect.Parameters["DiffuseIntensity"].SetValue(1); 
       part.Effect.Parameters["LineColor"].SetValue(Color.Black.ToVector4()); 
       part.Effect.Parameters["LineThickness"].SetValue(new Vector4(.1f)); 
       part.Effect.Parameters["Texture"].SetValue(Texture); 

       foreach (EffectPass pass in part.Effect.CurrentTechnique.Passes) 
       { 
        part.Effect.CurrentTechnique.Passes[0].Apply(); 
       } 
      } 
      mesh.Draw(); 
     } 
    } 

celshader이다 그리기 얼마나, 그리고 텍스처는 모델의로드 질감입니다. 실마리가 있습니까?

+0

업데이트 : //part.Effect.Parameters["DiffuseLightDirection"].SetValue(new Vector3을 주석 (.5f)); //part.Effect.Parameters[ "DiffuseColor"]. SetValue (Color.White.ToVector4()); //part.Effect.Parameters[ "DiffuseIntensity"].SetValue(1); //part.Effect.Parameters["LineColor"].SetValue(Color.Black.ToVector4()); //part.Effect.Parameters["LineThickness"].SetValue(new Vector4 (1f)); 은 색상을 표시 할 수 있지만 이제는 스킨이 엉망입니다. – Neovivacity

답변

0

난 당신이 살펴 보도록해야한다고 생각 : 당신은 효과를 할당해서는 안

http://msdn.microsoft.com/en-us/library/bb975391(v=xnagamestudio.31).aspx

모든 전화를 그리기; 로드 시간 동안 그렇게하십시오 (일반적으로 LoadContent에 있지만, 설정 방법은 가정하지 않습니다).

또한 Draw에서는 일반적으로 각 메쉬가 아니라 아티클에있는대로 각 효과에 대해 mesh.Draw()를 호출해야합니다.

0

나는 시뮬 CelShader :

내가 할 첫 번째 일은 내가 영향을 만들고 LoadContent에서 그 효과에 CEL 쉐이더를로드 인으로,이 오류가 있었다.

이제 모델을 그릴 때 셰이더를 사용하도록 모델의 다른 부분을 설정하고 싶지는 않습니다 (그러나 시도하지는 않았지만). 대신 여기에 셰이더 매개 변수를 설정하십시오. (mesh.MeshParts에서 foreach는 내부 (ModelMeshPart 부분) 루프)도

celShader.Parameters["Texture"].SetValue(texture); 
celShader.Parameters["World"].SetValue(world); 
celShader.Parameters["TintColor"].SetValue(Color.DarkBlue.ToVector4()); 
celShader.CurrentTechnique = celShader.Techniques["Toon"]; 

그리고는

graphicsDevice.SetVertexBuffer(meshPart.VertexBuffer,meshPart.VertexOffset); 
graphicsDevice.Indices = meshPart.IndexBuffer; 

그리고 우리는 쉐이더를 적용 할 수있는 모델의 지표를 설정하고있는 GraphicsDevice에 VertexBuffer에을 채우기 모델에 그리고 그것을 또한 그립니다!

foreach (EffectPass pass in celShader.CurrentTechnique.Passes) 
{ 
    pass.Apply(); 
    graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 
    meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount); 
} 

모델이 검은 색이면 오류가 발생합니다. 희망이 도움이

내 전체 도면 코드 :

public void Draw(GraphicsDevice graphicsDevice, Effect theEffect) 
    { 
     Matrix[] bones = animationManager.GetBones(); 

     celShader.Parameters["Projection"].SetValue(Camera.Proj); 
     celShader.Parameters["View"].SetValue(Camera.View); 

     // for each model in the mesh 
     foreach (ModelMesh mesh in test.Meshes) 
     { 
      // for each mesh part 
      foreach (ModelMeshPart meshPart in mesh.MeshParts) 
      { 
       graphicsDevice.SetVertexBuffer(meshPart.VertexBuffer, 
         meshPart.VertexOffset); 
       graphicsDevice.Indices = meshPart.IndexBuffer; 

       //here i load the texture!!!!!!!!! 
       Texture2D texture = ((SkinnedEffect)meshPart.Effect).Texture; 


       Matrix world = Matrix.Identity; 

       celShader.Parameters["Texture"].SetValue(texture); 
       celShader.Parameters["World"].SetValue(world); 

       celShader.Parameters["Bones"].SetValue(bones); 
       celShader.Parameters["TintColor"].SetValue(Color.DarkBlue.ToVector4()); 

       celShader.CurrentTechnique = celShader.Techniques["Toon"]; 
       // for each effect pass in the cell shader 
       foreach (EffectPass pass in celShader.CurrentTechnique.Passes) 
       { 
        pass.Apply(); 

        graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 
         meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount); 
       } 
      } 
     } 
} 
+0

안녕하세요. 두 가지 답변에 도움을 주셔서 감사합니다. 내 코드 좀 정리 했어. 너와 네 메쏘드 모두를 사용하여 그리기를 시도했다. 단지 mesh.Draw() 였고, 여전히 동일한 결과를 얻었고, 모델에서 껍질을 벗기다. (셀 시브로 보이지만). 나는 스크린 샷이이 시점에서 더 도움이 될 것이라고 생각했다. http://i1231.photobucket.com/albums/ee516/Neovivacity/celshadingError.png 스킨이 여러 개인 모델에 문제가있을 수 있습니다. SkinnedModel 자습서에서 직접 살펴보면 스킨이 적용된 부품의 헤드, 자켓, 바지 등의 이미지가 있습니다. 나는 새로운 모델을 시도 할 것이지만 나는 여전히 블렌더를 배우고있다. – Neovivacity

+0

텍스처를 어떻게로드합니까? 파일이나 메쉬에서? 내 전체 드로잉 코드로 게시물을 업데이트합니다. – OlssN

+0

텍스처가로드 될 때 텍스처가 자동으로로드됩니다 (Mesh에서 가정 함). – Neovivacity

관련 문제