how to do a brightpass properly

Started by
13 comments, last by 21st Century Moose 11 years, 3 months ago
I've tried a few different approaches before, but right now my preferred one is this: don't do a brightpass at all. Instead, raise the original colour to some power, greyscale the result, then multiply the original colour by that result. I find that it gives a nice smooth transition between boomed parts of the scene and non-bloomed parts, and preserves the original colour balance perfectly.

okeys, this is interesting. so what you suggest is something like this (pixelshader ...pre blur pass pseudo code)?

powColor.r=inColor.r * inColor.r //i thought of using x^n with n=2 because pow() seems expensive? pls comment on this! :)

powColor.r=inColor.g * inColor.g

powColor.r=inColor.b * inColor.b

greyscale = (powColor.r +.powColor.b +powColor.g)/3 //calculate the arithmetic mean value (i think graphics guys refer to this as luminance, right?)

inColor *= greyscale //rescale the original color

this results in texture data which can be fed to the rest of the effect pipeline (the blurs and combining) just like the brightpass.

is this what you had in mind? or did i get something wrong?

Advertisement

okeys, even if you didnt mean it the way i interpreted it, it looks *ways* better than my original brightpass, at almost no fps cost at all, even when using pow()

and preserves the original colour balance perfectly.

word

probably the best gain to this method

[quote name='Tasche' timestamp='1357871509' post='5020113']
okeys, this is interesting. so what you suggest is something like this (pixelshader ...pre blur pass pseudo code)?



powColor.r=inColor.r * inColor.r //i thought of using x^n with n=2 because pow() seems expensive? pls comment on this! smile.png

powColor.r=inColor.g * inColor.g

powColor.r=inColor.b * inColor.b



greyscale = (powColor.r +.powColor.b +powColor.g)/3 //calculate the arithmetic mean value (i think graphics guys refer to this as luminance, right?)



inColor *= greyscale //rescale the original color



this results in texture data which can be fed to the rest of the effect pipeline (the blurs and combining) just like the brightpass.

is this what you had in mind? or did i get something wrong?
[/quote]

Some notes, this is more like a contrast function than a brightpass, but will work. Luminance is often a weighted sum of RGB like Y = 0.2126 R + 0.7152 G + 0.0722 B, And eventually I believe, that most compilers will optimize the pow function, therefor pow(x,2) will most likely compile to x*x if the compile mean that this one is faster.

Can we see some screenshots of before and after? ;)
I've tried a few different approaches before, but right now my preferred one is this: don't do a brightpass at all. Instead, raise the original colour to some power, greyscale the result, then multiply the original colour by that result. I find that it gives a nice smooth transition between boomed parts of the scene and non-bloomed parts, and preserves the original colour balance perfectly.

okeys, this is interesting. so what you suggest is something like this (pixelshader ...pre blur pass pseudo code)?

powColor.r=inColor.r * inColor.r //i thought of using x^n with n=2 because pow() seems expensive? pls comment on this! smile.png

powColor.r=inColor.g * inColor.g

powColor.r=inColor.b * inColor.b

greyscale = (powColor.r +.powColor.b +powColor.g)/3 //calculate the arithmetic mean value (i think graphics guys refer to this as luminance, right?)

inColor *= greyscale //rescale the original color

this results in texture data which can be fed to the rest of the effect pipeline (the blurs and combining) just like the brightpass.

is this what you had in mind? or did i get something wrong?

You're pretty much correct here, although obviously your code is going to be different to mine; here's my calculation:


return float4 (ColorIn.rgb * pow (abs (max (ColorIn.r, max (ColorIn.g, ColorIn.b))), powerFactor), 1.0f);

If you're concerned about performance of the power function an option is to encode it as a 256x1 floating point texture then do a look up. In practice I don't find that really necessary.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement