【问题标题】:Shader Input Layout Invalid着色器输入布局无效
【发布时间】:2012-10-15 02:40:06
【问题描述】:

我正在尝试向我的工作代码中添加内容,但在调用 CreateInputLayout() 时返回错误 [Invalid Arg]。

在我添加纹理之前它可以工作,但是当我添加它时会失败。
编译后的着色器文件没有错误。
我认为我制作布局的方式很糟糕。这是正确的吗?

C++ 顶点结构:

struct VertexData{
    XMFLOAT3 Pos;
    XMFLOAT4 Color;
    XMFLOAT2 TexCoord;
};

C++ 布局:

    D3D11_INPUT_ELEMENT_DESC inputLayout[]={
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    }; uint lSize=sizeof(inputLayout)/sizeof(inputLayout[0]);

着色器代码:

    // Stuff from DX Tutorial 7
Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register( s0 );

cbuffer ViewData : register(b0){
    matrix World;
    matrix View;
    matrix Projection;
}

struct VS_INPUT{
    float4 pos : SV_POSITION;
    float4 color : COLOR0;
    float2 tex : TEXCOORD0;
};
struct PS_INPUT{
    float4 pos : SV_POSITION;
    float4 color : COLOR0;
    float2 tex : TEXCOORD0;
};

PS_INPUT VS(VS_INPUT input){
    PS_INPUT output=(PS_INPUT)0;

    output.pos=mul(input.pos, World);
    output.pos=mul(output.pos, View);
    output.pos=mul(output.pos, Projection);

    output.color = input.color;

    output.tex = input.tex;

    return output;
}

float4 PS(PS_INPUT input) : SV_Target {
    return input.color;
}

编辑:

在玩了一堆着色器代码之后,我发现如果我将...
1st位置的语义更改为:float4 pos : POSITION;
第二个位置:float4 pos : SV_POSITION;
...输入布局成功创建。

我在没有 SV_ [系统值] 前缀的情况下都尝试了,但也失败了。我不知道为什么我不能让它们相同。

Semantics 看起来有点神奇。不知道我是应该用这个回答我自己的问题,还是等待更聪明的人更好地回答。

【问题讨论】:

    标签: c++ directx shader


    【解决方案1】:

    你的结构不匹配:

    struct VertexData
    {
        XMFLOAT3 Pos;  // float3 here
        XMFLOAT4 Color;
        XMFLOAT2 TexCoord;
    };
    
    struct VS_INPUT{
        float4 pos : SV_POSITION; // float4 here
        float4 color : COLOR0;
        float2 tex : TEXCOORD0;
    };
    

    对于 3D 空间中的位置,我更喜欢使用 float3。所以,作为你的输入布局:

    "POSITION", 0, R32G32B32_FLOAT
    

    关于语义魔术: HLSL 中的名称必须与输入布局名称匹配。例如:

    布局:

    { "POSITION", 0, .. }
    

    顶点着色器:

    float4 pos : POSITION0;
    

    唯一的例外是像素着色器对于像素的输入位置必须始终具有float4 pos : SV_POSITION语义(它是S系统V语义语义之一) .

    作为奖励,我想推荐一些常用的东西:

    • int size = ARRYSIZE(inputayoutDesc);
    • 使用 D3D11_APPEND_ALIGNED_ELEMENT 代替 12、28 数字作为对齐偏移量。

    【讨论】:

    【解决方案2】:

    如果输入语义在您的输入顶点中,则它们不应该是 SV_POSITION,我认为它们应该是 POSITION。

    你也声明了这个 -

    struct VS_INPUT{
        float4 pos : SV_POSITION;
    

    这不应该是float3 pos : POSITION;

    您的输入布局只有 3 个浮点数用于该项目。不确定是不是问题,但看起来不太正确。

    【讨论】:

    • 输入语义不能在这些输入上?心灵扭曲。 float4 的想法是我之前问过的。其他人说它用于对齐数据。 stackoverflow.com/questions/12889619/…
    • SV_POSITION 是顶点着色器输出和像素着色器输入的适当语义。顶点着色器的输入是不对的,用你自己的名字就好了。 POSITION 可以正常工作,显然它需要在 VS 中的结构和输入布局声明中使用相同的名称。在您的 VS 中,您将 4 个浮点数加载到 pos 中,但仅在输入中为其提供 3 个数据。我认为只要你只在着色器中使用 .xyz 元素,它仍然可以正常工作。除此之外不确定如何提供帮助(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    • 2016-03-16
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    相关资源
    最近更新 更多