I have a render target RenderTargetScene that holds my scene texture with the scene's depth buffer
rtScene = new RenderTarget2D(
graphicsDevice,
graphicsDevice.PresentationParameters.BackBufferWidth,
graphicsDevice.PresentationParameters.BackBufferHeight,
false,
SurfaceFormat.Rgba64,
DepthFormat.Depth24Stencil8, // Requires a depth format for objects
// to be drawn correctly (e.g. wireframe model surrounding model)
0,
RenderTargetUsage.PreserveContents
);
If I attempt to copy the render target contents to another render target using the following code
game.GraphicsDevice.SetRenderTargets(sceneCopy);
game.GraphicsDevice.Clear(ClearOptions.Target, Color.Transparent, 0f, 0);
//game.GraphicsDevice.Clear(Color.Transparent);
game.SpriteBatch.Begin(
SpriteSortMode.Immediate,
BlendState.Opaque,
SamplerState.PointClamp,
DepthStencilState.Default,
RasterizerState.CullCounterClockwise
);
game.SpriteBatch.Draw(game.RenderTargetScene,
new Rectangle(0, 0, sceneCopy.Width, sceneCopy.Height), Color.White);
game.SpriteBatch.End();
Then the texture is copied across but the depth buffer appears to be lost.
This is apparent when using DepthStencilState.DepthRead as there is no depth for the objects drawn with that render state to read.
How can I make sure the depth buffer is copied across too?
EDIT:
I have a depth texture created via my deferred rendering system so I thought I would use that.
I'm now drawing a full screen quadrangle using a depth writing shader
public void RestoreDepthBuffer(Texture2D depthTexture)
{
// Set the render states
game.GraphicsDevice.BlendState = BlendState.Opaque;
game.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
game.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
game.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
Effect effect = restoreDepthBuffer;
effect.CurrentTechnique = effect.Techniques["Default"];
effect.Parameters["DepthTexture"].SetValue(depthTexture);
effect.CurrentTechnique.Passes[0].Apply();
game.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(
PrimitiveType.TriangleStrip,
NearPlaneVerticesVPT,
0,
4,
Indices,
0,
2
);
}
The important parts of the shader look like
struct PixelShaderOutput
{
float4 Colour : COLOR0;
float Depth : DEPTH;
};
PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
{
PixelShaderOutput output;
output.Colour = float4(0, 0, 0, 0);
output.Depth = 1.0f - tex2D(DepthSampler, input.TextureCoordinates).r;
return output;
}
This is still not working though.
EDIT2: I've got it to work but I have to set the depth and draw all the objects when the RenderTarget is first set and not unset it again.
Should I post an answer based on my working method?
RenderTarget2Dto anotherRenderTarget2D, without losing the associated Z-Buffer? Is that it? – Laurent Couvidou Jul 28 '12 at 0:20