Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (804)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (868)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Bloom effect  (Read 19028 times)
0 Members and 1 Guest are viewing this topic.
Offline steveyg90
« Posted 2016-05-10 20:11:38 »

Hi,

Looking at adding a bloom effect to my game.  Is it possible to do this without using 3 FBOs?

First FBO used for original render, the second and third FBO will be used for the two passes of the Gaussian blur operation.

Many thanks,




Offline theagentd
« Reply #1 - Posted 2016-05-10 20:36:47 »

It is not possible to do bloom without using FBOs. Why are you asking?

Myomyomyo.
Offline steveyg90
« Reply #2 - Posted 2016-05-10 20:45:27 »

Just learning how to do it.

I take it the FBO's need updating each time the game screen is scrolled and you set the FBO's to the size of the screen?  Just wondering
how many cpu cycles it takes to do the bloom effect.

Thanks
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline theagentd
« Reply #3 - Posted 2016-05-10 22:00:08 »

You have a couple of misunderstandings here.

An FBO does not contain any actual data. What an FBO does is allow you to draw things to a texture. The FBO itself has no actual data; it just tells OpenGL where to put the result of your pixel shader at the end.

Secondly, using an FBO takes very little CPU cycles. The actual gaussian blur shader and the writing to the texture all happens in your graphics card, so it doesn't actually cost any CPU cycles at all (as long as your GPU is fast enough and doesn't lag behind, forcing the CPU to wait for it to catch up).

Myomyomyo.
Offline cylab

JGO Kernel


Medals: 195



« Reply #4 - Posted 2016-05-11 07:32:14 »

https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson5

Mathias - I Know What [you] Did Last Summer!
Offline steveyg90
« Reply #5 - Posted 2016-05-11 10:21:39 »

Many thanks,

Logic for a blur effect:

1. Create two FBO's the size of original display/scene
2. Render original scene with default shader to FBO_A
3. Enable horizontal blur shader, render FBO_A to FBO_B
4. Enable vertical blur shader, render FBO_B to screen

I'm taking it the original display size is what the camera sees, not the whole game/world scene!

Hoping to try this tonight.

Thanks
Offline steveyg90
« Reply #6 - Posted 2016-05-12 21:22:34 »

Hi,

Ok, tried to do just blur effect first, fine when doing it just for my hud display, great I thought, just move it around so it will do it for the landscape, no landscape is shown :-(

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
blurTargetA.begin();
     
      Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1f);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
               
      batch.setShader(null);
         
      batch.begin();
      batch.setProjectionMatrix(camera.combined);
   
      // Draw the map - only draw what camera sees
      worldMap.drawMap(debug, batch, regions, camX-2 , camY-2, endX , endY+2, WORLDWIDTH, WORLDHEIGHT);
   
      batch.flush();
      blurTargetA.end();
   
      batch.setShader(blurShader);
      // pass 1 - horizontal blur
      blurShader.setUniformf("dir", 1f, 0f);
      blurShader.setUniformf("radius", 1 * MAX_BLUR);
      blurTargetB.begin();
      fboRegion.setTexture(blurTargetA.getColorBufferTexture());
      batch.draw(fboRegion, 0, 0);
      batch.flush();
      blurTargetB.end();
         
      // pass 2 - vertical blur
      blurShader.setUniformf("dir", 0f, 1f);
      blurShader.setUniformf("radius", 1 * MAX_BLUR);
      fboRegion.setTexture(blurTargetB.getColorBufferTexture());
      batch.draw(fboRegion, 0, 0);
     
      batch.setShader(null);
      batch.end();


and the drawMap method:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
public void drawMap(boolean bDebug, SpriteBatch batch, TextureRegion[][] region, int sx, int sy, int ex, int ey,
         int w, int h) {

      // draw what we can see
      for (int row = sy; row < ey + 1; row++)
         for (int col = sx; col < ex + 1; col++) {
            BlankEntity entity = getEntity(col, row);
            if (entity != null) {
               {
                  batch.setColor((float) entity.lightValue / MAXLIGHT, (float) entity.lightValue / MAXLIGHT,
                        (float) entity.lightValue / MAXLIGHT, 1);
                 
                  if (entity.lightValue > 0)
                     worldMap[col][row].draw(batch, region, col, row);
                                 }
            }
         }

   }


I thought it had to be the line worldMap[col][row].draw(batch, region, col, row); as col and row basically start from where the camera is and thus thought by subtracting sx from col and sy from row would fix the issue as it is now placed in a FBO, but still nothing shows.  I'm convinced it got to be something to do with this.

The shader does work as originally did it with my HUD and worked a treat.  I'm stumped, but still have a feeling it is the drawMap method.

BTW I originally set the FBO's etc up like this:

1  
2  
3  
4  
         blurTargetA = new FrameBuffer(Format.RGBA8888, SCREENWIDTH, SCREENHEIGHT, false);
         blurTargetB = new FrameBuffer(Format.RGBA8888, SCREENWIDTH, SCREENHEIGHT, false);
         fboRegion = new TextureRegion(blurTargetA.getColorBufferTexture());
         fboRegion.flip(false, true);


SCREENWIDTH is 1920 and SCREENHEIGHT is 1080.

Hope somebody can see what I'm obviously doing wrong here - new to using shaders, so please be easy on me!

Many thanks you amazing people  Grin


PS - Vertex and pixel shader shown here:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 vColor;
varying vec2 vTexCoord;

void main() {
   vColor = a_color;
   vTexCoord = a_texCoord0;
   gl_Position = u_projTrans * a_position;      
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
varying vec4 vColor;
varying vec2 vTexCoord;

//declare uniforms
uniform sampler2D u_texture;
uniform float resolution;
uniform float radius;
uniform vec2 dir;

void main() {
    //this will be our RGBA sum
    vec4 sum = vec4(0.0);

    //our original texcoord for this fragment
    vec2 tc = vTexCoord;

    //the amount to blur, i.e. how far off center to sample from
    //1.0 -> blur by one pixel
    //2.0 -> blur by two pixels, etc.
    float blur = radius/resolution;

    //the direction of our blur
    //(1.0, 0.0) -> x-axis blur
    //(0.0, 1.0) -> y-axis blur
    float hstep = dir.x;
    float vstep = dir.y;

    //apply blurring, using a 9-tap filter with predefined gaussian weights

    sum += texture2D(u_texture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;
    sum += texture2D(u_texture, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;
    sum += texture2D(u_texture, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;
    sum += texture2D(u_texture, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;

    sum += texture2D(u_texture, vec2(tc.x, tc.y)) * 0.2270270270;

    sum += texture2D(u_texture, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;
    sum += texture2D(u_texture, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;
    sum += texture2D(u_texture, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;
    sum += texture2D(u_texture, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;

    //discard alpha for our simple demo, multiply by vertex color and return
    gl_FragColor = vColor * vec4(sum.rgb, 1.0);
}

Offline steveyg90
« Reply #7 - Posted 2016-06-05 11:36:28 »

Blur filter I did ages ago, now need to put in bloom.  I currently have to fbo's, do I need another one to do the bloom?  I'm taking it you do a threshold filter before the blur?

This is my code to do blur:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
blurTargetA.begin();
         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
     
         batch.begin();

         worldMap.drawMapWithBloom(debug, batch, regions, camX, camY, endX, endY, WORLDWIDTH, WORLDHEIGHT);
         
         batch.flush();
         blurTargetA.end();
         
         batch.setShader(blurShader);// blurShader);
         // pass 1 - horizontal blur
         blurShader.setUniformf("dir", 1f, 0f);
         blurShader.setUniformf("radius", 1 * MAX_BLUR);

         blurTargetB.begin();

         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

         fboRegion.setTexture(blurTargetA.getColorBufferTexture());

         batch.setColor(1, 1, 1, 1); // VIP!

         batch.draw(fboRegion, 0, 0, SCREENWIDTH, SCREENHEIGHT);
         batch.flush();
         blurTargetB.end();

         blurShader.setUniformf("dir", 0f, 1f);
         blurShader.setUniformf("radius", 1 * MAX_BLUR);
         fboRegion.setTexture(blurTargetB.getColorBufferTexture());

         batch.setProjectionMatrix(camera.combined); // bind to main camera
                                          // projection - VIP!!!

         batch.draw(fboRegion, (camX * 16), (camY * 16));// , 320,480);draw
                                             // to position
                                             // x400,y400


Where would I put code to do the threshold and then the bloom?

Thanks
Offline steveyg90
« Reply #8 - Posted 2016-06-07 19:45:41 »

Hi,

Ok, so bloom(threshold) shader just goes in first pass (when copying screen to first frame buffer).  

Bloom shader looks like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
uniform sampler2D u_texture0;
uniform sampler2D u_texture1;
uniform float BloomIntensity;
uniform float OriginalIntensity;
varying MED vec2 vTexCoord;

void main()
{
   vec4 original = texture2D(u_texture0, vTexCoord) * OriginalIntensity;
   vec4 bloom = texture2D(u_texture1, vTexCoord) * BloomIntensity;    
        original = original *  (vec4(1.0) - bloom);      
    gl_FragColor =  original + bloom;    
}


Now, my issue is, I light up parts of my display when player turns their torch on, but as OriginalIntensity is set only once, how can I get the
textures new colour?  Thus, using torch as on, lights up parts of the screen but then using bloom, it's like the torch isn't on...

Any help is much appreciated!

Thanks
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #9 - Posted 2016-06-07 23:55:21 »

Off topic, but why the heck are you using my texture banking convention D: u_texture

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline chrislo27
« Reply #10 - Posted 2016-06-08 01:14:19 »

Off topic, but why the heck are you using my texture banking convention D: u_texture

You don't own anything like u_texture - that just means it's a uniform. It's a typical naming convention. Not everything you "make up" is yours.

Steve, from what you're saying the bloom isn't getting applied? Or is messing with the existing lighting? A screenshot would be useful here.
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #11 - Posted 2016-06-08 03:31:36 »

Awe cute someone is angry at me sharing similarities with someone.

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline steveyg90
« Reply #12 - Posted 2016-06-08 08:15:32 »

Off topic, but why the heck are you using my texture banking convention D: u_texture

?!

Chrislo - Will get some screen shots up this evening.  I do believe the bloom is being applied as it does brighten certain areas up.

Offline steveyg90
« Reply #13 - Posted 2016-06-08 19:48:28 »

I've posted some screen shots here:

https://sites.google.com/site/sterrialand/development/news/shaderwhoes

My code for doing bloom:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
   if (bloomShaderOn) {

         blurTargetA.begin();
         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
     
         batch.begin();

         batch.setShader(bloomShader);
        bloomShader.setUniformi("u_texture0", 0);
         bloomShader.setUniformi("u_texture1", 1);
         bloomShader.setUniformf("BloomIntensity", 2.5f);
         bloomShader.setUniformf("OriginalIntensity", 0.2f);
         Gdx.gl.glDisable(GL20.GL_BLEND);
         
         worldMap.drawMapWithBloom(debug, batch, regions, camX, camY, endX, endY, WORLDWIDTH, WORLDHEIGHT);
         
         batch.flush();
         blurTargetA.end();
         
         Gdx.gl.glEnable(GL20.GL_BLEND);  
         
         batch.setShader(blurShader);
         // pass 1 - horizontal blur
         blurShader.setUniformf("dir", 1f, 0f);
         blurShader.setUniformf("radius", 0.5f * MAX_BLUR);

         blurTargetB.begin();

         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

         fboRegion.setTexture(blurTargetA.getColorBufferTexture());

         batch.setColor(1, 1, 1, 1);

         batch.draw(fboRegion, 0, 0, SCREENWIDTH, SCREENHEIGHT);
         batch.flush();
         blurTargetB.end();

         blurShader.setUniformf("dir", 0f, 1f);
         blurShader.setUniformf("radius", 0.5f * MAX_BLUR);
         fboRegion.setTexture(blurTargetB.getColorBufferTexture());

         batch.setProjectionMatrix(camera.combined); // bind to main camera
                                          // projection - VIP!!!

         batch.draw(fboRegion, (camX * 16), (camY * 16));
                                   
         batch.setShader(null);
   }


FBO's created like this:

1  
2  
3  
         blurTargetA = new FrameBuffer(Format.RGBA8888, SCREENWIDTH, SCREENHEIGHT, false);
         blurTargetB = new FrameBuffer(Format.RGBA8888, SCREENWIDTH, SCREENHEIGHT, false);
         fboRegion = new TextureRegion(blurTargetA.getColorBufferTexture());



Thanks
Pages: [1]
  ignore  |  Print  
 
 

 
Riven (579 views)
2019-09-04 15:33:17

hadezbladez (5501 views)
2018-11-16 13:46:03

hadezbladez (2398 views)
2018-11-16 13:41:33

hadezbladez (5761 views)
2018-11-16 13:35:35

hadezbladez (1220 views)
2018-11-16 13:32:03

EgonOlsen (4660 views)
2018-06-10 19:43:48

EgonOlsen (5681 views)
2018-06-10 19:43:44

EgonOlsen (3196 views)
2018-06-10 19:43:20

DesertCoockie (4094 views)
2018-05-13 18:23:11

nelsongames (5114 views)
2018-04-24 18:15:36
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!