是否可以使纹理具有 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)
}
.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 中也有关于部分透明纹理的相同故事:
var material = SimpleMaterial()
material.color = try! .init(tint: .white.withAlphaComponent(0.9999),
texture: .init(.load(named: "semi.png", in: nil)))
tint
参数也是 texture
的乘数。
在visionOS应用程序中,使用
OpacityComponent
创建透明材质变得更加容易:
modelEntity.components[OpacityComponent.self] = .init(opacity: 0.25)
如果使用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]
)