Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LibGDX Stencil Buffers while using SpriteBatch

This is a continuation of my previous problem and post, seen here. Thanks to the answer I received there I feel I was able to get a little closer to my goal, as well as further my learning of OpenGL, but shortly after figuring out the basics of working with stencil buffers, I've run into a problem.

It seems that when I draw a sprite to the stencil buffer, it draws the entire square area, rather than just the pixels that aren't fully transparent as I had ignorantly hoped. I vaguely understand why it happens that way, but I am not sure where the solution lies. I have experimented with the stencil itself quite a bit, and I have modified the shaders that the spritebatch uses to discard low-alpha fragments, but I seem to be failing to see the bigger picture.

As a visual example of the problem, I will continue with the examples I used in the previous question. Right now, trying to draw two circles over each other (So they blend perfectly, no overlapping), I am getting this :

Stencil testing

So, basically, is there a way for me to utilize stencil buffers using the Sprite and SpriteBatch functionality of LibGDX on complex shapes (Circles are only being used as an example), or do I need to look for an alternative route?

EDIT ::

    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

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

    batch.begin();
    sprite.draw(batch);
    sprite2.draw(batch);
    batch.end();

    Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
like image 680
Synthetik Avatar asked Mar 21 '26 17:03

Synthetik


1 Answers

Stencil writing/testing happens at the fragment level. When you draw a circle, you are actually drawing a quad of fragments where each fragment may or may not be textured. The issue of the matter is that the GPU doesn't care what color you write into the fragment when it does the stencil test for the fragment. Therefore, you need to discard fragments to stop the stencil writes for the parts of the quad where you don't want to write stencil values.

TL;DR Use "if(gl_FragColor.a < 0.01) discard;" in the fragment shader to make sure a circle of fragments (and stencil values) are generated.

like image 120
Darth Zaloj Avatar answered Mar 23 '26 09:03

Darth Zaloj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!