Problem with transparent images

Hello Guys,
I’m struggling to make my sprites render with proper transparency.
I have this .j3md file:

MaterialDef Spritesheet {

    MaterialParameters {
        Texture2D ColorMap
        Float SizeX : 1
        Float SizeY : 1
        Float Position
    }

    Technique {
        VertexShader GLSL310 GLSL300 GLSL100 GLSL150:   MatDefs/sprite_sheet.vert
        FragmentShader GLSL310 GLSL300 GLSL100 GLSL150: MatDefs/sprite_sheet.frag

        WorldParameters {
            WorldViewProjectionMatrix
        }

        Defines {
        }
    }

}

with this .vert file:

uniform mat4 g_WorldViewProjectionMatrix;
uniform float m_SizeX;
uniform float m_SizeY;
uniform float m_Position;

attribute vec3 inPosition;
attribute vec2 inTexCoord;

varying vec2 texCoord;

void main(){

    float t = m_Position;
    float tPointerY = 1.0 - ((floor(m_Position / m_SizeX)) / m_SizeY) - 1.0 / m_SizeY;
    float tPointerYOffset = (floor(t / m_SizeX)) / m_SizeY;
    float tPointerX = (t - (tPointerYOffset * m_SizeX * m_SizeY)) / m_SizeX;
    texCoord.x = inTexCoord.x / m_SizeX + tPointerX;
    texCoord.y = inTexCoord.y / m_SizeY + tPointerY;
    gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
}

and this .frag file:

uniform sampler2D m_ColorMap;

varying vec2 texCoord;

void main(){

    vec4 color = texture2D(m_ColorMap, texCoord);
  gl_FragColor=color;
}

I create the material (and attach it to a cube) as explained in the docs:

Box b = new Box(1f, 1f, 0.01f); // create cube shape
        Geometry geom = new Geometry("Box", b);  // create cube geometry from the shape
        mat = new Material(assetManager, "MatDefs/sprite_sheet.j3md");
        mat.setTexture("ColorMap", texture);
        mat.setFloat("SizeX", cols);
        mat.setFloat("SizeY", rows);
        mat.setFloat("Position", 0f);
        mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
        geom.setQueueBucket(RenderQueue.Bucket.Transparent);
        geom.setMaterial(mat);

Problem - it looks transparent but a little bit dark (not fully transparent)

I copied the PreNormalPass technique code from the unshaded.j3md shader and added to mine:

   Technique PreNormalPass {

        VertexShader GLSL310 GLSL300 GLSL100 GLSL150 :   Common/MatDefs/SSAO/normal.vert
        FragmentShader GLSL310 GLSL300 GLSL100 GLSL150 : Common/MatDefs/SSAO/normal.frag

        WorldParameters {
            WorldViewProjectionMatrix
            WorldViewMatrix
            NormalMatrix
            ViewProjectionMatrix
            ViewMatrix
        }

        Defines {
            COLORMAP_ALPHA : ColorMap
            NUM_BONES : NumberOfBones
            INSTANCING : UseInstancing
            NUM_MORPH_TARGETS: NumberOfMorphTargets
            NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers
        }
   }

and it made the transparency look better but still - not perfect - It’s not dark now but it kind of highlights the background and I can see the other object’s shadow rendered on the sprite (also on the transparent parts) which is weird…

I read some questions here about transparency issues & this post: Alpha/Transparency Sorting, Your Z-buffer, and You

I also tried just for testing to use the unshaded.j3md shader and it also “highlights” the background and doesn’t render perfect transparency.

My question - what needs to be added to my shader in order for it to show good transparency with no side effects?

Thanks a lot! :slight_smile:

Update: I have added those 2 lines as explained in another post:

        mat.getAdditionalRenderState().setDepthWrite(false);
        mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.AlphaAdditive);

and now it looks like it solved the transparency issue.

For sprites, alpha additive is not right. It will add pixel values together instead of mixing them. If your red sprite is over your blue sprite then you will have purple on screen. This is probably not what you want.

Unless you are using things like SSO then the prenormal pass isn’t even used.

Did you set the alpha discard threshold?

Is this in 2D is 3D? rootNode or guiNode? We see a little soda-straw view of your code so we are left to guess about some things.

Even for something like this, a complete single class example would be good and a screen shot of what’s not right.

2 Likes

No, I didn’t

It’s 3D. I’m adding the Sprite to the rootNode with a BillboardControl.

I will do some more testing and update. Ill also try to compose a single class example.
Thanks a lot!

It’s the “PERFECT” text + kicks / punches hits effects that are presented with those sprites

To me, the only difference between what you want to do and Unshaded.j3md is the texture coordinates.

I’m a loooong time jme veteran by this point and even I fork one of the existing shaders whenever I want to do something new… even if I ultimately gut the whole thing. Probably you can get 100% of what you want to achieve by cut/pasting Unshaded.j3md and modifying a few lines in the vert shader.

Edit: and actually, you wouldn’t need to modify Unshaded.j3md at all if you gave your mesh the right atlas-based texture coordinates to begin with.

I tried to do that except I didn’t modify the .vert file but replaced it with mine and didn’t see anything (nothing was rendered to the screen)

I’m not sure I understand what do you mean by that… I also need to calculate the coordinates(maybe it’s called UV mapping?) depending on the given desired frame (position). this calculation is done in the .vert file. Is it as efficient as calculating it in Java code outside of the .vert file?

Well, I guess yours was missing something important then?

Debugging shaders is tough but there are tricks… like setting a particular color, etc…

What is the calculation?

Either way, this should be trivial to insert into a copied Unshaded.vert.