Draw-order based transparency issue

I am having a transparency issue with drawing multiple POINTS style PShapes into a P3D PGraphics object. Each Vertex inside the PShapes has its own image-driven alpha value. Vertices with partial transparency misbehave. Those in PShapes drawn later will properly blend partially into PShapes drawn earlier. The PShapes drawn earlier will still exhibit partial alpha transparency, but they will completely mask out (i.e. fully occlude) PShapes that were drawn later. In other words, it appears that PShapes drawn later only check for the existence of a potentially occluding pixel–they do not evaluate whether its alpha value is greater than 0.

I am a new user so it will only let me post one image at a time. Below is Image 1. See the followup post for Image 2.

Image 1 illustrates the desired behavior. Image 2 illustrators the incorrect behavior, with the circular image masking entirely through the face layer.

The only different is the order the PShapes were instantiated into PGraphics objects: Image 1 first added the red square, followed by the face, followed by the circular image. Image 2 added the red square, followed by the circular image, followed by the face.

This behavior is not acceptable for the purposes of this Sketch, because in some situations five separate PShapes will all have partial transparency information, in which case no PShape loading order would produce a correct result.

I have tried altering various hint() properties. None produce the correct result in situations where the order is “wrong.”

The script is too long to post in full, so there’s a pseudocode description of the process below. I will happily repost excerpts that might be useful for evaluating the problem, but I’m expecting the issue is more deeply rooted.

Pseudocode:
PGraphics canvas = createGraphics(width,height,P3D);
PShape s1,s2,s3;
s1,s2,s3 = createShape(POINTS); all vertices derived from image pixel values
canvas.shape(s1);
canvas.shape(s2);
canvas.shape(s3);
image(canvas,0,0);

It’s the order that I call the canvas.shape(xxx); commands that affects transparency performance.

One (not ideal) solution would be to load all images’ vertices into a single PShape, but this would not be ideal because I allow interactive repositioning of each image cloud, and resetting 2,000,000 vertices is much slower than translating a PShape.

Please let me know if there’s anything that can be done to resolve this. I am running Processing 3.5.4, Java mode, on a 2019 Macbook Pro. Thank you!

Below is Image 2, showing incorrect behavior, where PShape drawn earlier (the circle) masks entirely through a PShape drawn later (the face), which has no transparency.

I just discovered the same, using only simple ellipses as shapes.
In an array of 7 objects, with alpha values, the first drawn will not display the alpha value.
If drawing from last to first5, the opposite

is there a fix for this problem now?

Not sure if I fully understand the problem but from my own experience Processing will not blend alpha values like other software can. In order for proper blending, the transparent shapes must NOT overlap or else undesired visual effects will be produced. Also the objects should be sorted from front to back. I hope this helps…

Just confirming that there is no fix to it–this is just how Processing handles alpha. You’ll always have to make a layer order decision, and it will impact the final appearance.

The only way for multiple transparent polygons to render correctly is to draw them from back to front. OpenGL, and, therefore, Processing, don’t know anything about the front to back order of your polygons and so can’t render them as you would like. OpenGL uses a z-buffer to store depth information per-pixel and, when drawing a random triangle, will only draw a given pixel if it is closer to you than (in front of) all the previously seen triangles that overlap that pixel. Transparency breaks this since you can see through a pixel to the triangles behind. The problem comes when you later try to draw a new triangle that falls between previously seen transparent triangles. The z-buffer only knows the depth of closest triangle, whether it’s opaque or transparent, so it assumes the closer pixel must be hiding the new triangle’s pixel and doesn’t show it.

The only way you can handle this is to draw all of your opaque triangles first, in any order, letting the z-buffer order them per-pixel. Then you have to manually sort your transparent triangles based on depth from the camera and draw them into the scene from back to front. If any of your transparent triangles intersect each other, you have to split them along the line of intersection and render the back halves first and then the front halves. It’s a mess.