如何禁用 skybox 或将 SceneView 的黑色背景设为透明?
结论
要让骰子后方的 Compose 图层显示出来,需要让 SceneView 的渲染结果保留透明度,并停止绘制不透明背景。Modifier.background(Color.Transparent) 只影响 Compose 背景,无法清除 3D 渲染器已经画出的黑色像素。
你已经设置了 isOpaque = false 和 SurfaceType.TextureSurface,接下来应检查实际场景中的 skybox,以及 Filament 的混合模式和清屏颜色。仅凭这段代码,还不能确定黑色来自 skybox。
为什么蓝色只显示一瞬间
这通常是因为 SceneView 提交渲染帧之前,Compose 设置的蓝色背景可见;开始渲染后,不透明的 3D 输出就覆盖了它。
反复修改 Modifier.background(...) 无法解决渲染帧本身不透明的问题,需要检查以下配置:
- 场景是否仍在绘制 skybox。
- Filament
View是否允许透明混合。 - 未绘制模型的位置在清屏后,Alpha 是否为
0。 - 底层 TextureView 的
isOpaque是否为false。
禁用 skybox,并保留环境光照
skybox 负责显示天空或背景,环境光照中的 IndirectLight 负责照亮模型。隐藏 skybox 时,可以保留环境光照,避免骰子的外观随之改变。
在 Filament 层,可以这样移除可见的 skybox:
scene.skybox = null
这里的 scene 必须是 SceneView 正在渲染的 com.google.android.filament.Scene。
如果 SceneView 在加载或更新 environment 时重新设置了 skybox,就需要在环境配置中去掉 skybox,或者等环境应用完成后再执行上述设置。如果只在初始化早期清空一次,后续更新可能会覆盖这项设置。
透明渲染的配置示例
将 SceneView 实际使用的对象传入以下函数即可,无需另建场景或渲染器:
import com.google.android.filament.Renderer
import com.google.android.filament.Scene
import com.google.android.filament.View as FilamentView
fun configureTransparentBackground(
scene: Scene,
view: FilamentView,
renderer: Renderer
) {
// 停止绘制天空盒背景,保留已有的 IndirectLight。
scene.skybox = null
// 允许渲染结果与下方图层进行透明混合。
view.blendMode = FilamentView.BlendMode.TRANSLUCENT
// 将未绘制模型的位置清为透明。
renderer.clearOptions = renderer.clearOptions.apply {
clear = true
clearColor = floatArrayOf(0f, 0f, 0f, 0f)
}
}
题目没有给出 SceneView 的依赖版本,无法确定该版本通过哪些 Compose 参数或回调暴露 scene、view 和 renderer。接入时,应使用当前版本提供的初始化或更新入口,在环境应用完成后、渲染帧开始前配置这些对象。
部分版本会通过 isOpaque = false 自动设置透明混合和清屏。如果这两项设置已经正确,就重点检查 skybox 是否仍然存在,以及环境更新是否覆盖了配置。无需将相同设置一直放在 onFrame 中逐帧执行。
原代码中的旋转逻辑、相机位置和 LightNode 可以保留,它们不决定背景透明度。
让 Compose 内容位于骰子下方
透明区域下方还需要有 Compose 内容。可以用 Box 叠放图层,先放背景,再放骰子:
@Composable
fun DiceScreen(result: Int, isRolling: Boolean) {
Box(modifier = Modifier.fillMaxSize()) {
Box(
modifier = Modifier
.matchParentSize()
.background(Color.Blue)
)
Dice3DScene(
result = result,
isRolling = isRolling,
modifier = Modifier.matchParentSize()
)
}
}
先用蓝色背景验证,比使用透明背景更容易观察效果。配置正确后,骰子周围应该持续显示蓝色,此时再将蓝色 Box 换成游戏界面即可。
仍然黑屏时怎么排查
可以暂时移除模型,观察空场景:
- 空场景仍然是黑色:继续检查 skybox、清屏 Alpha、混合模式,以及底层 TextureView 的
isOpaque是否为false。 - 空场景已经透明,加载模型后才出现黑色区域:检查
dice.glb是否包含背景平面或其他遮挡几何体。 - 启动时透明,环境加载后变黑:检查应用环境时是否重新设置了 skybox。
- 背景颜色始终不可见:检查 Compose 图层顺序,以及中间是否有不透明容器覆盖背景。
rememberEnvironment(environmentLoader, isOpaque = false) 的具体行为应以所用版本的实现为准。仅凭参数名称,无法确认运行时的 skybox、混合模式和清屏 Alpha 都已符合要求。
备注:内容仅供参考。
