I’m having trouble trying to draw a refractive surface (a simple water plane) on top of an existing big complex scene, without having to draw the whole scene twice. To that end, I’m using the following steps:
- Initialise both RenderTargets with PreserveContents, in the superstitious hope that that would help (it didn’t)…
primaryRenderTarget = new RenderTarget2D(GraphicsDevice,
pp.BackBufferWidth,
pp.BackBufferHeight,
false,
pp.BackBufferFormat,
pp.DepthStencilFormat,
pp.MultiSampleCount,
RenderTargetUsage.PreserveContents);
bloomRenderTarget = new RenderTarget2D(GraphicsDevice,
pp.BackBufferWidth,
pp.BackBufferHeight,
false,
pp.BackBufferFormat,
pp.DepthStencilFormat,
pp.MultiSampleCount,
RenderTargetUsage.PreserveContents);
- Draw the whole scene to a rendertarget
GraphicsDevice.SetRenderTarget(primaryRenderTarget);
// Draw big complex scene
- Start up a new RenderTarget (this one will later be used for the bloom lighting post-process) and clear only the colour target, theoretically leaving the depth buffer right where it is.
GraphicsDevice.SetRenderTarget(bloomRenderTarget);
GraphicsDevice.Clear(ClearOptions.Target, Color.Black, 1.0f, 0);
- Draw the previously rendered scene onto the new RenderTarget, being careful not to overwrite the depth buffer.
spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.Opaque,
null,
DepthStencilState.None);
spriteBatch.Draw(primaryRenderTarget,
new Rectangle(0, 0, screenWidth, screenHeight),
Color.White);
spriteBatch.End();
- And finally, draw my refractive surface on top, feeding the already-drawn scene image into the refraction shader.
waterEffect.Parameters["refractionTexture"].SetValue(refractionMap);
waterPlane.Draw(GraphicsDevice, cameraMatrices, gameTime);
Straightforward enough in concept, except for the bit where it doesn’t work. The water plane simply ignores the depth buffer and draws itself on top of everything else, and I can’t work out why, even after a fair bit of searching.
This is an OpenGL project, if that matters.
Can anybody help?