4

I'm trying to have two boxes with one of them half transparent and the other in orange. Somehow it always just fully replaces the pixels but still kinda applies the transparency to the color. What am I missing? Same happens with loaded Obj files which have d/Tr set to 0.5 for example.

import javafx.application.Application;
import javafx.application.ConditionalFeature;
import javafx.application.Platform;
import javafx.scene.DepthTest;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.CullFace;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;

public class HelloFX extends Application {

    @Override
    public void start(Stage primaryStage) {
        boolean is3DSupported = Platform.isSupported(ConditionalFeature.SCENE3D);
        if (!is3DSupported) {
            System.out.println("Sorry, 3D is not supported in JavaFX on this platform.");
            return;
        }

        Box boxForeground = new Box(100, 500, 100);

        boxForeground.setTranslateX(250);
        boxForeground.setTranslateY(100);
        boxForeground.setTranslateZ(400);
        boxForeground.setMaterial(new PhongMaterial(new Color(0, 0, 0, 0.3)));

        Box boxBackground = new Box(100, 100, 100);

        boxBackground.setMaterial(new PhongMaterial(Color.ORANGE));
        boxBackground.setTranslateX(250);
        boxBackground.setTranslateY(200);
        boxBackground.setTranslateZ(800);

        boolean fixedEyeAtCameraZero = false;
        PerspectiveCamera camera = new PerspectiveCamera(fixedEyeAtCameraZero);
        camera.setTranslateX(150);
        camera.setTranslateY(-100);
        camera.setTranslateZ(250);

        Group root = new Group(boxForeground, boxBackground);
//        root.setDepthTest(DepthTest.ENABLE); // no effect
        root.setRotationAxis(Rotate.X_AXIS);
        root.setRotate(30);

        Scene scene = new Scene(root, 500, 300, true);
        scene.setCamera(camera);
        primaryStage.setScene(scene);
        primaryStage.setTitle("3D Example");

        primaryStage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}

I've played around with many options of depth buffer, depth test settings and colors but it seemed to have no good effect.

My expectation is that its possible to slightly see the orange box through the black box with strong transparency.

Actual result: enter image description here

kleopatra
  • 51,061
  • 28
  • 99
  • 211
schwaller
  • 147
  • 1
  • 8
  • 2
    If I swap the order of adding the 3d boxes it start to work as expected but thats not really feasible for complex scene. Must be a bug right? `Group root = new Group(boxBackground, boxForeground); // workaround` – schwaller Dec 01 '22 at 00:19
  • 1
    A related example is examined [here](https://stackoverflow.com/q/73291762/230513). – trashgod Dec 01 '22 at 00:30
  • 1
    Thank you - it really seems like we are expected to reorder the Group/Shape3D tree when the camera or objects move in the "z order" that is rather obviously the one that give the right transparency effect -.- Guess gonna go back to LWGL ... – schwaller Dec 01 '22 at 00:47
  • 1
    Related feature request: [JDK-8090548 3D: Support blending when diffuse component has alpha (transparency)](https://bugs.openjdk.org/browse/JDK-8090548), developer comment on request: “The fix to RT-40600 should work for some use cases as long as any overlapping 3D shapes are sorted such that the transparent 3D shapes (nearest last) are rendered after opaque 3D shapes.” -> exactly the findings of your independent investigation here. – jewelsea Dec 01 '22 at 02:22
  • Saw that one as well. There also other issues they closed/fixed that seem to indicate it should work and nobody mentions the order in the graph. Good to see i'm not a complete idiot - yet. Its also 7 years old similar to this one: https://bugs.openjdk.org/browse/JDK-8170852?filter=39543&jql=project%20%3D%20JDK%20AND%20issuetype%20in%20(Bug%2C%20Enhancement)%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20javafx%20AND%20text%20~%20%22transparency%203d%22%20ORDER%20BY%20updated%20DESC – schwaller Dec 01 '22 at 11:13

1 Answers1

2

So based on the comments and my own investigation it seems to be a known bug thats hasn't been fixed in over 5 years. Basically transparency works like in the 2D space of JavaFx. The one last added to the graph paints over the already painted ones - potentially using transparency blending when your colors/pixels contain alpha information.

Bugtracker: Order-independent transparency for 3D objects

Workaround:

The current workaround is to reorder the graph so it matches the desired z-order. Depending on the use case you can group objects on a root level to get close to an ideal transparency handling. But for transparent objects that 'interact' with each other on the same level of the graph you gonna need constant reordering when the objects or the camera move.

When done right you get the expected result:

enter image description here

Group root = new Group(boxForeground, boxBackground); // bug shows


Group root = new Group(boxBackground, boxForeground); // workaround

Apparently JavaFx has a long history of transparency issues. Which are also discussed here: JavaFX 3D Transparency

schwaller
  • 147
  • 1
  • 8