Problems with alpha blending

I have used two "Geom"s to create a test terrain and grass on it.
The terrain works fine - quite basic but the grass has some weird behaviour.

Both Geoms use the same vertex data. They do use a different geometry shader. Terrain uses a simple pass-through. The grass shader takes in points and outputs a quad (2 triangles).

The quad gets a texture applied to it. All very simple.
It seems that the transparent parts of the quad obscure other quads.
I can not order the quads by depth - they are all one Geom - created via the geometry shader.

I read this forums and tried quite a few fixes for this but I can not get it working.

grass = self.render.attachNewNode(grassGN)
grass.setTexture( grassTXT )
grass.setTwoSided(True)
#grass.setTransparency(True)
#grass.setTransparency(TransparencyAttrib.M_dual,1)
grass.setTransparency(TransparencyAttrib.M_alpha , 1)
grass.setTransparency(TransparencyAttrib.M_binary , 1)
grass.setDepthWrite(True)
grass.setShader(grassShader)

Above is how the grass is set up. I tried different (all) combinations of TransparencyAttrib - to no avail.
The terrain is visible through the transparent bits but other grass bits are not.

To me it seems that it depends on the side from which the quad is seen. The depth buffer value is written even when alpha is 0 when the quad is seen from specific side. On side all is ok - on the other side it is not.

Setting grass.setTwoSided(True) or False does not seem to have any impact on the actual output.

In more basic OpenGl I think I would use :

glAlphaFunc ( GL_GREATER, 0.1 ) ;
glEnable ( GL_ALPHA_TEST ) ;

What would be the equivalent in Panda3d?

I even tried a more manual approach with :

void main() {

  vec4 color = texture2D(p3d_Texture0, VertexIn.TexCoord0);
  if (color.a < 0.5 )
  {
      gl_FragColor  = vec4(1.0 , 0 , 0 , 1.0) ;
      discard ;
  }
  else
  {
    gl_FragColor  = color ;
  }

If I do not use discard - I get alpha visibly red from both sides - all ok.
But if I use “discard” - as above - I still overwrite the z buffer when alpha is small and obstruct quads drawn afterwards.

fixed it.
As part of earlier fix attempt I had :
layout(early_fragment_tests) in;

in the fragment shader.
This does not seem to work well with alpha blending .

Close.

Hi, welcome to the forums! :slight_smile:

Yes, “discard” is incompatible with early depth test, since the visibility of a fragment can only be known after fragment processing when you use “discard”.

For what it’s worth, GL_ALPHA_TEST is enabled with setTransparency(TransparencyAttrib.MBinary) (which just enables alpha test, not alpha blend), or, you may specify using the lower level node.setAttrib(AlphaTestAttrib.make(…)) interface.

I believe that modern drivers implement alpha test by injecting code into the active fragment shader similar to the code you have above.