Alpha value is multiplied by itself

I try to do the following:

  • Create an Image object from a png file with transparency (let’s say alpha = 0.36 for all pixels)
  • Create a Texture2D object from the image
  • Create a Material from that texture
  • Create a Quad with the material
  • Attach the quad to the scene graph
  • Render the scene
  • Read the frame buffer into a byte buffer
  • Convert the byte buffer to buffered image (BGRA → ARGB)

The result is the same original png, with the correct RGB components, but the Alpha is multiplied by itself!!! in our example - I’ll get alpha=0.36*0.36=0.1296

Any idea?

what material did you use ? and with what parameters ?

the main code lines are here:

jme3Image = new AWTLoader().load(new FileInputStream(“C:\temp\jme3_abstract.png”), false);
Texture2D texture2D= new Texture2D(jme3Image);
Geometry geo = new Geometry(“Flattenning”,new Quad(1, 1, false));
geo.setQueueBucket(Bucket.Transparent);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);
mat.setColor(“Color”, ColorRGBA.White);
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
mat.setTexture(“ColorMap”, texture2D);

geo.setMaterial(mat);

How are you determining that?

I’m checking the returned buffer, and also writing the returned buffer to png file and checking it…

Well, something seems to be odd about your setup then… because I use alpha all the time without this issue. My images all look like they are supposed to.

perhaps this is causing the texture to be rendered twice, once on the backside, once on the front side, which would explain the alpha channel multiplying by itself.

I get the same problematic result even when I set the Cull mode to back

Is your concern visual artifacts or that the data is stored badly?

I use alpha blending all the time and have never noticed bad visuals.

It seems like the result I get is in the pre-multiplied alpha format - but for some reason - the alpha itself is also multiplied by itself. When I take a square root of the alpha and use the result to convert the RGB components to regular RGB (not pre multiplied) I get the correct result.

??

The alpha channel is stored badly. I can fix it on my side after fetching the data - but I fail to understand what I’m doing wrong or what I’m missing here that I get this result. (assuming that JME3 is working OK)

Ok, then it’s the how the blend mode is setup. JME doesn’t really care what the stored alpha is. If the visuals are right then I guess JME thinks “it’s right”.

Without looking at the code, I guess the blend mode is setup to write SRC * SRC_ALPHA. So all four components will get multiplied by alpha when writing to the buffer. (Edit: or something like that… my blend-mode-fu is rusty.)

OK - thanks… Can you try to point me to the code where this magic happens?

Find the BlendMode class. Look at the comments in there that explain exactly what the blend mode setting is. There are online tools you can plug those values into to see the effect (I don’t have the links handy).

…then search through the code to see where BlendMode is used.