c++ - HLSL - Sampling a render target texture always return black color -
okay, first of all, i'm new directx11 , first project using it. i'm relatively new computer graphics in general might have concepts wrong although, particular case, not think so. code based on rastertek tutorials.
in trying implement shader shader, need render scene 2d texture , perform gaussian blur on resulting image. part seems working fine when using visual studio graphics debugger output seems expect.
however, after having having done post processing, render quad backbuffer using simple shader uses final output of blur resource. gives me black screen. when debug pixel shader vs graphics debugger, seem sample(texture, uv) method returns (0,0,0,1) when trying sample texture.
the pixel shader works fine if use different texture, normal map or whatever, resource, not when using of rendertargets previous passes. behaviour particularly weird because actual blur shader works fine when using of rendertargets resource.
i know cannot use rendertarget both input , output think have covered since call omsetrendertargets can render backbuffer.
here's step step of implementation:
- set render targets
- clear them
- clear depth buffer
- render scene texture
- turn off z buffer
- render quad
- perform horizontal blur
- perform vertical blur
- set buffer render target
- clear buffer
- render final output quad
- turn z buffer on
- present buffer
here shader quad:
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); }
here's relevant c++ code
this how set render targets
void deferredbuffers::setrendertargets(id3d11devicecontext* devicecontext, bool activerts[buffer_count]){ vector<id3d11rendertargetview*> rts = vector<id3d11rendertargetview*>(); (int = 0; < buffer_count; ++i){ if (activerts[i]){ rts.push_back(m_rendertargetviewarray[i]); } } devicecontext->omsetrendertargets(rts.size(), &rts[0], m_depthstencilview); // set viewport. devicecontext->rssetviewports(1, &m_viewport); }
i use ping pong approach render targets blur. render scene maintarget , depth information depthmap. first pass performs horizontal blur onto third target (horizontalblurred) , use 1 input vertical blur renders maintarget , finaltarget. it's loop because on vertical pass i'm supposed blend ps output what's on finaltarget. left code (and other stuff) out it's not relevant. m_fullscreen quad.
bool activerendertargets[4] = { true, true, false, false }; // set render buffers render target. m_shadermanager->getdeferredbuffers()->setrendertargets(m_d3d->getdevicecontext(), activerendertargets); // clear 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 scene render buffers. renderscenetotexture(); // matrices. m_d3d->getworldmatrix(worldmatrix); m_camera->getbaseviewmatrix(baseviewmatrix); m_d3d->getorthomatrix(projectionmatrix); // turn off z buffer begin 2d rendering. m_d3d->turnzbufferoff(); // put full screen ortho window vertex , index buffers on graphics pipeline prepare them 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 never render target again (int = 0; < numblurs; ++i){ activerendertargets[0] = false; //main target resource in 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 main target activerendertargets[2] = false; //horizontal blurred resource activerendertargets[3] = true; //rendering 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 viewport original. m_d3d->resetviewport(); m_shadermanager->rendertextureshader(m_d3d->getdevicecontext(), m_fullscreenwindow->getindexcount(), worldmatrix, baseviewmatrix, projectionmatrix, depthmap); m_d3d->turnzbufferon(); m_d3d->endscene();
and, finally, here 3 screenshots graphics log. show rendering scene onto maintarget, verticalpass takes input horizontalblurred resource , finally, rendering onto backbuffer, what's failing. can see resource bound shader , how output black screen. purposedly set background red find out if sampling wrong coordinates, nope.
so, has ever experienced this? cause of bug?
thanks in advance help!
edit: render_something_something_shader methods handle binding resources, setting shaders, draw calls etc etc. if necessary can post them here, don't think it's relevant.
Comments
Post a Comment