Bloom Effect On Windows Phone 7


In this post iam going to explain a dirty way to simulate the bloom effect under Windows Phone 7. Unfortunatelly, we dont have custom shaders in this plataform yet, so we need to use some combination of alpha blending to simulate the threshold filter and the Blur filter.

In a simple way, the classic boom post effect consists of:

  • A first pass that exctracts the parts of the image that are more “bright” (we get the pixels with rgb colors bigger than something like 0.7 and discard the others — this is the threshold filter)
  • The second pass apply a gaussian blur (or another blur algorithm) to the previous generated image
  • We make an additive blending between the original image and the previous generate image

For PC and Consoles, we normally use Custom shaders for all the passes, but in WP7 we cant. The alternative is to use Subtrative alpha blending for the threshold pass, draw the images with offset for the blur and use additive blending for the last pass.

The results i got are pretty cool (for a phone =P). Next i will show my implementation of this idea:

 Creating the Blend States

The following piece of code shows the blending states creation:

            ///Additive blending
            BlendState additiveBlend = new BlendState();
            additiveBlend.AlphaBlendFunction = BlendFunction.Add;
            additiveBlend.AlphaSourceBlend = Blend.One;
            additiveBlend.AlphaDestinationBlend = Blend.One;
            additiveBlend.ColorBlendFunction = BlendFunction.Add;
            additiveBlend.ColorSourceBlend = Blend.One;
            additiveBlend.ColorDestinationBlend = Blend.One;

            ///Subtractive blending
            BlendState subBlend = new BlendState();
            subBlend.AlphaBlendFunction = BlendFunction.Subtract;
            subBlend.AlphaSourceBlend = Blend.One;
            subBlend.AlphaDestinationBlend = Blend.One;
            subBlend.ColorBlendFunction = BlendFunction.Subtract;
            subBlend.ColorSourceBlend = Blend.One;
            subBlend.ColorDestinationBlend = Blend.One;

We also need two Render Targets to hold our intermediate images. (letst call SCENERT (used to hold the scene) and BLOOMRT (used to hold the bloom passes) )

Executing the Bloom Pass

The following code shows the complete Bloom Pass. (the Render class is our wrapper to the xna graphic device)

            ///set the scene render target on device
            render.PushRenderTarget(SCENERT);
            ////RENDER THE SCENE HERE !!!! EVERYTHING ..
            ///set the bloom render target on device
            render.PopRenderTarget();
            render.PushRenderTarget(BLOOMRT);
            render.Clear(Color.FromNonPremultiplied(bloomThreshold, bloomThreshold, bloomThreshold, 255));
            ///Render the Scene Texture using the SubBlend (the spritebatch can do it easily =P, i used the render object cause this is part of our engine)
            render.RenderTextureComplete(SCENERT, Color.White, GraphicInfo.FullScreenRectangle, Matrix.Identity, null, true, SpriteSortMode.Deferred, SamplerState.LinearClamp, subBlend);
            ///set the frame buffer render target (now we are going to render to the MONITOR)
            render.PushRenderTarget(null);

            render.Clear(Color.Black);
            ///Render the original texture (without blending)
            render.RenderTextureComplete(SCENERT, Color.White, GraphicInfo.FullScreenRectangle, Matrix.Identity);

            ///FAKE BLUR KKKKK (mais KKKK)
            ///Render the BLOOM render target four times on the top of the original images with offset and Additive blending
            ///We also use a brightNess variable to control how brigh the final image will be. (use something like 60)
            render.RenderTextureComplete(BLOOMRT, Color.FromNonPremultiplied(255, 255, 255, brightNess), GraphicInfo.FullScreenRectangle, Matrix.CreateTranslation(2, 2, 0), null, true, SpriteSortMode.Deferred, SamplerState.AnisotropicClamp, additiveBlend);
            render.RenderTextureComplete(BLOOMRT, Color.FromNonPremultiplied(255, 255, 255, brightNess), GraphicInfo.FullScreenRectangle, Matrix.CreateTranslation(-2, -2, 0), null, true, SpriteSortMode.Deferred, SamplerState.AnisotropicClamp, additiveBlend);
            render.RenderTextureComplete(BLOOMRT, Color.FromNonPremultiplied(255, 255, 255, brightNess), GraphicInfo.FullScreenRectangle, Matrix.CreateTranslation(2, -2, 0), null, true, SpriteSortMode.Deferred, SamplerState.AnisotropicClamp, additiveBlend);
            render.RenderTextureComplete(BLOOMRT, Color.FromNonPremultiplied(255, 255, 255, brightNess), GraphicInfo.FullScreenRectangle, Matrix.CreateTranslation(-2, 2, 0), null, true, SpriteSortMode.Deferred, SamplerState.AnisotropicClamp, additiveBlend);

The helper Code i Used:

public void RenderTextureComplete(Texture2D texture, Color color, Rectangle destination, Matrix transform, Rectangle? source = null, SpriteSortMode SpriteSortMode = SpriteSortMode.Deferred, SamplerState samplerState = null, BlendState blenderState = null, RasterizerState rasterizerState = null, DepthStencilState depthState = null, Effect effect = null)
        {
            spriteBatch.Begin(SpriteSortMode, blenderState, samplerState, depthState, rasterizerState, effect, transform);
            spriteBatch.Draw(texture, destination,source, color);
            spriteBatch.End();
        }

///actually is a bit more than this ... but this is enough for this effect
public void PushRenderTarget(params RenderTarget2D[] renderTarget)
        {
            if (renderTarget == null)
            {
                device.SetRenderTargets(null);
            }
            else
            {
                RenderTargetBinding[] bindings = new RenderTargetBinding[renderTarget.Count()];
                for (int i = 0; i < renderTarget.Count(); i++)
                {
                    bindings[i] = renderTarget[i];
                }

                device.SetRenderTargets(bindings);
            }
        }

public void Clear(Color color, ClearOptions options = ClearOptions.Target | ClearOptions.DepthBuffer, float depth = 1, int stencil = 0)
        {
            device.Clear(options, color, depth, stencil);
        }

You can use this idea to simulate others post effects like Blur.
Enjoy =P

  1. #1 by payday loans on 26 de agosto de 2016 - 4:20 am

    You have made some really good points there. I looked on the net for additional information about the issue and found most people will go along with your views on this website.

  2. #2 by crowdfunding platform on 26 de agosto de 2016 - 7:22 am

    Thanks-a-mundo for the article.Much thanks again. Great.

  3. #3 by films en streaming en vf on 26 de agosto de 2016 - 8:02 am

    Thanks again for the article post.Really thank you!

  4. #4 by fast loans on 26 de agosto de 2016 - 9:19 am

    Wonderful post, you have pointed out some amazing details , I besides believe this s a really excellent web site.

  5. #5 by magic show singapore on 26 de agosto de 2016 - 9:52 am

    wow, awesome blog post.Really looking forward to read more. Much obliged.

  6. #6 by party entertainer singapore on 26 de agosto de 2016 - 10:13 am

    A round of applause for your post.Much thanks again. Really Cool.

  7. #7 by nettside on 26 de agosto de 2016 - 10:35 am

    Thank you ever so for you blog.Really thank you!

  8. #8 by joyeria plata on 26 de agosto de 2016 - 10:57 am

    This is one awesome article.Much thanks again. Great.

  9. #9 by for more information on 26 de agosto de 2016 - 11:19 am

    Thanks-a-mundo for the article.Really thank you! Really Great.

  10. #10 by payday loans on 26 de agosto de 2016 - 12:43 pm

    Really informative article.Thanks Again. Fantastic.

  11. #11 by hidden camera on 26 de agosto de 2016 - 1:30 pm

    wow, awesome post.Really looking forward to read more. Much obliged.

  12. #12 by locksmith san jose ca on 26 de agosto de 2016 - 1:53 pm

    Thank you ever so for you blog article.Much thanks again. Will read on…

  13. #13 by smoke hidden camera smoke detector on 26 de agosto de 2016 - 2:16 pm

    Thank you ever so for you blog post.Really looking forward to read more. Awesome.

  14. #14 by Yong Dymek on 26 de agosto de 2016 - 3:14 pm

    Youre so proper. Im there with you. Your blog is surely worth a read if anyone comes throughout it. Im lucky I did because now Ive obtained a entire new view of this. I didnt realise that this concern was so crucial and so universal. You completely put it in perspective for me.

  15. #15 by ideen zum selber machen on 26 de agosto de 2016 - 4:02 pm

    Thanks so much for the post.Really thank you! Really Cool.

  16. #16 by Carly Hahs on 26 de agosto de 2016 - 9:30 pm

    Wow! Your website is astounding 😀 I will tell about it to my wife and anybody that could be enticed by this matter. Great work girls :)

  17. #17 by payday loans on 27 de agosto de 2016 - 1:06 am

    I think this is a real great article post.Really looking forward to read more. Much obliged.

  18. #18 by betterscooter.com on 27 de agosto de 2016 - 1:41 am

    Relatively perfect.the exact betterscooter.com http://adf.ly/6249830/banner/www.scamadviser.com/is-betterscooter.com-a-fake-site.html were beneficial

  19. #19 by fast loans on 27 de agosto de 2016 - 2:29 am

    I really enjoy the blog.Much thanks again.

  20. #20 by creosote sweeping log menards on 27 de agosto de 2016 - 3:18 am

    As soon as I detected this site I went on reddit to share some of the love with them.

1 27 28 29
(não será publicado)