好的,首先,我是DirectX11的新手,这实际上是我使用它的第一个项目。我对计算机图形学一般也比较新,所以我可能有一些概念错了,但对于这种特殊情况,我不这么认为。我的代码基于RasterTek tutorials。
在尝试实现着色器着色器时,我需要将场景渲染为2D纹理,然后在生成的图像上执行高斯模糊。 这部分似乎工作正常,因为使用Visual Studio图形调试器时输出似乎是我所期望的。
然而,在完成所有后期处理之后,我使用一个简单的着色器渲染一个四边形到后备缓冲区,该着色器使用模糊的最终输出作为资源。这总是给我一个黑屏。当我使用VS图形调试器调试我的像素着色器时,似乎Sample(texture,uv)方法在尝试对该纹理进行采样时始终返回(0,0,0,1)。
如果我使用不同的纹理(如某些普通地图或其他任何东西)作为资源,则像素着色器工作正常,而不是在使用先前传递的任何渲染时。 行为特别奇怪,因为当使用任何rendertargets作为资源时,实际模糊着色器工作正常。
我知道我不能使用rendertarget作为输入和输出但我认为我已经覆盖了,因为我调用OMSetRenderTargets所以我可以渲染到后台缓冲区。
以下是我实施的一步一步:
这是四边形的着色器:
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。第一遍对第三个目标(horizontalBlurred)执行水平模糊,然后我使用那个作为垂直模糊的输入,渲染回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将horizontalBlurred资源作为输入,最后渲染到backBuffer,这就是失败的原因。您可以看到绑定到着色器的资源以及输出如何只是黑屏。我的目的是将背景设置为红色,以确定它是否采用错误的坐标进行采样,但不是。
那么,有没有人经历过这样的事情?可能是这个错误的原因是什么?
提前感谢您的帮助!
编辑:Render_SOMETHING_SOMETHING_shader方法处理绑定所有资源,设置着色器,绘制调用等等。如果有必要,我可以在这里发布,但我不认为它是&#39;相关的。