Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
给出wierd结果的法线映射。(C#XNA)_C#_Xna_Shader - Fatal编程技术网

给出wierd结果的法线映射。(C#XNA)

给出wierd结果的法线映射。(C#XNA),c#,xna,shader,C#,Xna,Shader,好的,所以这个问题有点大,出于同样的原因,我宁愿发布尽可能少的代码,但更希望你能想到它可能是什么。我会把代码贴在我觉得有问题的地方。如果你想看到更多,请询问,我会提供 所以,我只是为我的游戏“偷”了一个着色器。我的意思是找到了一个我以前做过的教程,然后复制了最终结果。因此我知道着色器应该工作,因为我以前使用过它 我有一个自定义网格类,还有一个自定义顶点结构。我以前从未做过xertex结构,所以最初我认为这就是问题所在。 但我后来发现了一些反驳: 他们所有的变量似乎都是正确的,除了凹凸贴图之外,一

好的,所以这个问题有点大,出于同样的原因,我宁愿发布尽可能少的代码,但更希望你能想到它可能是什么。我会把代码贴在我觉得有问题的地方。如果你想看到更多,请询问,我会提供

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

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

这是我得到的输出。请记住,这是一个体素引擎。如您所见,所有框都具有相同的wierd法线贴图阴影。但是,这是法线贴图:

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

  • 这可能是我在xna中设置着色器的方式
  • 它也可能是顶点结构中的某个东西
  • 这也可能是我调用实际绘图函数的方式
  • 下面是这三件事(以及着色器)的代码:

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

    着色器:

        // 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();
        }
    }
    
    //XNA 4.0着色器编程#4-法线映射
    //母体
    四驱世界;
    浮动4x4视图;
    浮动4x4投影;
    //光相关
    浮动4环境色;
    漂浮环境强度;
    漂浮方向;
    4扩散色;
    漂浮扩散强度;
    浮动4镜面颜色;
    3眼位;
    纹理2D彩色地图;
    sampler2D ColorMapSampler=采样器\状态
    {
    纹理=;
    MinFilter=线性;
    磁滤波器=线性;
    MipFilter=线性;
    };
    纹理2D法线贴图;
    sampler2D NormalMapSampler=采样器\状态
    {
    纹理=;
    MinFilter=线性;
    磁滤波器=线性;
    MipFilter=线性;
    };
    //VertexShader的输入
    结构VertexShaderInput
    {
    浮动4位置:位置0;
    浮动2 TexCoord:TEXCOORD0;
    float3 Normal:NORMAL0;
    浮动3副法线:副法线0;
    float3切线:切线0;
    };
    //顶点着色器的输出,用于以后的处理
    结构VertexShaderOutput
    {
    浮动4位置:位置0;
    浮动2 TexCoord:TEXCOORD0;
    浮动3视图:TEXCOORD1;
    float3x3 WorldToTangentSpace:TEXCOORD2;
    };
    //顶点着色器。
    VertexShaderOutput VertexShaderFunction(VertexShaderInput输入)
    {
    VertexShaderOutput输出;
    float4 worldPosition=mul(input.Position,World);
    float4 viewPosition=mul(世界位置,视图);
    输出位置=mul(视图位置、投影);
    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(眼位,1.0)-worldPosition);
    返回输出;
    }
    //像素着色器
    float4 PixelShaderFunction(VertexShaderOutput输入):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漫反射=饱和(点(-LightDirection,normal));
    float4 reflect=规格化(2*漫反射*法线-float4(光照方向,1.0));
    float4镜面反射=pow(饱和(点(反射,输入.视图)),32);
    返回颜色*环境颜色*环境强度+
    颜色*漫反射强度*漫反射颜色*漫反射+
    颜色*镜面反射颜色*镜面反射;
    }
    //我们的技术
    技术1
    {
    通行证1
    {
    VertexShader=编译vs_2_0 VertexShaderFunction();
    PixelShader=编译ps_2_0 PixelShaderFunction();
    }
    }
    
    此操作的顺序不正确:

    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);
    
    否则,法线将从世界空间变换中缩放,并将产生非常亮和非常暗的面片(这看起来像是您的问题)。顺便说一句,鉴于您对体素引擎的法线贴图感兴趣,请查看我制作的以下内容:

    希望你得到启发,完成你的项目。

    你是说
    规范化(mul(input.Tangent,World))
    (而不是
    规范化(mul(input.Tangent,World)
    )?
    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);