We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
primitive bloom (Read 1346 times)
primitive bloom
Jan 3rd, 2008, 2:29pm
 
I've been digging around for a bloom solution and many simply required shaders. None of the processing GL shader solutions I've been trying out have worked so far (need to ask Creighton / Alexander and friends), so I dug even more for a non-shader bloom technique.

This method is quite simple and involves a brightpass and a box blur. References posted below as comments.

I've made it tunable so it can render quickly, or draw nicely for your renders.

There's a few more things you can tune as well.
Adding a tint(amount); before you draw pg will allow you to control the bloom strength.


Controlling the 150 constant in this line
   buffer.pixels[i] = red(buffer.pixels[i])>150 ? 255:0;

Will allow you to set a threshold for the bloom.

It's also possible to use this without additive blending, and use other ways of exposing it (drawing underneath your objects for example).


Some more notes:
- you can probably omit the updatepixels and speed things up, it's unnecessary...
- loadPixels is a bottleneck, not sure how I could speed this up (it eats bout 15ms of processing time on my machine)


Code:

// bloom code found at http://everyware.cc/files/codes/Bloom/ by EveryWare creative computing group
// modified and optimized by Flux http://www.ghost-hack.com



import processing.opengl.*;
import javax.media.opengl.*;

GL gl;

// offscreen buffer to draw the bloom onto
PGraphics pg;

// blur passes, the higher the number the more blurry the bloom becomes
int pass = 3;

// the lower the number the higher quality the bloom (less flickering)
int bufferScale = 6;

void setup() {
size(640, 480, OPENGL);
gl=((PGraphicsOpenGL)g).gl;
pg = createGraphics(width/bufferScale, height/bufferScale, P3D);
}

void draw() {

// draw renders normally
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
background(0);
stroke(255);
fill(255);
rectMode(CENTER);
ellipse(mouseX, mouseY, 50,50);

// dump contents into pg's pixel buffer
pg.beginDraw();
pg.copy(g,0, 0, width, height, 0, 0, pg.width, pg.height);
pg.endDraw();

// apply brightness pass
brightPass(pg);

// blur the brightness pass
for(int i=0; i<pass; i++)
blur(pg);

// display the brightpass as an additive blend
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);
pushMatrix();
image(pg, 0, 0, width, height);
popMatrix();
}




// brightpass utils

void brightPass(PGraphics buffer) {
for(int i=0; i<buffer.pixels.length; i++)
buffer.pixels[i] = red(buffer.pixels[i])>150 ? 255:0;
}

float[][] kernel = {
{
1.0, 1.0, 1.0, 1.0, 1.0 }
,
{
1.0, 1.0, 1.0, 1.0, 1.0 }
,
{
1.0, 1.0, 1.0, 1.0, 1.0 }
,
{
1.0, 1.0, 1.0, 1.0, 1.0 }
,
{
1.0, 1.0, 1.0, 1.0, 1.0 }
};

void blur(PGraphics buffer) {
int n2 = 5/2;
int m2 = 5/2;
int[][] output = new int[buffer.width][buffer.height];


// Convolve the image
for(int y=0; y<buffer.height; y++) {
for(int x=0; x<buffer.width; x++) {
float sum = 0;
for(int k=-n2; k<=n2; k++) {
for(int j=-m2; j<=m2; j++) {
// Reflect x-j to not exceed array boundary
int xp = x-j;
int yp = y-k;

if (xp < 0) {
continue;
}
else if (x-j >= buffer.width) {
continue;
}
// Reflect y-k to not exceed array boundary
if (yp < 0) {
continue;
}
else if (yp >= buffer.height) {
continue;
}
// avoid using get for a pinch of extra speed
sum = sum + kernel[j+m2][k+n2]/25.0 * brightness(buffer.pixels[yp*buffer.width + xp]);
// sum = sum + kernel[j+m2][k+n2]/25.0 * brightness(buffer.get(xp, yp));
}
}
output[x][y] = int(sum);
}
}

for(int i=0; i<buffer.pixels.length; i++)
buffer.pixels[i] = color(output[i%buffer.width][i/buffer.width]);

}
Re: primitive bloom
Reply #1 - Feb 14th, 2008, 10:45pm
 
hm... Sad nothing but a white rectangle
Re: primitive bloom
Reply #2 - Feb 23rd, 2008, 7:27am
 
Ah I just got it testing and working with processing 135 (ported from 125.. ten versions!!).

Apparently you no longer need updatePixels for this.

I've fixed the code above. Try it again? Smiley
Re: primitive bloom
Reply #3 - Feb 23rd, 2008, 9:27am
 
Aaahh! Smiley very, very, very nice!
Re: primitive bloom
Reply #4 - Feb 26th, 2008, 3:10pm
 
Im getting a "nullPointerException" for:

pg.copy(g,0, 0, width, height, 0, 0, pg.width, pg.height);


I'm using processing 134 Beta...any solutions ? Sad
Re: primitive bloom
Reply #5 - Feb 26th, 2008, 3:16pm
 
Okay, it's working with 135 now. THX, very nice!
Page Index Toggle Pages: 1