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 Education Quotes on 10 de dezembro de 2016 - 12:35 am

    I just couldn’t leave your site prior to suggesting that I actually loved the usual info a person provide in your visitors? Is gonna be back often in order to check up on new posts

  2. #2 by hauskredit holland on 10 de dezembro de 2016 - 12:57 am

    Your answer lifts the intelligence of the debate.

  3. #3 by ルイ ヴィトン 財布 タイガ 二つ折り on 10 de dezembro de 2016 - 4:18 am

    新作最高品質コピー時計、スーパーコピー時計
    最高品質(N級品)時計,バッグ,財布新作最新入荷,スーパーコピー時計,
    スーパーコピー財布,スーパーコピーバッグ,ブランド時計コピー,スーパー コピー,
    ブランドスーパーコピー,ブランド偽物,スーパーコピー時計,ルイヴィトンバッグ,
    エルメススーパーコピー,シャネルスーパーコピー,ロレックススーパーコピー,
    カルティエスーパーコピー,オメガスーパーコピー,ウブロスーパーコピーなどの世界にプランド商品です。
    当店のスーパーコピーブランド(N級品)は本物と同じ素材を採用しています。
    スーパーコピー,本物を真似た偽物.模造!
    ホームページ上でのご注文は24時間受け付けております
    ルイ ヴィトン 財布 タイガ 二つ折り http://www.msnbrand.com/brand-copy-IP-31.html

  4. #4 by http://besteonlinekreditjetzo.pw/hauskredit-ohne-eigenkapital-online.html on 10 de dezembro de 2016 - 4:40 am

    GRACIAS SOFI PORQUE AL SER LA CANDIDATA DE LAS MUJERES BUSCAS QUE HAYA INCLUSIÓN Y NO EXCLUSIÓN,Y TIENES EN CUENTA LOS INTERESES DE LAS DIFERENTES MUJERES, SIN OLVIDAR QUE HAY MUJERES JEFES DE HOGAR, JOVENES, VIUDAS, NIÑAS,MADRES, HIJAS, HERMANAS O ESPOSAS Y QUE TODAS QUIEREN LO MEJOR PARA LOS SUYOSGRACIAS POR PROCURAR REPRESENTAR A LAS MUJERES.

  5. #5 by dispokredit zins jugendsparkonto on 10 de dezembro de 2016 - 4:45 am

    Your post has moved the debate forward. Thanks for sharing!

  6. #6 by http://www.bestekreditevergleichje.info/ on 10 de dezembro de 2016 - 5:51 am

    I think another good place to hide it would be in the shack at the right of the mine when it is filled up with crops. The delivery truck would pick it up and carry it far away from Club Penguin xD

  7. #7 by http://bestekreditjemals.info/deutsch-kredit-selbstaendig-serioes-ly.html on 10 de dezembro de 2016 - 6:43 am

    ¿sabéis que el que sale en la foto que ha puesto la lady del padre Damián, realmente no es “padre”?Si no es padre, será porque no quiere que a la vista está, cualidades no le faltan para ser lo que quiera en la vida.Esto me va a costar un collejón de la madre, uy ya me duele

  8. #8 by http://kreditvergleichejetzo.info/baukredit-berechnen-kostenlos.html on 10 de dezembro de 2016 - 6:46 am

    Hát szerintem egy ilyen rendszernél nagyon észen kell lenni, hogy mit aggatunk szegény katonára, minden dekának hatványozottan van súlya. A képen látható rendszer sem lesz ilyen formában hatékony. Például a képen látható kamerának a vezetéke szerintem nagyon zavarhatja az embert. Vagy a repeszállónak az a lelógó része a combhoz futásnál nem ép szerencsés.Tetszik / Egyetértek: 0 Az értékeléshez be kell

  9. #9 by kredit arbeitslos hartz iv überwiesen on 10 de dezembro de 2016 - 8:44 am

    Holy shiznit, this is so cool thank you.

1 80 81 82
(não será publicado)