Jump to content

  • Log In with Google      Sign In   
  • Create Account

We need your feedback on a survey! Each completed response supports our community and gives you a chance to win a $25 Amazon gift card!


2DLight Blending in OpenGL


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 thecoast47   Members   -  Reputation: 255

Like
0Likes
Like

Posted 21 May 2011 - 11:04 PM

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.

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

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:
http://www.youtube.com/watch?v=s60AljUbpKY


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



Heres what the Main draw method looks like:
	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();}
	}

Edited by thecoast47, 18 June 2012 - 08:35 PM.


Sponsor:

#2 Fabbo   Members   -  Reputation: 102

Like
0Likes
Like

Posted 22 May 2011 - 02:15 AM

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
E=mc^2 + 2d6

#3 thecoast47   Members   -  Reputation: 255

Like
0Likes
Like

Posted 22 May 2011 - 07:41 AM

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

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.

#4 haegarr   Crossbones+   -  Reputation: 4604

Like
1Likes
Like

Posted 22 May 2011 - 08:06 AM

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.

#5 thecoast47   Members   -  Reputation: 255

Like
0Likes
Like

Posted 22 May 2011 - 08:56 AM

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.

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.

#6 thecoast47   Members   -  Reputation: 255

Like
0Likes
Like

Posted 22 May 2011 - 10:07 AM

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.
http://www.youtube.com/watch?v=qq1X_vTBTwU

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:
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();}

	}


#7 Michael Tanczos   Senior Staff   -  Reputation: 5457

Like
1Likes
Like

Posted 22 May 2011 - 10:34 AM

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.
http://www.youtube.com/watch?v=qq1X_vTBTwU

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:

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();}

	}


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:

http://www.photokabo...ending_mode.htm

Another quick description of the mode:


Multiply: X = 1/255 (U*L)

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). Note: the mode is commutative; the order of the two layers doesn't matter.


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.



Now I'm not an opengl programmer, but with Direct3d I've done this using shaders pretty easily.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS