0
\$\begingroup\$

recently I decided to implement in my game the drawing of a silhouette of the player when he is behind objects (the top layer of the map). Found a similar question here, but it doesn't matter to me to understand anything. Can someone please explain how it all works? I will be very grateful to you! Specifically, I'm interested in the issue of creating the Vertex and Fragments of the shaders? And why is only one shader passed to two setSheader methods.

Code that I do not understand:

// Rendering the upper map layer:
// Simple "if (gl_FragColor.a == 0.0) discard;" fragment shader
renderer.getBatch().setShader(shader);

//Rendering the silhouettes:
// "gl_FragColor = vec4(0.0, 1.0, 1.0, 0.2) * texture2D(u_texture, v_texCoord0).a;"
batch.setShader(shader);

EDITS:

I tried adding this code and this is what I got:

Java code:

//above render the normal player texture outside the shader code

mapRenderer.render(lowerLayer);
player.update(mapMgr, game.batch, delta, world);
mapRenderer.render(upperLayer);

Gdx.gl20.glClear(GL20.GL_STENCIL_BUFFER_BIT);

Gdx.gl20.glEnable(GL20.GL_STENCIL_TEST);
Gdx.gl20.glStencilFunc(GL20.GL_ALWAYS, 0x1, 0xFF);
Gdx.gl20.glStencilOp(GL20.GL_REPLACE, GL20.GL_REPLACE, GL20.GL_REPLACE);

mapRenderer.getBatch().setShader(shader);
mapRenderer.render(upperLayer);
mapRenderer.getBatch().setShader(null);

Gdx.gl20.glStencilFunc(GL20.GL_LEQUAL, 0x1, 0xFF);
Gdx.gl20.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_KEEP);

game.batch.setShader(shader);
player.update(mapMgr, game.batch, delta, world);
game.batch.setShader(null);

Gdx.gl20.glDisable(GL20.GL_STENCIL_TEST);

Fragment GLSL code:

varying vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;

void main() {
  vec4 c = vec4(.5, .5, .5, texture2D(u_texture, v_texCoords).a);
  if (c.a == 0.0) {
    discard;
  }
  gl_FragColor = c;
}

enter image description here

It didn't work out that way. In addition to the fact that the color of the top layer changes, the player is also completely painted, regardless of whether he is under the top layer or not.

I think the problem is in some of this:

  1. This part of the code does not work. Because even if you remove it, nothing changes.

    Gdx.gl20.glClear(GL20.GL_STENCIL_BUFFER_BIT); Gdx.gl20.glEnable(GL20.GL_STENCIL_TEST); Gdx.gl20.glStencilFunc(GL20.GL_ALWAYS, 0x1, 0xFF); Gdx.gl20.glStencilOp(GL20.GL_REPLACE, GL20.GL_REPLACE, GL20.GL_REPLACE); Gdx.gl20.glStencilFunc(GL20.GL_LEQUAL, 0x1, 0xFF); Gdx.gl20.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_KEEP); Gdx.gl20.glDisable(GL20.GL_STENCIL_TEST);

  2. Fragment shader is not written correctly

I spent all day solving this problem. Nothing works. I hope someone will figure it out! Thanks.

\$\endgroup\$
  • 2
    \$\begingroup\$ I think your question would greatly benefit from an explanation of what you have tried, and which part you are exactly having issues with. \$\endgroup\$ – Tyyppi_77 Sep 12 at 13:27
  • \$\begingroup\$ @Tyyppi_77, I'm specifically interested in what happens above the code that I provided in the link. That is, in the creat method. And what shader is used to achieve silhouette \$\endgroup\$ – Ra Aga Sep 12 at 14:28
  • \$\begingroup\$ The code provided seems to contain comments about the important bits of the fragment shader implementation? Is there a specific issue you are having with the initialization code that is not included in the original question? \$\endgroup\$ – Tyyppi_77 Sep 12 at 14:35
  • \$\begingroup\$ @Tyyppi_77, I would like to know what the Vertex and Fragment shader looks like.And I wonder why two identical shaders are passed to the setShader function, shouldn't they be different, for the map and for the silhouette \$\endgroup\$ – Ra Aga Sep 12 at 14:53
  • \$\begingroup\$ @Tyyppi_77 I added changes to my question, can you help me now? \$\endgroup\$ – Ra Aga Sep 12 at 21:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.