Sign in to follow this  
thecoast47

2DLight Blending in OpenGL

Recommended Posts

thecoast47    255
The language im working with is : JAVA (atm)
So awhile back i made a shadow caster. To simulate 2D light i use a radial gradient but when the radial gradients overlap they dont bleed into each other.

[media]http://www.youtube.com/watch?v=y3hiLiDlm4c[/media]

So my question Is: is there a way to make the multiple light sources bleed into each other?

In this Example it shows how i want the light to merge together to form a new color.
Example of blending light:
[media]http://www.youtube.com/watch?v=s60AljUbpKY[/media]


I asked a question similar to this in the openGL section but nobody answered it.



Heres what the Main draw method looks like:
[code]
public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glDepthMask(true);
gl.glClearDepth(2f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT |GL.GL_DEPTH_BUFFER_BIT );
gl.glEnable (GL.GL_BLEND);
gl.glBlendFunc (GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
gl.glDisable(GL.GL_CULL_FACE);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
setCamera(gl, glu,Distance);
for(int J = 0 ; J < ray.length ; J++){
ray[J].RenderLight(gl);
for(int K = 0 ; K < shape.length;K++){
shape[K].RenderShape(gl,ray[J]);
caster.getCastPoints(shape[K], ray[J], gl);
shape[K].ClearLists();
}
for(int K = 0 ; K < shape.length;K++){
shape[K].RenderShape(gl,ray[J]);
shape[K].ClearLists();
}
}
try {Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();}
}
[/code] Edited by thecoast47

Share this post


Link to post
Share on other sites
Fabbo    102
It looks like the lights value is set to a certain color instead of this color being added. This could fix yor problem.
If you can not add the lights color, try to use the alpha channel with a value arround 0.5

Share this post


Link to post
Share on other sites
thecoast47    255
[quote name='Fabbo' timestamp='1306052137' post='4814154']
It looks like the lights value is set to a certain color instead of this color being added. This could fix yor problem.
If you can not add the lights color, try to use the alpha channel with a value arround 0.5
[/quote]
I've tried that.
Doing that allowed me to see radial gradients that i drew at the beginning of the loop but they didnt blend together.
The colors bleeding into each other is what i want to achieve.

Share this post


Link to post
Share on other sites
haegarr    7372
Light effects are usually not blended by using the source alpha blending, i.e. src_RGB * src_A + dst_RGB * ( 1 - src_A ). Instead, it uses additive blending as in src_RGB * src_A + dst_RGB (i.e. there is no weighting of the original destination color other than with 1.0). If possible (e.g. when using a texture) the source should be pre-multiplied, so that src_RGB + dst_RGB would be used.

Similarly, shadow effects are usually done by using dst_RGB - src_RGB * src_A (or else dst_RGB - src_RGB if the source is pre-multiplied).

As soon as you use dst_RGB * ( 1 - src_A ) you're canceling out (or at least weakening) the original lighting.

Share this post


Link to post
Share on other sites
thecoast47    255
[quote name='haegarr' timestamp='1306073195' post='4814225']
Light effects are usually not blended by using the source alpha blending, i.e. src_RGB * src_A + dst_RGB * ( 1 - src_A ). Instead, it uses additive blending as in src_RGB * src_A + dst_RGB (i.e. there is no weighting of the original destination color other than with 1.0). If possible (e.g. when using a texture) the source should be pre-multiplied, so that src_RGB + dst_RGB would be used.

Similarly, shadow effects are usually done by using dst_RGB - src_RGB * src_A (or else dst_RGB - src_RGB if the source is pre-multiplied).

As soon as you use dst_RGB * ( 1 - src_A ) you're canceling out (or at least weakening) the original lighting.
[/quote]
Thanks for pointing me in the right direction.
I think i got it now.
The colors seem to be bleeding into each other now.
But it only blends in a in a certain spot.

Share this post


Link to post
Share on other sites
thecoast47    255
OK so now colors bleed into each other..but only the only problem is that the colors are all drawn in in a different layer than the shapes.
Its really weird and i cant really describe it.
[media]http://www.youtube.com/watch?v=qq1X_vTBTwU[/media]

Colors from light sources merge but now there is only one light source with (multiple light sources inside) and for some reason my shapes disappear when my light source isn't near them.
This is really getting frustrating.


To me , it looks like i drew everything into one buffer and im only looking at a portion of it the entire image.
Is there anyway to blit the entire buffer to the screen?

Here is the source:
[code]
public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT |GL.GL_DEPTH_BUFFER_BIT );
gl.glEnable (GL.GL_BLEND);
gl.glBlendFunc (GL.GL_SRC_ALPHA, GL.GL_ONE);
//gl.glBlendFunc(GL.GL_DST_ALPHA, GL.GL_ONE);*/
gl.glDisable(GL.GL_CULL_FACE);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glMatrixMode(GL.GL_TEXTURE);
gl.glLoadIdentity();
//System.out.println(Distance);
setCamera(gl, glu,Distance);

for(int J = 0 ; J < ray.length ; J++){

//this.BlendON(gl);
ray[J].RenderLight(gl);
//this.BlendOFF(gl);
gl.glBlendFunc(GL.GL_DST_ALPHA, GL.GL_ONE);
for(int K = 0 ; K < shape.length;K++){
shape[K].RenderShape(gl,ray[J]);
caster.getCastPoints(shape[K], ray[J], gl);//<---CASTS SHADOWS
shape[K].ClearLists();// this is here because i was to lazy to do it inside class
}
for(int K = 0 ; K < shape.length;K++){
shape[K].RenderShape(gl,ray[J]);
shape[K].ClearLists();
}
}




//try {Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();}

}
[/code]

Share this post


Link to post
Share on other sites
Michael Tanczos    5681
[quote name='thecoast47' timestamp='1306080466' post='4814257']
OK so now colors bleed into each other..but only the only problem is that the colors are all drawn in in a different layer than the shapes.
Its really weird and i cant really describe it.
[media]http://www.youtube.com/watch?v=qq1X_vTBTwU[/media]

Colors from light sources merge but now there is only one light source with (multiple light sources inside) and for some reason my shapes disappear when my light source isn't near them.
This is really getting frustrating.


To me , it looks like i drew everything into one buffer and im only looking at a portion of it the entire image.
Is there anyway to blit the entire buffer to the screen?

Here is the source:
[code]
public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT |GL.GL_DEPTH_BUFFER_BIT );
gl.glEnable (GL.GL_BLEND);
gl.glBlendFunc (GL.GL_SRC_ALPHA, GL.GL_ONE);
//gl.glBlendFunc(GL.GL_DST_ALPHA, GL.GL_ONE);*/
gl.glDisable(GL.GL_CULL_FACE);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glMatrixMode(GL.GL_TEXTURE);
gl.glLoadIdentity();
//System.out.println(Distance);
setCamera(gl, glu,Distance);

for(int J = 0 ; J < ray.length ; J++){

//this.BlendON(gl);
ray[J].RenderLight(gl);
//this.BlendOFF(gl);
gl.glBlendFunc(GL.GL_DST_ALPHA, GL.GL_ONE);
for(int K = 0 ; K < shape.length;K++){
shape[K].RenderShape(gl,ray[J]);
caster.getCastPoints(shape[K], ray[J], gl);//<---CASTS SHADOWS
shape[K].ClearLists();// this is here because i was to lazy to do it inside class
}
for(int K = 0 ; K < shape.length;K++){
shape[K].RenderShape(gl,ray[J]);
shape[K].ClearLists();
}
}




//try {Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();}

}
[/code]
[/quote]

For 2d lighting a quick trick is to render all your lights using additive blending to an offscreen buffer that is the size of your screen. Then use a multiply blend to combine your unlit scene with the offscreen buffer. Here was a quick description of multiply blending I found:

[url="http://www.photokaboom.com/photography/learn/Photoshop_Elements/blending_modes/6_blending_modes_mulitply_blending_mode.htm"]http://www.photokabo...ending_mode.htm[/url]

Another quick description of the mode:


[font="verdana"][size="2"][/size][/font][quote][font="verdana"][size="2"][b][i]Multiply: X = 1/255 (U*L)[/i][/b][/size][/font]
[font="verdana"] [/font]
[font="verdana"][size="2"]Multiply mode multiplies the pixel values of the upper layer with those of the layer below it and then divides the result by 255. The result is usually a darker image. If either layer is white, the resulting image is the same as the other layer (1 * L = L). If either layer is black, the resulting image is completely black (0 * L = 0). [i]Note: the mode is commutative; the order of the two layers doesn't matter.[/i][/size][/font]
[font="verdana"][size="2"][i]
[/i][/size][/font]
[font="verdana"][size="2"]In the next installment, we'll look at the Screen Blending Mode. Future postings will include a look at Soft Light and Difference Blending Modes as well as providing a list of references for further details on this complex subject.[/size][/font]
[/quote][font="verdana"] [/font]
[font="verdana"] [/font]
[font="verdana"][size="2"]Now I'm not an opengl programmer, but with Direct3d I've done this using shaders pretty easily.[/size][/font]

Share this post


Link to post
Share on other sites

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