DirectX 11渲染到纹理

6
基本上我正在尝试在DirectX 11中呈现一个场景到纹理中,就像这个ogl教程here,但我遇到了一些问题:
  1. 当我启动程序时,绝对没有任何东西被渲染,我不知道为什么。
  2. 唯一正确显示的是清除颜色的纹理。 debug build
  3. 我已经在RenderDoc中检查了可执行文件,在捕获的帧中,后台缓冲区绘制了四边形,上面的纹理正确地显示了场景! renderdoc capture output

源代码峰值:

                D3D11_TEXTURE2D_DESC texDesc;
            ZeroMemory(&texDesc, sizeof(D3D11_TEXTURE2D_DESC));

            texDesc.Width = Data.Width;
            texDesc.Height = Data.Height;
            texDesc.Format = R32G32B32A32_FLOAT;
            texDesc.Usage = D3D11_USAGE_DEFAULT;
            texDesc.SampleDesc.Count = 1;
            texDesc.SampleDesc.Quality = 0;
            texDesc.CPUAccessFlags = 0;
            texDesc.ArraySize = 1;
            texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
            texDesc.MiscFlags = 0;
            texDesc.MipLevels = 1;

            if (Data.Img_Data_Buf == NULL)
            {
                if (FAILED(DX11Context::GetDevice()->CreateTexture2D(&texDesc, NULL, &result->tex2D)))
                {
                    Log.Error("[DirectX] Texture2D Creation Failed for Null-ed Texture2D!\n");
                    return;
                }
                D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
                srvDesc.Format = texDesc.Format;
                srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
                srvDesc.Texture2D.MostDetailedMip = 0;
                srvDesc.Texture2D.MipLevels = 1;

                DX11Context::GetDevice()->CreateShaderResourceView(result->tex2D, &srvDesc, &result->resourceView);

                return;
            }
            //depth stencil texture 
            D3D11_TEXTURE2D_DESC texDesc;
            {
                texDesc.Width = size.x;
                texDesc.Height = size.y;
                texDesc.MipLevels = 1;
                texDesc.ArraySize = 1;
                texDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
                texDesc.SampleDesc.Count = 1;
                texDesc.SampleDesc.Quality = 0;
                texDesc.Usage = D3D11_USAGE_DEFAULT;
                texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
                texDesc.CPUAccessFlags = 0;
                texDesc.MiscFlags = 0;
            }
            if (FAILED(API::DirectX::DX11Context::GetDevice()->CreateTexture2D(&texDesc, nullptr, &depthstenciltex)))
            {
                Log.Error("[DX11RenderTarget] Failed to create DepthStencilTexture for render-target!\n");
                //Return or the next call will fail too
                return;
            }
            if (FAILED(API::DirectX::DX11Context::GetDevice()->CreateDepthStencilView(depthstenciltex, nullptr, &depthstencilview)))
            {
                Log.Error("[DX11RenderTarget] Failed to create DepthStencilView for render-target!\n");
            }

            //render target
            D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
            ZeroMemory(&renderTargetViewDesc, sizeof(D3D11_RENDER_TARGET_VIEW_DESC));
            renderTargetViewDesc.Format = texDesc.Format;

            renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
            renderTargetViewDesc.Texture2D.MipSlice = 0;

            ID3D11RenderTargetView* rtv;

            if (FAILED(API::DirectX::DX11Context::GetDevice()->CreateRenderTargetView(texture->tex2D, &renderTargetViewDesc, &rtv)))
            {
                Log.Error("[DX11RenderTarget] Failed to create render-target-view (RTV)!\n");
                return;
            }

            //binding
            Context->OMSetRenderTargets(1, &rtv, rt->depthstenciltex);

着色器:

    std::string VertexShader = R"(struct VertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD;
};

struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD;
};

cbuffer NE_Camera : register(b0)
{
    matrix Model;
    matrix View;
    matrix Projection;
};

PixelInputType main(VertexInputType input)
{
    PixelInputType output;

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = mul(Model, input.position);
    output.position = mul(View, output.position);
    output.position = mul(Projection, output.position);

    // Store the input texture for the pixel shader to use.
    output.tex = input.tex;
    return output;
})";

    std::string PixelShader = R"(
struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD;
};

Texture2D NE_Tex_Diffuse : register(t0);
SamplerState NE_Tex_Diffuse_Sampler : register(s0);

float4 main(PixelInputType input) : SV_TARGET
{
    return NE_Tex_Diffuse.Sample(NE_Tex_Diffuse_Sampler, input.tex);
}
)";
    std::string ScreenVertexShader = R"(struct VertexInputType
{
    float2 position : POSITION;
    float2 tex : TEXCOORD;
};

struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD;
};


PixelInputType main(VertexInputType input)
{
    PixelInputType output;

    // CalcSulate the position of the vertex against the world, view, and projection matrices.
    output.position = float4(input.position.x,input.position.y,0.0f,1.0f);
    // Store the input texture for the pixel shader to use.
    output.tex = input.tex;
    return output;
})";

    std::string ScreenPixelShader = R"(
struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD;
};

Texture2D ScreenTexture : register(t0);
SamplerState ScreenTexture_Sampler : register(s0);

float4 main(PixelInputType input) : SV_TARGET
{
    return float4(ScreenTexture.Sample(ScreenTexture_Sampler, input.tex).rgb, 1.0f);
}
)";

完整源代码

我还使用Visual Studio图形调试器捕获了一帧,并注意到渲染到纹理的绘制调用具有 "阶段未运行,无输出" 的PS着色器。

注意:我知道在DirectX中场景应该翻转。


你有很多库代码,很难看出可能存在的问题。在 Stack Overflow 上,您需要发布简洁的代码片段以获得真正的帮助。或者,您可以通过 DirectX 工具包教程 并特别是 这个 来解决问题。 - Chuck Walbourn
@ChuckWalbourn 我添加了资源创建代码,这样就够了吗? - Zlixine
@ChuckWalbourn,实际上我已经多次查看了代码,调试输出没有任何问题,所有资源创建都返回S_OK,而且我正在使用DirectX10.1特性级别。顺便说一句,我在Visual Studio图形调试器中运行并捕获了另一个日志,我注意到在每个“Draw”函数中,PS Shader被绑定,但上面写着“Stage didn't run, no output”,很奇怪... - Zlixine
你能分享一下RenderDoc的捕获吗? - Michael Nastenko
@MichaelNastenko 请查看答案。 - Zlixine
显示剩余3条评论
1个回答

3
我已经找到了导致这个问题的错误,我没有在渲染时清除深度模板视图。我想知道为什么清除DSV对RenderTarget输出至关重要。

DSV中的深度用于确定应在PixelShader中绘制的像素是已绘制像素的前面还是后面。如果在前面,则将像素的深度写入DSV中的深度掩码。因此,对于第一帧,它已经起作用,因为深度掩码只包含“远离”值。如果不清除为“远离”,所有像素都会被拒绝,因为在相同位置上已经有相同深度的东西了。当您检查DepthState设置时,可能会发现类似DepthFunc = LESS的内容。如果不清除DSV,则LESS_EQUAL应该会产生一些z-fighting伪影。 - Auskennfuchs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接