1

I am trying to render a texture to the stencil buffer. I only need pixels where their alpha is > 0, but my code is rendering every pixel of my quad - even the ones with 0 alpha. How can I avoid this?

Heres my code:

GL.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Incr);
GL.ColorMask(false, false, false, false);
GL.DepthMask(false);

RenderMask(mask);

GL.StencilFunc(StencilFunction.Equal, 1, 0xFF);

GL.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);
GL.ColorMask(true, true, true, true);
GL.DepthMask(true);

When debugging with RenderDoc I see that the stencil buffer contains 1s where my texture is... but its a rectangle, it does not take alpha into account.

Heres my fragment shader (it works fine for normal rendering):

varying lowp vec4 vColor;
varying lowp vec2 vTexCoords;
uniform lowp sampler2D uTexture;
void main() {
  gl_FragColor = texture2D(uTexture, vTexCoords) * vColor;
}
sydd
  • 1,824
  • 2
  • 30
  • 54

1 Answers1

4

Use a "discard" statement in the shader to drop the fragments you don't want to keep.

varying lowp vec4 vColor;
varying lowp vec2 vTexCoords;
uniform lowp sampler2D uTexture;
void main() {
  vec4 color = texture2D(uTexture, vTexCoords) * vColor;  
  if (color.a == 0.0) {
    discard; 
  }
  gl_FragColor = color;
}
solidpixel
  • 10,688
  • 1
  • 20
  • 33
  • Thanks! Is this this only solution in GL ES (I can use 3.0 too)? My issue is that discard is slow on iOS.. – sydd Sep 21 '16 at 21:40
  • 1
    Without changing the geometry, yes. In general the "best" fix for transparent sprites is to use well fitted geometry which isolates the totally opaque parts, and culls the transparent parts, so you're not rendering a high percentage of pixels which don't do anything useful. Something like this: https://community.arm.com/groups/arm-mali-graphics/blog/2015/11/19/mali-performance-7-accelerating-2d-rendering-using-opengl-es – solidpixel Sep 21 '16 at 21:42