manuelbua/libgdx-contribs

PostProcessor rendering clobbering Box2DLights and particles?

JesseTG opened this issue · 32 comments

This is more likely me using this (awesome) library incorrectly or my unfamiliarity with low-level OpenGL structures than it is a bug, but I'll ask anyway.

So I have several steps in the rendering. First I render the tiles (via OrthogonalTiledMapRenderer), then the sprites, then the lights (via box2dlights.RayHandler), then particles, then the in-game GUI (health bars over each enemy), then finally the GUI (via Scene2D and Stage). There's some particles here and there, too. This is all done with the same SpriteBatch (except RayHandler, it doesn't use a Batch). However, within my render() loop, anything I draw within PostProcessor destroys whatever I drew prior that wasn't drawn with PostProcessor. For example...

screenshot from 2014-06-11 21 37 28

Look at how sexy that glow is. You did this. You da man. Problem is, there should be a stream of particles behind the ship, and there should be a cone light in front of the player.

screenshot from 2014-06-11 21 39 01

If I turn off the PostProcessor's rendering in the GUI renderer, the lights and particles render as normal...but I want the GUI to glow.

What am I doing wrong?

Are you capturing the rendering operations by enclosing your drawings in capture/render block? You may need to enable blending as i'm doing here in the demo app, but this really depends on what you are rendering and how.

In one of my past projects i was also using the postprocessor with box2dlights and it was fine, but i'm sure i had to take blending or other box2dlights stuff into account, hopefully i can still find the sources when i get back home from work but don't count on that :)

Just an update: i remember one guy wanting to postprocess in the middle of the rendering operations, while performing it on the whole (stage included) was working fine, try check out this forum post maybe that will help :)

No good. Even if I wrap my entire game loop within PostProcessr.capture() and PostProcessor.render(), the lighting and even the GUI don't render as they should (particles appear fine, though).

I have no idea what I'm doing. Please help me.

I can't help but think you may need to blend the result in some way, if that's the case, but since this isn't a real issue of the postprocessor i'm closing this now.
I couldn't find the sources i was speaking of, but you can also take a look at the demo app, it's already doing the blending mechanic there.

You're right, that was it. I just enabled blending (with both parameters as GL_ONE) and screwed around with the bloom parameters a bit.

Nice one JesseTG, happy you got it running fine, and thanks for using the library!

Thank you for making it!

Note to self: Learn more OpenGL.

I have the same problem. How did you set the parameters of blending correctly? What bloom parameters did you set? Just using Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_ONE); didn't work..

Problem is that the Box2DLights only work when I do not use the post processing effects. In Box2DLights blending is always enabled so I don't know what the problem is...

It depends on what the state of the pipeline is: i'm using something similar in my game and box2dlights is working correctly, but i'm probably taking care of that in a different way.. should lookup the sources this evening though, much time passed :(

That'd be awesome! I'll sit tight then and wait for your update. Or if you could share some code where you integrate the post processing effects with Box2DLights?

All my drawing is just all wrapped in PostProcessor.capture and PostProcessor.render (I have no GUI).

Box2DLights has some blending GL-calls in its render method, could this interfere?

Mmm i'm quite sure i had to render to an off-screen buffer and then blend it where i needed, but if you are on mobile this will be costly!

I am working for desktop, so I can take abit of performance hit. I'd love to see some sample code if you can share!

You did something along those lines?:

        buffer.begin();
        super.draw();
        debugRenderer.render(this.level.world, getCamera().combined);
        buffer.end();

        postProcessing.begin();
        Batch batch = new SpriteBatch();

        batch.begin();

        batch.enableBlending();
        batch.setBlendFunction(GL20.GL_BLEND_SRC_ALPHA,GL20.GL_ONE);

        batch.draw(buffer.getColorBufferTexture(), 0, 0);

        batch.end();

        postProcessing.end();

Same problem...

Yes, then i think i was rendering the buffer after the postprocessing capture step, but before drawing it to video by postprocessing.render().
You may need to tweak that blend function, ie. GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA since it doesn't look right.

Urgh. Can't get that to work either.

Some of the effects work, but those are the effects that aren't "whole screen effects": still problem with blending..

I just did my Box2DLights rendering inside of the PostProcessor.begin() and PostProcessor.end() block. It actually didn't make the lights look too different.

Hmm thats what I am doing currently. Can you post source code?

JesseTG I don't think you got post processor working with Box2DLights if you just did what you are saying. I don't think it's possible getting them both working together without either using frame buffers or changing the source code in Box2DLights. Perhaps you got post processing working on GUI elements, background and sprites, but not on the lights themselves.

I did neither. I don't remember what my blending settings were, though,
but I'm pretty sure I applied them to the effect itself (a Bloom, in my
case).

On 09/11/2014 03:08 PM, Prantare wrote:

JesseTG I don't think you got post processor working with Box2DLights
if you just did what you are saying. I don't think it's possible
getting them both working together without either using frame buffers
or changing the source code in Box2DLights.


Reply to this email directly or view it on GitHub
#12 (comment).

Hm? By changing the source code in libgdx-contribs? Are you 100% sure the bloom affected the lights aswell? I have spoken to multiple people having problem doing this.

Yes, but it's quite subtle. Because my game is fast-paced, it's not
likely to be noticed, and even if it is it's no big deal.

And I did not change any source code except my own. libgdx?
box2dlights? libgdx-contribs? Nope. Nada.

On 09/11/2014 03:13 PM, Prantare wrote:

Hm? By changing the source code in libgdx-contribs? Are you 100% sure
the bloom affected the lights aswell? I have spoken to multiple people
having problem doing this.


Reply to this email directly or view it on GitHub
#12 (comment).

OK care to share how you did it through some source code? It'd be really really helpful! Me and my friends have problem getting this to work. Either the post processing is off or the Box2DLights just disappear.

Sure, gimme a minute.

On 09/11/2014 03:17 PM, Prantare wrote:

OK care to share how you did it through some source code? It'd be
really really helpful!


Reply to this email directly or view it on GitHub
#12 (comment).

I initialized the PostProcessor with something like this;

Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

this.postProcessor.setClearBits(GL20.GL_COLOR_BUFFER_BIT); // Probably not important
this.postProcessor.setClearColor(0, 0, 0, 1); // Probably not important

this.bloom.enableBlending(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_COLOR);

If you have a SpriteBatch, ShaderProgram, or similar running, make sure to end() it before rendering the lights (and to begin() it again immediately after, of course). This is all within the postProcessor.capture() and postProcessor.render() block.

Exactly what me and my friends do. Could you give more source code? Like when you call draw, capture/render on PostProcessor and RayHandler.render?

Initialize all that as above. My rendering then looks something like this;

Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
postProcessor.capture();
spriteBatch.begin();

// Render Sprites and TextureRegions

// Now, in the physics system...
world.step(RATE, VELOCITY_ITERATIONS, POSITION_ITERATIONS);
lighting.update();

spriteBatch.end();

lighting.render();

spriteBatch.begin();

// Render more sprites (GUI stuff mostly, but anything that shouldn't be colored by the lights)

// Okay, done rendering now

spriteBatch.end();
postProcessor.render();

The lights still don't bloom, only the sprites.

Here is my code:

    @Override
    public void draw(){ 
        if(postProcess){        
            // GL Blend and Clear
            Gdx.gl.glEnable(GL20.GL_BLEND);
            Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

            this.postProcessing.crt.enableBlending(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_COLOR);
            this.postProcessing.bloom.enableBlending(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_COLOR);
            this.postProcessing.postProcessor.setClearBits(GL20.GL_COLOR_BUFFER_BIT);
            this.postProcessing.postProcessor.setClearColor(0,0,0,1);


            // Post processing + sprites
            postProcessing.begin();
            super.draw();
            RayHandlerWrapper.renderRayHandlers(getCamera().combined);
            postProcessing.end();

            // Debug
            debugRenderer.render(this.level.world, getCamera().combined);
        } else {
            // Box2DLights + sprites
            super.draw();
            RayHandlerWrapper.renderRayHandlers(getCamera().combined);
            // Debug
            debugRenderer.render(this.level.world, getCamera().combined);
        }
    }

It's very subtle. Look closely.

Nope. It is not there. I can turn bloom intensity to 1000f and all my sprits just turn into blobs while the Box2DLights does not change at all.

I don't have enough free time to follow the thing as i would like, but i looked at my sources and trying to remember the ins and outs of it.
Basically, i separated the box2dlights' lightmap building step and the rendering phase (so that i'm not calling rayhandler.render() anymore), instead i just build the lightmap and render it manually, where and when i need.
If i'll ever have the time to post some code i'll do, but don't sit and wait for it since i'm very busy!