Sign in to follow this  

HLSL render to texture

This topic is 4659 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, Is there a way to render-to-texture using HLSL? Im trying to create a filter that already spans two passes. However I have to call the filter n more times each having the previous stages output as the input texture. To complicate things, the texture output at each stage is sampled randomly, to be fed to some static variables. Im working on a video application and obviuosly I am looking to avoid any readback till the very last stage's output. Could some body suggest a way to write the techniques/passes such and any additionaly code, or direct me to any place/sample code that deals with this problem. Thanks! -/\=

Share this post


Link to post
Share on other sites
You can't set a render target from your effect file, if that's what you're asking. You should be able to have the outpout of one stage be the input texture for the next stage without a problem.

Just make sure that you don't have the same texture set as both a render target and a source texture all at the same time because this causes all kinds of headaches for the driver. If you try to do this, D3D will give you warnings about it.

Other than that, it's up to your main application to handle all the render target passes stuff. Your rendering would look something like this:

pEffect->SetTechnique(...)
for( int renderPasses = 0; renderPasses < TotalPasses; renderPasses++ )
{
pDevice->SetRenderTarget()
if( pDevice->Begin() )
{
pEffect->Begin(&numEffectPasses, D3DXFX_DONOTSAVESTATE)
for( int effectPass = 0; effectPass < numEffectPasses; effectPass++ )
{
pEffect->BeginPass( effectPass );
pEffect->SetTexture(...) // Not the same texture set as your render target.
pDevice->DrawIndexedPrimitive(...)
}
}
}

neneboricua

Share this post


Link to post
Share on other sites
Hey thanks for the reply. However I am still confused. Before i start the render code, i setup an offscreen rendering surface and do a SetRenderTarget() for it. Then after effect->Begin() I loop through the available passes in a given technique.
Now say for pass 1, i use a source texture, say srcTex and do a effect->SetTexture(gSrcTex,srcTex). pass p0 has a pixel shader which has an output as a float4 color.
*NOW* what should I do to pass this color/texture or whatever to pass p1, which again has a pixel shader that processes the output frame from pass p0.

questions that arise:
1. what is the way to save pass p0's color information?
2. is it possible to have a global declared as:
static float4 gTempVector;
and have pixel shaders called in different passes read/update the value from gTempVector faithfully?
3. assuming i don't disturb the input scene coordinates, (or in other words, the scene coordinates at the second pass can be presumed to be the texcoords of the first stage), if i were to make a texcoord query to the original texture sampler gSrcTex, should that work?

desperately looking for some help/explanations, thanks!
-/\=

Share this post


Link to post
Share on other sites
ATI has a sample that does all of these things. I think its called Video Shader. Go to www.ati.com/developer.

In any case, I'll try to answer some of these questions. My answers will probably make more sense once you've looked through the ATI sample.
Quote:
floydude
Before i start the render code, i setup an offscreen rendering surface and do a SetRenderTarget() for it. Then after effect->Begin() I loop through the available passes in a given technique.
Now say for pass 1, i use a source texture, say srcTex and do a effect->SetTexture(gSrcTex,srcTex). pass p0 has a pixel shader which has an output as a float4 color.
*NOW* what should I do to pass this color/texture or whatever to pass p1, which again has a pixel shader that processes the output frame from pass p0.

To do this, you'll need to have at least two textures that you will be using as render targets. It works a lot like the backbuffer/frontbuffer combo. As you enter your render loop, you'll do the following. Note that in this pseudocode, pRenderTextures is an array of two textures you've created as render targets. Also, pRenderSurfaces is an array with the two surfaces you get from each of these textures to set as render targets.

// Start rendering
pEffect->SetTechnique(...);
pEffect->Begin( &numEffectPasses, D3DXFX_DONOTSAVESTATE );
for( int pass = 0; pass < numEffectPasses; pass ++ )
{
pDevice->SetRenderTarget( 0, pRenderSurfaces[pass %2] );
pEffect->SetTexture( hTextureHandle, pRenderTextures[pass%1] );
pEffect->Begin( &numEffectPasses, D3DXFX_DONOTSAVESTATE );
pEffect->BeginPass( effectPass );
pDevice->DrawIndexedPrimitive(...)
pEffect->EndPass();
}
pEffect->End();

So in the first pass, you'll render into surface 0 (which is part of texture 0) and use texture 1 for input. Since this is the first time through, hopefully you've cleared texture 0 to black some where before this. In the second pass, the variable "pass" is now 1. So 1 mod 2 is 1. So you'll use surface 1 as your render target and then have texture 0 as your source. Remember that in this second pass, texture 0 has the results from your first pass since it was used as the render target in that first pass.

You'll probably have to add some code in here to keep some more state info or something but hopefully its a little more clear now. Take a look at that ATI sample. It does pretty much exactly what you're looking for and a whole lot more.

neneboricua

Share this post


Link to post
Share on other sites

This topic is 4659 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this