Reputation: 4817
Is it possible to have alpha transparency with textures?
I have png file that contains 8 bit RGBA, but for some reason, the supposed-to-be-transparent parts are simply black.
I assign the material like this:
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)
}
Upvotes: 4
Views: 2247
Reputation: 58563
.tintColor
is a multiplier for .baseColor
If you have a .png
file with a premultiplied alpha (RGB
*A
). all you need to do is to additionally use a tintColor
instance property with alpha equal to 0.9999
.
material.tintColor = UIColor(white: 1.0, alpha: 0.9999)
Here's how it looks like in a real code:
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)
}
Seems like a bug in RealityKit for iOS – why png
transparency doesn't work as expected?!
The same story about partially transparent textures is in RealityKit 2.0:
var material = SimpleMaterial()
material.color = try! .init(tint: .white.withAlphaComponent(0.9999),
texture: .init(.load(named: "semi.png", in: nil)))
tint
parameter is a multiplier for texture
as well.
In visionOS app, to create a transparent material has become easier with OpacityComponent
:
modelEntity.components[OpacityComponent.self] = .init(opacity: 0.25)
Upvotes: 13
Reputation: 4127
In case of using the PhysicallyBasedMaterial, the tint color does not work. You need to use the blending
property together with opacityThreshold
.
RealityKit 2.0
The easy solution is to use the convenience method to create a transparent texture with an opacity near to 1.
Besides if you want to show the texture for both sides of the mesh which was my case, you can set the faceCulling
to none
var material = PhysicallyBasedMaterial()
material.baseColor = .init(texture: .init(myPNGTexture))
material.blending = .init(blending: .transparent(opacity: 0.9999))
material.opacityThreshold = 0.0 // IMPORTANT
material.faceCulling = .none
Upvotes: 4