Jump to content
• Advertisement

Bloom Flickering

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

I've been having some issues with how I am doing bloom:

1. DownSample to 1/2 resolution
2. Perform bright pass at 1/2 resolution
3. DownSample BrightPass to 1/4 resolution
4. DownSample BrightPass  to 1/8 resolution
5. DownSample BrightPass  to 1/16 resolution
6. Apply Separable Gaussian Blur tap= 11 sigma=.25
7. UpSample Blurred Image to 1/8 resolution
8. Blend BrightPass at 1/8 and Blurred Image
9. Apply Separable  Gaussian Blur tap= 11 sigma=.25
10. UpSample Blurred Image to 1/4 resolution
11. Blend BrightPass at 1/4 and Blurred Image
12. Apply Separable Gaussian Blur tap= 11 sigma=.25
13. UpSample Blurred Image to 1/2 resolution
14. Blend BrightPass at 1/2 and Blurred Image
15. Apply Separable Gaussian Blur tap= 11 sigma=.25
16. Add final blurred image to the result from tonemapping.

For some reason, using this method makes it so that I have aliasing:

Here is what I think the problem is. The issue really occurs when I am moving around as the rasterizer chooses a different set of pixels to approximate its triangles.  This results in certain pixels being filled in one frame and not in the other.  I believe this what causes the flickering in the bloom.

I was thinking of applying some anti-aliasing methods to the bright pass filter, but I'm not even sure if I am on the right track.

Has anyone else encountered this issue?

Share this post

Share on other sites
Advertisement
That might be the problem, indeed. if your normal image suffers from aliasing already and you enhance the flickering pixel by a bloom filter, you'll notice that flickering way more.
real anti-aliasing would help for sure, but not the modern post-antialiasing techs, as these just soften the image, these are not adding sample information.
if you cannot go for real anti-aliasing, you could try to apply filter that will remove bright pixel, something like a median filter.

but before you take all the effort, make sure it's 100% not just a bug ;), as this can easily happen. e.g. render a pixel-resolution checkerbox, after the first step "DownSample to 1/2 resolution" you should get an absolutely even 50% gray image.

Share this post

Share on other sites

Try doing bloom in 1/1 instead of 1/2, seems like you end up doing bloom in 50% resolution which will always give jaggies IMO..

The "doing bloom in 50% res" was back when GPUs weren't as effective as today: a 1/1 bloom pass requires little computing power today :)

Share this post

Share on other sites

he "doing bloom in 50% res" was back when GPUs weren't as effective as today: a 1/1 bloom pass requires little computing power today

The op didn't specify what type of GPU is being used, and using down res rendertarget for post-processing is sometimes more than just computing power. There is power efficienc y concerns as well as algorithmic efficiency is generally. Just because the computing power is there, why not do stuff more efficiently than throwing computing resource at the issue.

Now to the op issue, even with an anti-aliased render target, you will still see a little flickering as the issue you are having is temporal aliasing. You probably need to make your filters ( blur etc ) temporal aware, ie. factor in the change in between frames.

Share this post

Share on other sites

Are you downsampling in high dynamic range format ? Don't forget that half overbright can still be overbright, so if your process introduces non linearities those overbright values do not get filtered as you wish they would.

Share this post

Share on other sites
What filter do you use during down/up-sampling?
A simple box filter will lead to spatial biasing and temporal instability.

You'll probably also have better luck if you blur at every step of the downsampling, then sum all thr blurred images together to approximate a very wide filter.

Share this post

Share on other sites

Try doing bloom in 1/1 instead of 1/2, seems like you end up doing bloom in 50% resolution which will always give jaggies IMO..

The "doing bloom in 50% res" was back when GPUs weren't as effective as today: a 1/1 bloom pass requires little computing power today

The issue is that I want to have a large bloom radius and my compute shader gaussian blur can only do a max tap of 33. However, I may be able to get similar results by just concatenating my blur filters.  Even so I'd still like to find out what I'm doing wrong as I think its pretty standard to do a downsample for bloom.

That might be the problem, indeed. if your normal image suffers from aliasing already and you enhance the flickering pixel by a bloom filter, you'll notice that flickering way more.
real anti-aliasing would help for sure, but not the modern post-antialiasing techs, as these just soften the image, these are not adding sample information.
if you cannot go for real anti-aliasing, you could try to apply filter that will remove bright pixel, something like a median filter.

but before you take all the effort, make sure it's 100% not just a bug ;), as this can easily happen. e.g. render a pixel-resolution checkerbox, after the first step "DownSample to 1/2 resolution" you should get an absolutely even 50% gray image.

Thanks! I'll give that a try and see what the results are.

Are you downsampling in high dynamic range format ? Don't forget that half overbright can still be overbright, so if your process introduces non linearities those overbright values do not get filtered as you wish they would.

Should I do the bright pass at full resolution?

What filter do you use during down/up-sampling?
A simple box filter will lead to spatial biasing and temporal instability.

For down sampling I am using this code:

static const float2 c_downSample4UV[4] =
{
float2( 0.5f, 0.5f),
float2(-0.5f, 0.5f),
float2( 0.5f,-0.5f),
float2(-0.5f,-0.5f),
};

void FillDownSample4UVs(in float2 texCoords, in float2 rcpFrameSize,
out float2 outSampleUVs[4])
{
[unroll]
for (int i = 0; i < 4; ++i)
{
outSampleUVs[i] = texCoords + rcpFrameSize * c_downSample4UV[i];
}
}

float4 main(in PSIn input) : SV_TARGET
{
float4 color = 0;
float2 uv[4];
FillDownSample4UVs(input.m_texCoords, g_rcpFrameSize, uv);

[unroll]
for (int i = 0; i < 4; ++i)
{
color += g_colorTexture.Sample(g_linear, uv[i]);
}

return color * 0.25f;
}


You'll probably also have better luck if you blur at every step of the downsampling, then sum all thr blurred images together to approximate a very wide filter.

I think I am doing something similar to this as I am blending the result of the DownSampled bright pass at each resolution and the resultant blur from the previous lower resolution.

However, I am not adding all the steps together, I am simply taking the final blended result.  Wouldn't adding all the filters add even more bloom to the final image? (This may not be a problem as I can probably tweak it by modifying the bloom multiplier)

I will try out the method that you suggested and get back to you on the results.

Thanks everyone for all the help!  I'll post back when I implement some of the suggestions that you gave.

Share this post

Share on other sites

I don't know if you already do but you can also do adaptive bloom to have progressive bloom, it can certainly solve issues you have.

Share this post

Share on other sites

The issue is that I want to have a large bloom radius and my compute shader gaussian blur can only do a max tap of 33. However, I may be able to get similar results by just concatenating my blur filters. Even so I'd still like to find out what I'm doing wrong as I think its pretty standard to do a downsample for bloom.

What I meant was: do a 1/1, 1/2, 1/4 and so on (depending on how many layers you want) and sample them all in a final pass, adding them together - that's what I've always done and works just fine for me.. Did not mean "do only a 1/1 pass", but "also do a 1/1 pass"..

Share this post

Share on other sites

For down sampling I am using this code:

That looks a bit suss.
Say we're going from a 4x4 to a 2x2 - blue squares are the desination pixels, green squares are source pixels:

Your pixel shader will run 4 times, with input.m_texCoords equal to the center of those 4 green crosses.

• If g_rcpFrameSize is 1/float2(source.width, source.height), then yep, it's a simple box filter. However, you could optimize this by just doing a single sample at input.m_texCoords using a bilinear filtering sampler state!
• If g_rcpFrameSize is 1/float2(dest.width, dest.height), then your four sampling locations will be at the intersections of the blue lines.
• If you're using point filtering, this will be incorrect, and cause some weird aliasing patterns in the output.
• If you're using linear filtering, this will just be a wider box filter, as below:
• If you slightly modify those sample locations to be slightly closer to the center (and use linear filtering), it will weight the averaging towards the center more then the outside pixels, giving you a something that's closer to approximating a gaussian or tent filter

Those wider, and more Gaussian-esque downsampling filters will reduce aliasing and improve image stability.

Also, what does your "bright pass" shader look like? These days I prefer to use a simple multiplier -- e.g. brightPassOutput = HdrInput * 0.1

Anything with a very sudden cut-off may introduce aliasing.

Share this post

Share on other sites

• Advertisement
• Advertisement

• Popular Contributors

1. 1
2. 2
3. 3
4. 4
Rutin
21
5. 5
• Advertisement

• 9
• 13
• 19
• 14
• 9
• Forum Statistics

• Total Topics
632939
• Total Posts
3009320
• Who's Online (See full list)

There are no registered users currently online

×

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!