RealityKit – 材质的 Alpha 透明度

问题描述 投票:0回答:2

是否可以使纹理具有 alpha 透明度?

我有包含 8 位 RGBA 的 png 文件,但由于某种原因,本应透明的部分只是黑色。

我这样分配材料:

private func setupLightMeshes(_ scene: Entity) {
    let lightEntity = scene.findEntity(named: "LightWindow_Plane")!
    var lightMaterial = UnlitMaterial()
    
    lightMaterial.baseColor = try! MaterialColorParameter.texture(
    TextureResource.load(named: "light.png")) // this is 8bpc RGBA
    var modelComponent = lightEntity.components[ModelComponent] as! ModelComponent
    modelComponent = ModelComponent(mesh: modelComponent.mesh, materials: [lightMaterial])
    lightEntity.components.set(modelComponent)
}
swift augmented-reality arkit realitykit
2个回答
10
投票

RealityKit 1.0

.tintColor
.baseColor

的乘数

如果您有一个带有预乘 Alpha 的

.png
文件 (
RGB
*
A
)。您需要做的就是另外使用
tintColor
实例属性,其 alpha 等于
0.9999

material.tintColor = UIColor(white: 1.0, alpha: 0.9999)

实际代码如下:

fileprivate func material() -> UnlitMaterial {

    var material = UnlitMaterial()
    material.baseColor = try! .texture(.load(named: "transparent.png"))
    material.tintColor = UIColor(white: 1.0, alpha: 0.9999)
    return material
}

override func viewDidLoad() {
    super.viewDidLoad()
    
    let sphere: MeshResource = .generateSphere(radius: 0.5)

    let entity = ModelEntity(mesh: sphere,
                        materials: [material()])

    let anchor = AnchorEntity()
    anchor.orientation = simd_quatf(angle: .pi, axis: [0, 1, 0])

    anchor.addChild(entity)
    arView.scene.anchors.append(anchor)
}

似乎是 iOS 版 RealityKit 中的一个错误 - 为什么

png
透明度无法按预期工作?!


RealityKit 2.0

RealityKit 2.0 中也有关于部分透明纹理的相同故事:

var material = SimpleMaterial()

material.color = try! .init(tint: .white.withAlphaComponent(0.9999),
                         texture: .init(.load(named: "semi.png", in: nil)))

tint
参数也是
texture
的乘数。


visionOS 中的 RealityKit

在visionOS应用程序中,使用

OpacityComponent
创建透明材质变得更加容易:

modelEntity.components[OpacityComponent.self] = .init(opacity: 0.25)

1
投票

如果使用PhysicallyBasedMaterial,色调颜色不起作用。您需要使用

blending
属性。

RealityKit 2.0

简单的解决方案是使用便捷方法创建不透明度接近 1 的透明纹理。

此外,如果您想显示网格两侧的纹理(这是我的情况),您可以将

faceCulling
设置为
none

var material = PhysicallyBasedMaterial()
material.baseColor = .init(texture: .init(myPNGTexture))
material.blending = .transparent(opacity: 0.9999)
material.faceCulling = .none

更新

我意识到使用

PhysicallyBasedMaterial
,纹理不是完全透明的,所以并不完美。

这种材质是唯一支持

faceCulling
的材质,因此为了解决这个问题,我们的想法是使用
UnitMaterial
,但我们可以使用没有 深度 的盒子网格来代替平面。

var unlitMaterial = UnlitMaterial()
unlitMaterial.color = .init(
    tint: .init(white: 1.0, alpha: 0.9999),
    texture: .init(texture)
)
let entity = ModelEntity(
    mesh: MeshResource.generateBox(
        width: 0.33, 
        height: 0.33, 
        depth: 0 // IMPORTANT
    ),
    materials: [unlitMaterial]
)
© www.soinside.com 2019 - 2024. All rights reserved.