从DirectX中的多个渲染目标读取

时间:2013-03-15 01:44:06

标签: visual-c++ directx direct3d pixel-shader

我有两个渲染目标视图,我的后台缓冲区和一个表示专用掩码的Texture2D(我不能使用模板缓冲区来满足我的需要)。我的渲染方法看起来大致如下:

// clear the render target and depth stencil views, set render targets, 
// update subresources, set vertex buffers, topology, input layout, etc.

// draw to the back buffer and the mask
m_d3dContext->PSSetShader(m_pixelShader1.Get(), nullptr, 0);
m_d3dContext->IASetIndexBuffer(m_indexBuffer1.Get(), DXGI_FORMAT_R16_UINT, 0); 
m_d3dContext->DrawIndexed(m_indexCount1, 0, 0);

// read from the mask and draw to the back buffer
m_d3dContext->PSSetShader(m_pixelShader2.Get(), nullptr, 0);
m_d3dContext->IASetIndexBuffer(m_indexBuffer2.Get(), DXGI_FORMAT_R16_UINT, 0);
m_d3dContext->DrawIndexed(m_indexCount2, 0, 0);

PixelShader1看起来像这样(省略输入结构和其他一些部分):

struct PixelShaderInput
{
    float4 Color   : COLOR;
    float2 Texture : TEXCOORD;
};

struct PixelShaderOutput
{
    float4 Color : SV_TARGET0;
    float4 Mask  : SV_TARGET1;
};

PixelShaderOutput main(PixelShaderInput input)
{
    PixelShaderOutput output; 
    output.Color.rgba = input.Color;
    output.Mask.rgba = float4(1, 0, 0, 1);
    return output;
}

PixelShader2如下所示:

struct PixelShaderInput
{
    float3 Color   : COLOR0;
    float2 Texture : TEXCOORD0;
    float4 Mask    : COLOR1;
};

struct PixelShaderOutput
{
    float4 Color : SV_TARGET0; 
};

PixelShaderOutput main(PixelShaderInput input)
{
    PixelShaderOutput output; 

    // do some work with input.Texture

    if (input.Mask.x == 0)
    {
        output.Color = float4(0, 0, 0, 1); }
    }
    else
    {
        output.Color = float4(1, 1, 1, 1); 
    }

    return output;
}

使用Visual Studio的图形调试工具,我可以看到PixelShader1正确编写了蒙版纹理。在框架的末端,红色几何体出现在正确的位置。此外,后缓冲区(看起来不同)的输出也是预期的。所以我坚信PixelShader1是正确的。

然而,我从PixelShader2获得了意想不到的结果。单步执行它,input.Mask.x的值就到处都是。人们会期望它们是1或0,因为这是所有其他像素着色器设置它们,但相反,值看起来非常像纹理坐标。

所以,首先,我正在尝试做什么呢?如果是的话,任何人都可以在我如何阅读COLOR1时发现我的错误吗?我被这个困了几个小时,所以任何帮助都会非常感激。

我在DirectX 11,着色器模型4.0级别9_1和vc110中工作。

1 个答案:

答案 0 :(得分:1)

您的PixelShader2编写方式有一些概念错误。 PixelShader1将两个渲染纹理写入颜色和蒙版的值。在PixelShader 2中,您需要从纹理中读取这些值,而不是作为顶点输入。

Texture2D<float4> MaskTexture;
SamplerState MaskSampler;

struct PixelShaderInput
{
    float3 Color   : COLOR0;
    float2 Texture : TEXCOORD0;
};

struct PixelShaderOutput
{
    float4 Color : SV_TARGET0; 
};

PixelShaderOutput main(PixelShaderInput input)
{
    PixelShaderOutput output; 

    // do some work with input.Texture

    float maskValue = MaskTexture.Sample(MaskSampler, Texture).x;

    if (maskValue == 0)
    {
        output.Color = float4(0, 0, 0, 1);
    }
    else
    {
        output.Color = float4(1, 1, 1, 1); 
    }

    return output;
}

因此,为了做到这一点,你需要通过SetShaderResources()将MaskTexture(这是PixelShader1的第二个渲染目标输出)作为ShaderResource传递。您还需要创建一个SamplerState,并通过SetSamplerStates()将其设置到设备中。