Sign in to follow this  

Best way to filter for a bloom effect

This topic is 1919 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

So I have had a bloom effect implemented for some time but I just haven't been able to make it look right. I start my effect by filtering out the really bright parts then I do a two pass Gaussian blur and blend the blurred bright stuff with the original image. I have come to the conclusion that to make it look right I need to tweak how I decide what is bright so far I have two ways neither of which work well. My code is written in GLSL but this really applies to HLSL and cg as well. Anyway the first way goes like this:
[CODE]
if(sample.r > level)
{
sample.r = 1.0;
}
else
{
sample.r = 0.0;
}


if(sample.g > level)
{
sample.g = 1.0;
}
else
{
sample.g = 0.0;
}

if(sample.b > level)
{
sample.b = 1.0;
}
else
{
sample.b = 0.0;
}
[/CODE]
The problem with this method is that It will always glow either red, green or blue. For example a bright purple would glow red.

Method 2:

[CODE]
if((0.2126*sample.r) + (0.7152*sample.g) + (0.0722*sample.b) > level)
{
sample.r = 1.0;
sample.g = 1.0;
sample.b = 1.0;
}
else
{
sample.r = 0.0;
sample.g = 0.0;
sample.b = 0.0;
}
[/CODE]
This method works by determining the overall brightness (luminance?). But it never seems to glow any color but white.

So I developed two methods but neither seem to work right. Does anyone have any methods that they have used successfully? Or any suggestions on how to improve mine? Edited by ic0de

Share this post


Link to post
Share on other sites
Why are you multiplying the colour values by 2 in your second approach? That is probably why you're ending up with white glows since after saturation of the values you're likely ending up with white in most cases.

Share this post


Link to post
Share on other sites
[quote name='luca-deltodesco' timestamp='1350032211' post='4989397']
Why are you multiplying the colour values by 2 in your second approach? That is probably why you're ending up with white glows since after saturation of the values you're likely ending up with white in most cases.
[/quote]

Sorry that's a typo I was just testing something and accidentally posted the wrong shader. I updated it in my post but obviously it will still set everything to white. How do you suggest I brighten it without making white?

Share this post


Link to post
Share on other sites
Don't set them all to 1 for a start.

You could multiply them by a small factor i.e. 1.2 to make them brighter but consider that if you are adding the result to the buffer then you would probably want to de-brighten (great wordage) them first.

I think in the past I have just run a threshold, then blur, then a multiply down, then composite with an add

Share this post


Link to post
Share on other sites
I figured it out on my own and I must say It looks beautiful (although the effect seems to be fighting with my ssao). Anyway here is my solution.
[CODE]
if((0.2126*sample.r) + (0.7152*sample.g) + (0.0722*sample.b) > level)
{
float brightenRatio = 1.0 / max(max(sample.r, sample.g), sample.b);
sample.r *= brightenRatio;
sample.g *= brightenRatio;
sample.b *= brightenRatio;
}
else
{
sample.r = 0.0;
sample.g = 0.0;
sample.b = 0.0;
}
[/CODE]

The largest component ends up being 1.0 and the smaller components maintain the same ratio hence obtaining the same colour only brighter. Edited by ic0de

Share this post


Link to post
Share on other sites
[CODE](0.2126*sample.r) + (0.7152*sample.g) + (0.0722*sample.b)[/CODE]

Could be.

[CODE]
const vec3 luminance = vec3(0.2126, 0.7152, 0.0722);
float brightness = dot(lumiance * sample.rgb);
[/CODE]

Your method lose information. Everything over threshold just goes as bright. You allways can brighten up the blurred bloom texture values when you are compositing image. Then you dont lost information and you get much more variety for bloom.

One easy trick is just multiply the color with itself and using treshold or smoothstep.

Share this post


Link to post
Share on other sites
[quote name='kalle_h' timestamp='1350078357' post='4989591']
[CODE](0.2126*sample.r) + (0.7152*sample.g) + (0.0722*sample.b)[/CODE]

Could be.

[CODE]
const vec3 luminance = vec3(0.2126, 0.7152, 0.0722);
float brightness = dot(lumiance * sample.rgb);
[/CODE]

Your method lose information. Everything over threshold just goes as bright. You allways can brighten up the blurred bloom texture values when you are compositing image. Then you dont lost information and you get much more variety for bloom.

One easy trick is just multiply the color with itself and using treshold or smoothstep.
[/quote]

Sorry I don't quite get what you're saying. Do you mean I use something like:
[CODE]
const vec3 luminance = vec3(0.2126, 0.7152, 0.0722);
float brightness = dot(lumiance * sample.rgb);

if(brightness > level)
{
// do the rest
[/CODE] Edited by ic0de

Share this post


Link to post
Share on other sites
[code]
if((0.2126*sample.r) + (0.7152*sample.g) + (0.0722*sample.b) > level)
{
// just do nothing...
}
else
{
discard;
}
[/code]

Share this post


Link to post
Share on other sites
The "best way" in my opinion is not to use a threshold at all. A step function is ugly and will cause aliasing. A more natural approach is to just use a lower exposure for your bloom pass, which will naturally subdue to darker areas while allowing brighter areas to remain visible in the end result.

Share this post


Link to post
Share on other sites
In the threshold pass on my last project, we used an offset an a multiplier, e.g.
[code]output = max(0, input-threshold)*scale;[/code]Originally I was only had the scale variable, but the artists wanted a bit of extra control as to completely stopping the effect.

As with MJP's suggestion above, this ensures that there's no sudden point where your bloom texture jumps from zero up to some bright value.


BTW you should try an adopt a much more branchless style of programming when writing shaders compared to CPU code.
e.g. your different versions can have their [font=courier new,courier,monospace]if[/font] statements removed by using the [font=courier new,courier,monospace]step[/font] function along with multiplication:
[code]//1
sample.rgb = step(vec3(level), sample.rgb);
//2
sample.rgb = vec3(step(level, dot(sample.rgb, vec3(0.2126, 0.7152, 0.0722))));
//3
float brightenRatio = 1.0 / max(max(sample.r, sample.g), sample.b+0.00000001);
brightenRatio *= step( level, dot(sample.rgb, vec3(0.2126, 0.7152, 0.0722)) );
sample.rgb *= brightenRatio;[/code] Edited by Hodgman

Share this post


Link to post
Share on other sites
hy. im using this to in my bloom shader. is simple and it works really well
[CODE]

float4 color = tex2D( srcTex, IN.uv );
color = (-color + (pow(tex2D( srcTex, IN.uv ),Power) * Scale) )/Bias;
return color;
[/CODE]
here's a screenshot using scale = 1.83, power = 4 and bias = 0.27
[URL=http://imgur.com/WXed6][IMG]http://i.imgur.com/WXed6.jpg[/IMG][/URL]
PS: this is HLSL, but i think it should be really similar

Share this post


Link to post
Share on other sites
[quote name='pachesantiago' timestamp='1350324376' post='4990455']
hy. im using this to in my bloom shader. is simple and it works really well
[CODE]

float4 color = tex2D( srcTex, IN.uv );
color = (-color + (pow(tex2D( srcTex, IN.uv ),Power) * Scale) )/Bias;
return color;
[/CODE]
here's a screenshot using scale = 1.83, power = 4 and bias = 0.27
[url="http://imgur.com/WXed6"][img]http://i.imgur.com/WXed6.jpg[/img][/url]
PS: this is HLSL, but i think it should be really similar
[/quote]
Sorry, didnt mention that the grayscale is another shader, is not part of the "bright pass"
Using colors:
[URL=http://imgur.com/21Oys][IMG]http://i.imgur.com/21Oys.png[/IMG][/URL]

Share this post


Link to post
Share on other sites

This topic is 1919 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.

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