着色器链接错误/不匹配

时间:2016-06-10 02:29:45

标签: directx shader hlsl geometry-shader

我正致力于动态立方体贴图渲染。特别是,使用DirectX SDK示例" CubeMapGS"中的着色器渲染立方体贴图。着色器似乎是正确的,你可以在这里看到:

SamplerState ss;
Texture2D tex;

cbuffer Constants
{
    float4x4 worldMat;
    float4x4 viewMats[6];
    float4x4 projMat;
};

struct VS_CUBEMAP_IN
{
    float4 Pos : POSITION;
    float3 Normal : NORMAL;
    float2 Tex : TEXCOORD0;
};

struct GS_CUBEMAP_IN
{
    float4 Pos : SV_POSITION; // World position
    float2 Tex : TEXCOORD0; // Texture coord
};


struct PS_CUBEMAP_IN
{
    float4 Pos : SV_POSITION; // Projection coord
    float2 Tex : TEXCOORD0; // Texture coord
    uint RTIndex : SV_RenderTargetArrayIndex;
};


GS_CUBEMAP_IN VShader(VS_CUBEMAP_IN input)
{
    GS_CUBEMAP_IN output = (GS_CUBEMAP_IN) 0.0f;

    // Compute world position
    output.Pos = mul(input.Pos, worldMat);

    // Propagate tex coord
    output.Tex = input.Tex;

    return output;
}

[maxvertexcount(18)]
void GShader(triangle GS_CUBEMAP_IN input[3], inout TriangleStream<PS_CUBEMAP_IN> CubeMapStream)
{
    for (int f = 0; f < 6; ++f)
    {
        // Compute screen coordinates
        PS_CUBEMAP_IN output;
        output.RTIndex = f;
        for (int v = 0; v < 3; v++)
        {
            output.Pos = mul(input[v].Pos, viewMats[f]);
            output.Pos = mul(output.Pos, projMat);
            output.Tex = input[v].Tex;
            CubeMapStream.Append(output);
        }
        CubeMapStream.RestartStrip();
    }
}


float4 PShader(PS_CUBEMAP_IN input) : SV_Target {
    return tex.Sample(ss, input.Tex);
}

但是,它不起作用。实际上,我收到以下DirectX错误消息:

D3D11 ERROR: ID3D11DeviceContext::DrawIndexed: Vertex Shader - Geometry Shader linkage error: Signatures between stages are incompatible. Semantic 'SV_POSITION' is defined for mismatched hardware registers between the output stage and input stage. [ EXECUTION ERROR #343: DEVICE_SHADER_LINKAGE_REGISTERINDEX]
D3D11 ERROR: ID3D11DeviceContext::DrawIndexed: Vertex Shader - Geometry Shader linkage error: Signatures between stages are incompatible. Semantic 'TEXCOORD' is defined for mismatched hardware registers between the output stage and input stage. [ EXECUTION ERROR #343: DEVICE_SHADER_LINKAGE_REGISTERINDEX]
D3D11 ERROR: ID3D11DeviceContext::DrawIndexed: Geometry Shader - Pixel Shader linkage error: Signatures between stages are incompatible. Semantic 'TEXCOORD' is defined for mismatched hardware registers between the output stage and input stage. [ EXECUTION ERROR #343: DEVICE_SHADER_LINKAGE_REGISTERINDEX]
D3D11 ERROR: ID3D11DeviceContext::DrawIndexed: Geometry Shader - Pixel Shader linkage error: Signatures between stages are incompatible. Semantic 'SV_POSITION' is defined for mismatched hardware registers between the output stage and input stage. [ EXECUTION ERROR #343: DEVICE_SHADER_LINKAGE_REGISTERINDEX]

错误消息似乎表明输入参数与不同Shader函数的输出值之间存在某种不匹配,但我无法真正识别这种不匹配。

有关此错误的任何想法或解释?

1 个答案:

答案 0 :(得分:0)

你没有在像素着色器中读取Pos,因为Tex在几何着色器输出中得到寄存器0,它是寄存器1。

您可以通过在结构

的末尾放置下一阶段未读取的输出来解决此问题
struct PS_CUBEMAP_IN
{
    float2 Tex : TEXCOORD0; // Texture coord
    uint RTIndex : SV_RenderTargetArrayIndex;
    float4 Pos : SV_POSITION; // Projection coord
};

另外,请注意在像素着色器之前使用特殊SV_POSITION而不是最后一个阶段,它在nvidia和AMD之间的行为并不相同。只需将其命名为POSDONTMESSWITHME,并且因为顶点着色器必须输出它,所以在GS_CUBEMAP_IN的末尾添加一个假的并将其设置为0.

作为一条建议,几何着色器是一个坏主意。几何扩展非常慢,对于那种应用程序来说不值得,它们更擅长剔除三角形,遗憾的是它们是输出rt和视口索引而没有扩展的唯一阶段。