0

好的,所以这个问题有点大,出于同样的原因,我宁愿发布尽可能少的代码,而是让你有关于它可能是什么的想法。我将在我认为可能存在问题的地方发布代码。如果您想查看更多内容,请询问,我会提供。

所以,我只是为我的游戏“偷”了一个着色器。偷了我的意思是找到了一个我以前做过的教程,只是复制了最终结果。因此我知道着色器应该可以工作,因为我以前用过它。

我有一个自定义网格类,还有一个自定义顶点结构。我以前从未做过 xertex 结构,所以最初我认为这就是问题所在。但是我后来发现了一些反驳:他们所有的变量似乎都是正确的,除了凹凸映射之外一切都有效。更改切线和/或副法线似乎对阴影没有任何影响。所以我认为错误不在于它们的计算方式,而在于它们的使用方式。

http://imageshack.us/photo/my-images/838/w6kv.png/

这是我得到的输出。请记住,这是一个体素引擎。正如你所看到的,所有的盒子都有同样奇怪的法线贴图阴影。然而,这是法线贴图:

http://imageshack.us/photo/my-images/268/r7jt.jpg/

如您所见,它们根本不适合。现在,这可能是我所看到的三件事之一:

  1. 这可能是我在 xna 中设置着色器的方式。
  2. 它也可能是顶点结构中的东西
  3. 这也可能是我调用实际绘图功能的方式。

所以这是这三件事的代码(以及着色器):

着色器设置:((在这里我设置了着色器的数据,并绘制了网格))

// Bind the parameters with the shader.
BBS.Parameters["World"].SetValue(Matrix.Identity);
BBS.Parameters["View"].SetValue(camera.viewMatrix);
BBS.Parameters["Projection"].SetValue(camera.projectionMatrix);

BBS.Parameters["AmbientColor"].SetValue(Color.White.ToVector4());
BBS.Parameters["AmbientIntensity"].SetValue(0.5f);

Vector3 LD = new Vector3(0, 1, -1);
LD.Normalize();

BBS.Parameters["DiffuseColor"].SetValue(Color.White.ToVector4());
BBS.Parameters["DiffuseIntensity"].SetValue(0);
BBS.Parameters["LightDirection"].SetValue(LD);

BBS.Parameters["EyePosition"].SetValue(new Vector3(0.0f, 2.0f, 5.0f));
BBS.Parameters["SpecularColor"].SetValue(Color.White.ToVector4());
BBS.Parameters["ColorMap"].SetValue(cubeTexture);
BBS.Parameters["NormalMap"].SetValue(Content.Load<Texture2D>("images"));


BBS.CurrentTechnique = BBS.Techniques["Technique1"];

for (int i = 0; i < BBS.CurrentTechnique.Passes.Count; i++)
{
    //EffectPass.Apply will update the device to
    //begin using the state information defined in the current pass
    BBS.CurrentTechnique.Passes[i].Apply();

    //theMesh contains all of the information required to draw
    //the current mesh
    graphics.DrawUserPrimitives(PrimitiveType.TriangleList, Mesh.Vertices, 0, Mesh.NUM_TRIANGLES);
}

顶点结构:

public struct VertexPositionNormalTangentBinormalTexture : IVertexType
{ 
    public Vector3 Position; 
    public Vector3 Normal; 
    public Vector2 TextureCoordinate; 
    public Vector3 Tangent; 
    public Vector3 Binormal;

    public static readonly VertexDeclaration VertexElements = new VertexDeclaration
    ( 
        new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), 
        new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0), 
        new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0), 
        new VertexElement(32, VertexElementFormat.Vector3, VertexElementUsage.Tangent, 0), 
        new VertexElement(44, VertexElementFormat.Vector3, VertexElementUsage.Binormal, 0)
    );


    VertexDeclaration IVertexType.VertexDeclaration { get { return VertexElements; } }

    public static readonly int SizeInBytes = sizeof(float) * (3 + 3 + 2 + 3 + 3);
}

着色器:

    // XNA 4.0 Shader Programming #4 - Normal Mapping

// Matrix
float4x4 World;
float4x4 View;
float4x4 Projection;

// Light related
float4 AmbientColor;
float AmbientIntensity;

float3 LightDirection;
float4 DiffuseColor;
float DiffuseIntensity;

float4 SpecularColor;
float3 EyePosition;


texture2D ColorMap;
sampler2D ColorMapSampler = sampler_state
{
    Texture = <ColorMap>;
    MinFilter = linear;
    MagFilter = linear;
    MipFilter = linear;
};

texture2D NormalMap;
sampler2D NormalMapSampler = sampler_state
{
    Texture = <NormalMap>;
    MinFilter = linear;
    MagFilter = linear;
    MipFilter = linear;
};

// The input for the VertexShader
struct VertexShaderInput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
    float3 Normal : NORMAL0;
    float3 Binormal : BINORMAL0;
    float3 Tangent : TANGENT0;
};

// The output from the vertex shader, used for later processing
struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
    float3 View : TEXCOORD1;
    float3x3 WorldToTangentSpace : TEXCOORD2;
};

// The VertexShader.
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);
    output.TexCoord = input.TexCoord;

    output.WorldToTangentSpace[0] = mul(normalize(input.Tangent), World);
    output.WorldToTangentSpace[1] = mul(normalize(input.Binormal), World);
    output.WorldToTangentSpace[2] = mul(normalize(input.Normal), World);

    output.View = normalize(float4(EyePosition,1.0) - worldPosition);

    return output;
}

// The Pixel Shader
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    float4 color = tex2D(ColorMapSampler, input.TexCoord);

    float3 normalMap = 2.0 *(tex2D(NormalMapSampler, input.TexCoord)) - 1.0;
    normalMap = normalize(mul(normalMap, input.WorldToTangentSpace));
    float4 normal = float4(normalMap,1.0);

    float4 diffuse = saturate(dot(-LightDirection,normal));
    float4 reflect = normalize(2*diffuse*normal-float4(LightDirection,1.0));
    float4 specular = pow(saturate(dot(reflect,input.View)),32);

    return  color * AmbientColor * AmbientIntensity + 
            color * DiffuseIntensity * DiffuseColor * diffuse + 
            color * SpecularColor * specular;
}

// Our Techinique
technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
4

1 回答 1

0

这不是按照正确的顺序完成的:

output.WorldToTangentSpace[0] = mul(normalize(input.Tangent), World);
output.WorldToTangentSpace[1] = mul(normalize(input.Binormal), World);
output.WorldToTangentSpace[2] = mul(normalize(input.Normal), World);

它应该是这样的:

output.WorldToTangentSpace[0] = normalize(mul(input.Tangent, World));
output.WorldToTangentSpace[1] = normalize(mul(input.Binormal, World));
output.WorldToTangentSpace[2] = normalize(mul(input.Normal, World));

否则,您的法线将根据世界空间转换进行缩放,并导致非常明亮和非常黑暗的补丁(这看起来像您的问题)。顺便说一句,如果您对体素引擎的法线映射感兴趣,请查看我制作的以下内容:

http://www.youtube.com/watch?v=roMlOmNgr_w http://www.youtube.com/watch?v=qkfHoGzQ8ZY

希望您受到启发并完成您的项目。

于 2014-01-11T23:38:03.713 回答