Хорошо, во-первых, я действительно новичок в DirectX11, и это на самом деле мой первый проект, использующий его. Я также относительно новичок в компьютерной графике в целом, поэтому у меня могут быть некоторые неправильные концепции, хотя, в данном конкретном случае, я так не думаю. Мой код основан на RasterTek учебники.
В попытке реализовать шейдерный шейдер, мне нужно визуализировать сцену в 2D-текстуру, а затем выполнить гауссово размытие полученного изображения.
Эта часть, кажется, работает нормально, так как при использовании графического отладчика Visual Studio выходные данные, как я ожидаю.
Однако, выполнив всю постобработку, я рендерил квад в буфер, используя простой шейдер, который использует окончательный результат размытия в качестве ресурса. Это всегда дает мне черный экран. Когда я отлаживаю свой пиксельный шейдер с помощью графического отладчика VS, кажется, что метод Sample (texture, uv) всегда возвращает (0,0,0,1) при попытке сэмплирования этой текстуры.
Пиксельный шейдер работает хорошо, если я использую другую текстуру, например карту нормалей или что-то еще, в качестве ресурса, но не при использовании какой-либо цели рендеринга из предыдущих проходов.
Поведение особенно странное, потому что фактический шейдер размытия прекрасно работает при использовании любой цели рендеринга в качестве ресурса.
Я знаю, что не могу использовать 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, а информацию о глубине — в глубину. На первом проходе выполняется горизонтальное размытие для третьей цели (горизонтальная размытие), а затем я использую эту в качестве входных данных для вертикального размытия, которое отрисовывается до основной цели и конечной цели. Это цикл, потому что на вертикальном проходе я должен смешивать вывод 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 скриншоты из моего графического журнала.
Они показывают рендеринг сцены в mainTarget, verticalPass, который принимает в качестве входных данных горизонтальный ресурс Blur и, наконец, рендеринг в backBuffer, что является причиной сбоя. Вы можете видеть ресурс, связанный с шейдером, и то, как вывод — просто черный экран. Я специально установил красный фон, чтобы выяснить, нет ли у него выборок с неправильными координатами, но нет.
Итак, кто-нибудь испытывал что-то подобное? Что может быть причиной этой ошибки?
Заранее благодарю за любую помощь!
РЕДАКТИРОВАТЬ: Методы Render_SOMETHING_SOMETHING_shader обрабатывают связывание всех ресурсов, установку шейдеров, отрисовку вызовов и т. Д. При необходимости я могу опубликовать их здесь, но я не думаю, что это актуально.
Задача ещё не решена.