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
}
)
}
}
}
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.