Disabling skybox or black background


I'm new in programming with android.

I'm making a game based in compose but for a 3d dice I'm experimenting with sceneview (helped with IA) but I don't know what to make, I tried all but when I launch the dice (code down below) it appears with a black background, I just want it to be transparent so I can see my compose layers below. I tried changing the background in the SceneView to blue, and it appears in blue for a moment before going again to black.

fun Dice3DScene(result: Int, isRolling: Boolean, modifier: Modifier = Modifier) {
    val engine = rememberEngine()
    val modelLoader = rememberModelLoader(engine)
    val environmentLoader = rememberEnvironmentLoader(engine)

    var modelNode by remember { mutableStateOf<ModelNodeImpl?>(null) }
    var prevFrameTime by remember { mutableStateOf<Long?>(null) }

    val rotations = mapOf(
        1 to Rotation(0f, 0f, 0f),
        2 to Rotation(0f, 90f, 0f),
        3 to Rotation(90f, 0f, 0f),
        4 to Rotation(-90f, 0f, 0f),
        5 to Rotation(0f, -90f, 0f),
        6 to Rotation(180f, 0f, 0f)
    )

    SceneView(
        modifier = modifier.background(Color.Transparent),
        engine = engine,
        modelLoader = modelLoader,
        isOpaque = false,
        surfaceType = SurfaceType.TextureSurface,
        environment = rememberEnvironment(environmentLoader, isOpaque = false),
        cameraNode = rememberCameraNode(engine) {
            position = Position(z = 4.0f)
        },
        onFrame = { frameTimeNanos ->
            modelNode?.let { node ->
                if (isRolling) {
                    val delta = (frameTimeNanos.intervalSeconds(prevFrameTime) * 1000.0).toFloat()
                    node.rotation = Rotation(
                        x = node.rotation.x + delta,
                        y = node.rotation.y + delta * 1.5f,
                        z = node.rotation.z + delta * 0.5f
                    )
                } else {
                    val target = rotations[result] ?: Rotation(0f, 0f, 0f)
                    node.rotation = Rotation(
                        x = lerpAngle(node.rotation.x % 360f, target.x, 0.1f),
                        y = lerpAngle(node.rotation.y % 360f, target.y, 0.1f),
                        z = lerpAngle(node.rotation.z % 360f, target.z, 0.1f)
                    )
                }
            }
            prevFrameTime = frameTimeNanos
        }
    ) {
        LightNode(
            type = LightManager.Type.DIRECTIONAL,
            intensity = 100_000f,
            direction = Direction(-1f, -1f, -1f)
        )

        rememberModelInstance(modelLoader, "dice.glb")?.let { modelInstance ->
            ModelNode(
                modelInstance = modelInstance,
                scaleToUnits = 1.0f,
                centerOrigin = Position(0f, 0f, 0f),
                apply = {
                    modelNode = this
                }
            )
        }
    }
}
1
May 1 at 10:28 PM
User AvatarDaniel Espinosa
#android#android-jetpack-compose#sceneview

Accepted Answer

The black color is not coming from Modifier.background().
It is coming from SceneView/Filament’s 3D scene background, usually the skybox or environment.

For transparency, you need two things:

  • Use a transparent surface.

  • Do not render a skybox/background inside the 3D scene.

Try removing the environment first:

SceneView(
    modifier = modifier,
    engine = engine,
    modelLoader = modelLoader,

    // Important for transparency
    isOpaque = false,
    surfaceType = SurfaceType.TextureSurface,

    // Do not draw SceneView skybox/background
    environment = null,

    cameraNode = rememberCameraNode(engine) {
        position = Position(z = 4.0f)
    },
    onFrame = { frameTimeNanos ->
        // your rotation code
    }
) {
    LightNode(
        type = LightManager.Type.DIRECTIONAL,
        intensity = 100_000f,
        direction = Direction(-1f, -1f, -1f)
    )

    rememberModelInstance(modelLoader, "dice.glb")?.let { modelInstance ->
        ModelNode(
            modelInstance = modelInstance,
            scaleToUnits = 1.0f,
            centerOrigin = Position(0f, 0f, 0f),
            apply = {
                modelNode = this
            }
        )
    }
}

Also, put it above your Compose UI like this:

Box {
    // Your Compose background/layers
    YourComposeContent()

    Dice3DScene(
        result = result,
        isRolling = isRolling,
        modifier = Modifier.matchParentSize()
    )
}

Modifier.background(Color.Transparent) alone will not fix this because the black background is rendered by the 3D engine, not by Compose.

User AvatarAneequeMalik
May 2 at 12:52 AM
1