Pixelated Bloom 2d filter

So I wrote my first 2D filter, attempting to create a nice bloom filter with Gaussian blur (by blurring a lower resolution).
Didn’t work out too well, but I guess it’s a start.

any critique/inefficiency remarks would be appreciated to I can improve!

I also wanted to replace each kernel with a filled circle and attempted using abs(i)*abs(j) < sample_size to determine which pixels are glowing but it didn’t seem to work.

uniform sampler2D bgl_RenderedTexture;uniform float bgl_RenderedTextureWidth; 
uniform float bgl_RenderedTextureHeight;


const float blur_size = 12.0;
const float threshold = 0.3;
const int blur_sample = 5;


vec2 getPos(vec2 newpos){
    return vec2(newpos.x*ceil(gl_TexCoord[0].x/newpos.x), newpos.y*floor(gl_TexCoord[0].y/newpos.y));
}


vec4 brightness(vec4 current_color){
    current_color = max(current_color- threshold, 0.0);
    return current_color;
}


void main()
{
    int i;
    int j;
    
    float pixW = blur_size*(1./bgl_RenderedTextureWidth), pixH = blur_size*(1/bgl_RenderedTextureHeight);


vec4 set_color = vec4(0);


for (i= -blur_sample; i &lt;=blur_sample; i++){
    for (j=-blur_sample; j&lt;=blur_sample; j++){
            vec2 offset = vec2(i*pixW, j*pixH);
            set_color += brightness(texture2D(bgl_RenderedTexture, getPos(vec2(pixW, pixH)+offset)));
}}
set_color/=((blur_sample*2)+1)*((blur_sample*2)+1);




gl_FragColor = texture2D(bgl_RenderedTexture, gl_TexCoord[0]) + set_color;
}

blur_size = how much space the bloom is stretched out across
threshold = minimum pixel value to be able to receive bloom
blur_sample = how much blurring there is

The filter is based on the current display resolution!

blur_size =12, threshold=0.3, blur_sample = 5

blur_size = 5, threshold = 0.3, blur_sample = 12

blur_size = 30, threshold = 0.3, blur_sample = 2

Feel free to use for your games!

Very nice. Good way to improve framerate.

Bloom always seems to bloom everything. Is there a way to make it only bloom a object with a certain property
or a high emit ? great work

yeah I have an example vof clamped bloom that youle helped me with, I will post tonight.

This is what the threshold value is for! only pixels with a value higher than the threshold will glow the others won’t.

yeah, but sometimes you want just certain objects or fx to bloom

clamped bloom only blooms ‘pure’ colors
(all color value is above .75 or below .15)

so

1,0,1 will bloom but .74,0,.74 will not.

uniform sampler2D bgl_RenderedTexture;



const float BRIGHT_PASS_THRESHOLD = 0.55;
const float BRIGHT_PASS_OFFSET = 0.01;




#define blurclamp 0.001
#define bias 10.8




#define KERNEL_SIZE 6.0




vec2 texcoord = vec2(gl_TexCoord[0]).st;




vec4 bright(vec2 coo)
{
    vec4 color = texture2D(bgl_RenderedTexture, coo);
    float threshMult = 0.0;
    if (((color.r &gt; 0.75) || (color.r &lt;= 0.15)) &&
        ((color.g &gt; 0.75) || (color.g &lt;= 0.15)) &&
        ((color.b &gt; 0.75) || (color.b &lt;= 0.15)))
    {
        threshMult = max(max(color.r, color.g), color.b);
    }


    color = max(color - BRIGHT_PASS_THRESHOLD, 0.0) * threshMult;
    return color / (color + BRIGHT_PASS_OFFSET) * 5.0;
}




void main(void)
{
	vec2 blur = vec2(clamp( bias, -blurclamp, blurclamp ));
	
	vec4 col = vec4( 0, 0, 0, 0 );
	for ( float x = -KERNEL_SIZE + 1.0; x &lt; KERNEL_SIZE; x += 1.0 )
	{
	for ( float y = -KERNEL_SIZE + 1.0; y &lt; KERNEL_SIZE; y += 1.0 )
	{
		 col += bright( texcoord + vec2( blur.x * x, blur.y * y ) );
	}
	}
	col /= ((KERNEL_SIZE+KERNEL_SIZE)-1.0)*((KERNEL_SIZE+KERNEL_SIZE)-1.0);
	gl_FragColor = col + texture2D(bgl_RenderedTexture, texcoord);
}

Ahh. So can you make it so a object with property “Bloom” will only emit bloom ?
Would be amazing.

I would recommend looking at https://blenderartists.org/forum/showthread.php?397594-Render-Passes-in-BGE

You’ll have to have some understanding of GLSL. Here’s a blend file of mine that does sort of what you’re looking for.
lightsaber.blend (14.1 MB)
Beware: This piece of junk is NOT optimized. My laptop GPU can’t handle this. It also doesn’t work on the blenderplayer for some reason.

Basically what I did is do a RenderToTexture on the 16:9 plane, where each objects GLSL program is set to black EXCEPT the ones that have the property “saberBlade”. Then I bound the texture to a filter using the glBindTexture function and then did a really expensive blur on that texture, and added it to the main render.

This pixelated bloom 2D filter may actually be what I need to optimize this

Well the filter itself isn’t terribly efficient either. it still runs in standard o(n^2) time which is quite costly, it just allows you to stretch out the result without having to increase the amount of sampling. Other algorithms also exist but require multiple passes, which I’m unsure how to do in GLSL at the moment without running multiple 2d filters?

A really useful intel article sums this up quite well with performance graphs etc. Read more about it here