I want to be able to
- Draw something to the screen (orange line in this example).
- Apply a two pass shader (Gaussian X and Y) that draws on top of the orange line (white text).
- Draw on top of that (red text and blue line).
I have two problems
- Only one shader pass is applying no matter what I do (I can get the X gaussian or Y gaussian to apply but not both).
- The result of the shader is somehow drawing under the orange line.
I’m aware that the shader code and/or blend state may be wrong but I don’t care, I want to get two shader passes working and drawing over the orange line.
I have uploaded a short sample project that demonstrates my issue:
Download at: www.hernblog.com/MonogameGaussianBlur.zip
Here’s the main part of the code:
void DrawBlurredString(string text)
{
SpriteBatch.End();
// Pass 1 - render the text and make space for the blur
float textOffset = 5f;
Vector2 textSize = Font.MeasureString(text);
Vector2 textureSize = textSize + new Vector2(2f * textOffset, 2f * textOffset);
RenderTarget2D renderedText = new RenderTarget2D(SpriteBatch.GraphicsDevice,
(int)textureSize.X, (int)textureSize.Y, false,
SurfaceFormat.Color, DepthFormat.None, 1, RenderTargetUsage.DiscardContents);
SpriteBatch.GraphicsDevice.SetRenderTarget(renderedText);
SpriteBatch.GraphicsDevice.Clear(Color.Transparent);
SpriteBatch.Begin();
SpriteBatch.DrawString(Font, text, new Vector2(textOffset, textOffset), Color.White);
SpriteBatch.End();
// Pass 2 - Do the GaussianY shader
RenderTarget2D partiallyBlurredText = new RenderTarget2D(SpriteBatch.GraphicsDevice,
(int)textureSize.X, (int)textureSize.Y, false,
SurfaceFormat.Color, DepthFormat.None, 1, RenderTargetUsage.DiscardContents);
SpriteBatch.GraphicsDevice.SetRenderTarget(partiallyBlurredText);
SpriteBatch.GraphicsDevice.Clear(Color.Transparent);
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
GaussianY.CurrentTechnique.Passes[0].Apply(); // effect not showing up in result
SpriteBatch.Draw(renderedText, new Vector2(0, 0), null, Color.White);
SpriteBatch.End();
SpriteBatch.GraphicsDevice.SetRenderTarget(null);
// Pass 3 - Do the GaussianX shader (back onto the main render target)
SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
GaussianX.CurrentTechnique.Passes[0].Apply(); // effect is showing up in the result
SpriteBatch.Draw(partiallyBlurredText, Vector2.Zero, null, Color.White);
SpriteBatch.End();
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, null, null, RasterizerState, null);
SpriteBatch.DrawString(Font, text, new Vector2(textOffset, textOffset), Color.Red);
}
Edited for clarity.