Sign in to follow this  
SteveDeFacto

My bloom effect looks good but is very inefficient.

Recommended Posts

SteveDeFacto    109
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
Ashaman73    13715
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
Ashaman73    13715
[quote name='Ashaman73' timestamp='1313127141' post='4848113']
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:
[/quote]
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:
[code]
final = g0*p0 + g1*p1+g2*p2+..
[/code]
To utilize linear filtering better we could do something like this:
[code]
// 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 !
[/code]

Share this post


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

[quote name='SteveDeFacto' timestamp='1313112324' post='4848047']
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?
[/quote]

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this