HLSL - 渲染渲染目标纹理始终返回黑色

时间:2015-05-12 00:54:23

标签: c++ directx-11 hlsl pixel-shader

好的,首先,我是DirectX11的新手,这实际上是我使用它的第一个项目。我对计算机图形学一般也比较新,所以我可能有一些概念错了,但对于这种特殊情况,我不这么认为。我的代码基于RasterTek tutorials

在尝试实现着色器着色器时,我需要将场景渲染为2D纹理,然后在生成的图像上执行高斯模糊。 这部分似乎工作正常,因为使用Visual Studio图形调试器时输出似乎是我所期望的。

然而,在完成所有后期处理之后,我使用一个简单的着色器渲染一个四边形到后备缓冲区,该着色器使用模糊的最终输出作为资源。这总是给我一个黑屏。当我使用VS图形调试器调试我的像素着色器时,似乎Sample(texture,uv)方法在尝试对该纹理进行采样时始终返回(0,0,0,1)。

如果我使用不同的纹理(如某些普通地图或其他任何东西)作为资源,则像素着色器工作正常,而不是在使用先前传递的任何渲染时。 行为特别奇怪,因为当使用任何rendertargets作为资源时,实际模糊着色器工作正常。

我知道我不能使用rendertarget作为输入和输出但我认为我已经覆盖了,因为我调用OMSetRenderTargets所以我可以渲染到后台缓冲区。

以下是我实施的一步一步:

  1. 设置渲染目标
  2. 清除它们
  3. 清除深度缓冲区
  4. 将场景渲染为纹理
  5. 关闭Z缓冲区
  6. 渲染为四元
  7. 执行水平模糊
  8. 执行垂直模糊
  9. 将缓冲区设置为渲染目标
  10. 清除缓冲区
  11. 将最终输出渲染为四元
  12. 打开z缓冲区
  13. 提供后台缓冲区
  14. 这是四边形的着色器:

    Texture2D shaderTexture : register(t0);
    SamplerState SampleType : register(s0);
    struct PixelInputType
    {
        float4 position : SV_POSITION;
        float2 tex : TEXCOORD0;
    };
    
    float4 main(PixelInputType input) : SV_TARGET
    {
        return shaderTexture.Sample(SampleType, input.tex);
    }
    

    这是相关的c ++代码

    这是我设置渲染目标的方法

    void DeferredBuffers::SetRenderTargets(ID3D11DeviceContext* deviceContext, bool activeRTs[BUFFER_COUNT]){
    
        vector<ID3D11RenderTargetView*> rts = vector<ID3D11RenderTargetView*>();
        for (int i = 0; i < BUFFER_COUNT; ++i){
            if (activeRTs[i]){
                rts.push_back(m_renderTargetViewArray[i]);          
            }
        }
    
        deviceContext->OMSetRenderTargets(rts.size(), &rts[0], m_depthStencilView);
    
        // Set the viewport.
        deviceContext->RSSetViewports(1, &m_viewport);
    }
    

    我使用乒乓方法和渲染目标来模糊。 我将场景渲染到MainTarget并将深度信息渲染到depthMap。第一遍对第三个目标(horizo​​ntalBlurred)执行水平模糊,然后我使用那个作为垂直模糊的输入,渲染回mainTarget和finalTarget。它是一个循环,因为在垂直传递中我应该将PS输出与finalTarget上的内容混合。我把那些代码(以及其他一些东西)留下了,因为它不相关。 m_Fullscreen是四边形。

    bool activeRenderTargets[4] = { true, true, false, false };
    
    // Set the render buffers to be the render target.
    m_ShaderManager->getDeferredBuffers()->SetRenderTargets(m_D3D->GetDeviceContext(), activeRenderTargets);
    // Clear the render buffers.
    m_ShaderManager->getDeferredBuffers()->ClearRenderTargets(m_D3D->GetDeviceContext(), 0.25f, 0.0f, 0.0f, 1.0f);
    m_ShaderManager->getDeferredBuffers()->ClearDepthStencil(m_D3D->GetDeviceContext());
    
    
    // Render the scene to the render buffers.
    RenderSceneToTexture();
    
    // Get the matrices.
    m_D3D->GetWorldMatrix(worldMatrix);
    m_Camera->GetBaseViewMatrix(baseViewMatrix);
    m_D3D->GetOrthoMatrix(projectionMatrix);
    
    // Turn off the Z buffer to begin all 2D rendering.
    m_D3D->TurnZBufferOff();
    
    // Put the full screen ortho window vertex and index buffers on the graphics pipeline to prepare them for drawing.
    m_FullScreenWindow->Render(m_D3D->GetDeviceContext()); 
    
    ID3D11ShaderResourceView* mainTarget = m_ShaderManager->getDeferredBuffers()->GetShaderResourceView(0);
    ID3D11ShaderResourceView* horizontalBlurred = m_ShaderManager->getDeferredBuffers()->GetShaderResourceView(2);
    ID3D11ShaderResourceView* depthMap = m_ShaderManager->getDeferredBuffers()->GetShaderResourceView(1);
    ID3D11ShaderResourceView* finalTarget = m_ShaderManager->getDeferredBuffers()->GetShaderResourceView(3);
    activeRenderTargets[1] = false; //depth map is never a render target again
    
    for (int i = 0; i < numBlurs; ++i){
    
        activeRenderTargets[0] = false; //main target is resource in this pass
        activeRenderTargets[2] = true; //horizontal blurred target
        activeRenderTargets[3] = false; //unbind final target
        m_ShaderManager->getDeferredBuffers()->SetRenderTargets(m_D3D->GetDeviceContext(), activeRenderTargets);
        m_ShaderManager->RenderScreenSpaceSSS_HorizontalBlur(m_D3D->GetDeviceContext(), m_FullScreenWindow->GetIndexCount(), worldMatrix, baseViewMatrix, projectionMatrix, mainTarget, depthMap);
    
        activeRenderTargets[0] = true; //rendering to main target
        activeRenderTargets[2] = false; //horizontal blurred is resource
        activeRenderTargets[3] = true; //rendering to final target
        m_ShaderManager->getDeferredBuffers()->SetRenderTargets(m_D3D->GetDeviceContext(), activeRenderTargets);
        m_ShaderManager->RenderScreenSpaceSSS_VerticalBlur(m_D3D->GetDeviceContext(), m_FullScreenWindow->GetIndexCount(), worldMatrix, baseViewMatrix, projectionMatrix, horizontalBlurred, depthMap);
    
    }
    
    m_D3D->SetBackBufferRenderTarget();
    m_D3D->BeginScene(0.0f, 0.0f, 0.5f, 1.0f);
    // Reset the viewport back to the original.
    m_D3D->ResetViewport();
    
    
    m_ShaderManager->RenderTextureShader(m_D3D->GetDeviceContext(), m_FullScreenWindow->GetIndexCount(), worldMatrix, baseViewMatrix, projectionMatrix, depthMap);
    
    m_D3D->TurnZBufferOn();
    m_D3D->EndScene();
    

    最后,我的图形日志中有3 screenshots。 他们将场景渲染到mainTarget上,verticalPass将horizo​​ntalBlurred资源作为输入,最后渲染到backBuffer,这就是失败的原因。您可以看到绑定到着色器的资源以及输出如何只是黑屏。我的目的是将背景设置为红色,以确定它是否采用错误的坐标进行采样,但不是。

    那么,有没有人经历过这样的事情?可能是这个错误的原因是什么?

    提前感谢您的帮助!

    编辑:Render_SOMETHING_SOMETHING_shader方法处理绑定所有资源,设置着色器,绘制调用等等。如果有必要,我可以在这里发布,但我不认为它是&#39;相关的。

0 个答案:

没有答案