Jump to content
  • Advertisement
Sign in to follow this  
SteveDeFacto

My bloom effect looks good but is very inefficient.

This topic is 2533 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Alright I've gotten the desired result:
[attachment=4862:Bloom2.jpg]


However the way in which I got this result is not very desirable:

Step #1: Render my scene to a texture.
Step #2: Render a fullscreen quad to another texture to make a copy of the first texture.
Step #3: Extract the pixels which are above my threshold with a fragment shader and render to first texture.
Step #4: Blur horizontally with another fragment shader and render to first texture.
Step #5: Blur Vertically with another fragment shader and render to first texture.
Step #6: Add first texture and the second texture with yet another fragment shader and render it to the screen...

As you can see that's a lot of steps and a lot of code as well. Is there anyway I can do this simpler?

Share this post


Link to post
Share on other sites
Advertisement
Often step 2 will copy to a smaller texture than the screen resolution. The lower resolution isn't noticed, as you're blurring it anyway, and it makes the blur steps run much, much faster (and also increases your blur radius).

Share this post


Link to post
Share on other sites
An other trick to speed it up is to utilize the filtering capability of the GPU, that's instead of taking samples at .. -3,-2,-1,0,1,2,3.. , take them between two pixels:
...-3.5,-1.5,0,1.5,3.5,5.5,..
With linear filtering enabled the result will be
pixel(1.5) = (pixel(1)+pixel(2)) * 0.5
pixel(3.5) = (pixel(3)+pixel(4)) * 0.5
This way you can get a higher radius for less samples,thought a 100% accurate gaussian blur will not be possible, but as long as it looks good it will be ok :lol:

PS: Although you could combine step 2+3 in a single step.

Share this post


Link to post
Share on other sites

This way you can get a higher radius for less samples,thought a 100% accurate gaussian blur will not be possible, but as long as it looks good it will be ok :lol:

Hmmm... it could be possible...
When g0,g1,g2,... are the gaussian weights, and p0,p1,p2... the pixel values you want something like this:

final = g0*p0 + g1*p1+g2*p2+..

To utilize linear filtering better we could do something like this:

// normalize g1+g2
n1_2 = 1/(g1+g2)
=>
g1 * n1_2 + g2 * n1_2 = 1 = g1 * n1_2 + (1- (g1 * n1_2))
// now sample the pixel values with the normalized value of g1,g3,..
p0 = texture(0)
p1_2 = texture(1+(g1*n1_2))
p3_4 = textrue(3+(g3*n3_4))

// this results in
p1_2 = p1 * (g1*n1_2) + p2*(1-(g1*n1_2))
<=>
p1_2 = p1 * (g1*n1_2) + p2*(g2*n1_2)
// now multiply it with the inverted normalisation factor
p1_2 / n1_2 = p1 * g1 + p2 * g2

voila !

Share this post


Link to post
Share on other sites
Screenshot is looking much better than the previous one now :)


As you can see that's a lot of steps and a lot of code as well. Is there anyway I can do this simpler?


That's pretty much how many steps it takes. Ironically, sometimes adding more steps can help make things faster though. The main cost in bloom isn't the the number of passes, but instead the number of pixels you are operating on.

Food for thought: you don't need to run all of that code for bloom in areas that are below the threshold (doesn't matter how much you blur black, its still black). The trick to splitting up your display to work out where the bloom needs to go is an exercise left up to you though.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!