Need help with render to texture

Started by
2 comments, last by magicstix 11 years, 5 months ago
Hi all, I was wondering if anyone could help me with a minor render to texture problem:

I'm getting:
D3D11: WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD ]
D3D11: WARNING: ID3D11DeviceContext::OMSetRenderTargets[AndUnorderedAccessViews]: Forcing PS shader resource slot 0 to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD ]

When trying to render with the following loop:

void render()
{
static float theta = 0;
float thetaRads = theta * 3.14159/180.0;
float ClearColor[4] = { 0.0f, 0.0, 0, 0.9f }; // red,green,blue,alpha
float r = 0.1 * cos(2 * 3.14159 * 1 * thetaRads);
//Render the texture
g_pImmediateContext->OMSetRenderTargets(1, &g_baseRTV,NULL);
g_pImmediateContext->ClearRenderTargetView( g_baseRTV, ClearColor );
ConstantBufferType cb;
XMStoreFloat4x4(&cb.worldView, XMMatrixIdentity());
cb.worldView._11 = cos(thetaRads);
cb.worldView._12 = -sin(thetaRads);
cb.worldView._21 = sin(thetaRads);
cb.worldView._22 = cos(thetaRads);
//cb.worldView._14 = r*cos(thetaRads);
//cb.worldView._24 = r*sin(thetaRads);
g_pImmediateContext->UpdateSubresource(g_constantBuffer, 0, NULL, &cb, 0,0);
g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_constantBuffer);
g_pImmediateContext->PSSetConstantBuffers(0, 1, &g_constantBuffer);
g_pImmediateContext->VSSetShader(g_baseVShader, NULL, 0);
g_pImmediateContext->PSSetShader(g_basePShader, NULL, 0);
g_pImmediateContext->IASetInputLayout(g_layout);
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
UINT stride = sizeof(BasicVertex);
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers(0,1,&g_pLineVtxBuffer,&stride,&offset);
g_pImmediateContext->Draw(6,0);
//Render the screen.
g_pImmediateContext->OMSetRenderTargets(1,&g_pRenderTargetView, NULL);
g_pImmediateContext->VSSetShader(g_texVShader, NULL, 0);
g_pImmediateContext->PSSetShader(g_texPShader, NULL, 0);
g_pImmediateContext->IASetVertexBuffers(0,1,&g_pScreenVtxBuffer,&stride,&offset);
g_pImmediateContext->PSSetShaderResources(0,1, &g_baseSRV);
g_pImmediateContext->PSSetSamplers(0,1,&g_pSamplerLinear);
g_pImmediateContext->Draw(6,0);
g_pSwapChain->Present( 0, 0 );
theta += 0.05;
}


g_pRenderTargetView is the main screen's render target view, and g_baseRTV is the render target view I'm using for render to texture.
Any pointers on what I'm doing wrong?
It also doesn't seem to be alpha blending properly (I'm expecting a sort of blurred trail like an accumulation buffer effect, but it doesn't seem to be working), and I'm wondering if it has something to do with the errors I'm seeing D3D throw...
Advertisement
The error means exactly what it says: you're trying to bind a render target, but the texture for that render target is still bound as a shader resource view for the pixel shader. This is happening because at the end of your frame you bind the SRV for your render target texture to the pixel shader, then at the beginning of the next frame you bind RTV for that texture. You need to set the pixel shader SRV slot to NULL before you bind the RTV, and then you won't get the error.

If you want alpha blending, then you need to bind an appropriate blend state that has blending enabled. Are you attempting to blend into your render target texture, as if it were an accumulation buffer? If so, then you also won't want to clear the target each frame (otherwise it will lose everything you've currently accumulated).
Thanks, I didn't realize the shader view had to be unbounded before the texture could be bound as the render target again.

As for the blending, yes, I'm using an alpha blend state. The problem seems to come from blending a quad into the render texture, then blending the render texture into the screen. The quad itself seems to show alpha, but when its alpha gets mixed with the screen quad, either the screen quad seems to become transparent instead of additvely blending into the screen quad, or the trail only shows up within the smaller quad's area. I'm not sure my explanation makes sense, so here are some pics:

Where I don't clear the back buffer, I get the expected trail, but only within the quad:
noclearbackbuffer.png


Where I *do* clear the back buffer, you can see the transparency problem better:
clearbackbuffer.png

Alpha seems to at least be partially working, as alpha is how i implement the "fuzziness" of the dot (exponential falloff from the center of the quad on the alpha channel), but the quad makes a "hole" in the screen quad, allowing the background to bleed through. I always clear the render target view texture to 0,0,0, 0.9, yet it has no alpha except where I render the smaller quad into it.

Here's how I'm setting up my blending:

D3D11_BLEND_DESC blendDesc;
ZeroMemory( &blendDesc, sizeof(blendDesc) );
D3D11_RENDER_TARGET_BLEND_DESC rtbd;
ZeroMemory( &rtbd, sizeof(rtbd) );
rtbd.BlendEnable = true;
rtbd.SrcBlend = D3D11_BLEND_SRC_ALPHA;
rtbd.DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
rtbd.BlendOp = D3D11_BLEND_OP_ADD;
rtbd.SrcBlendAlpha = D3D11_BLEND_ONE;
rtbd.DestBlendAlpha = D3D11_BLEND_ZERO;
rtbd.BlendOpAlpha = D3D11_BLEND_OP_ADD;
rtbd.RenderTargetWriteMask = D3D10_COLOR_WRITE_ENABLE_ALL;
blendDesc.AlphaToCoverageEnable = false;
blendDesc.RenderTarget[0] = rtbd;
g_pd3dDevice->CreateBlendState(&blendDesc, &g_pBlendState);
g_pImmediateContext->OMSetBlendState(g_pBlendState, 0, 0xffffffff);
Oops, I noticed my DEST_BLEND_ALPHA was set to zero, so I set that to 1, and now the transparency problem is fixed and I'm getting some trails, but they don't seem to properly dissipate over time:
destblendfixed.png

I'm going more for a CRT persistence fall-off effect, like an analog oscilloscope where the trail will eventually fade to black and be brightest the closer you get to the dot.

This topic is closed to new replies.

Advertisement