RealityKit – How to set a ModelEntity's transparency?

≯℡__Kan透↙ 提交于 2020-05-26 08:21:23

问题


In SceneKit, there are lots of options such as

  • Use alpha channel of UIColor via SCNMaterial.(diffuse|emission|ambient|...).contents
  • Use SCNMaterial.transparency (a CGFloat from 0.0 to 1.0)
  • Use SCNMaterial.transparent (another SCNMaterialProperty)
  • Use SCNNode.opacity (a CGFloat from 0.0 (fully transparent) to 1.0 (fully opaque))

I wonder if there is a way to set transparency/opacity/alpha for ModelEntity in RealityKit?


回答1:


At the moment I see at least one solution in RealityKit allowing you to control object's transparency. But frankly saying, this solution works only for models made programmatically, hence you can't apply it to models that came from Reality Composer. You can do it using baseColor or tintColor instance properties of SimpleMaterial():

 var tintColor: NSColor { get set }     /*  color applied to the base color in macOS  */
 var baseColor: NSColor { get set }     /*  main (base) color in RealityKit macOS    */ 

Here's how real code looks like (I tested it in macOS):

var material = SimpleMaterial()

// CYAN TINT and SEMI-TRANSPARENT ALPHA   
material.tintColor = NSColor.init(red: 0.0, green: 1.0, blue: 1.0, alpha: 0.5)

material.baseColor = try! MaterialColorParameter.texture(TextureResource.load(contentsOf: url))
material.roughness = MaterialScalarParameter(floatLiteral: 0.0)
material.metallic = MaterialScalarParameter(floatLiteral: 1.0)

// CUBE WAS MADE IN REALITY COMPOSER
cubeComponent.materials = [material]

// SPHERE IS MADE PROGRAMMATICALLY
let mesh: MeshResource = .generateSphere(radius: 0.7)

let sphereComponent = ModelComponent(mesh: mesh,
                                materials: [material])

anchor.steelBox!.components.set(cubeComponent)
anchor.components.set(sphereComponent)
arView.scene.anchors.append(anchor)

Or if you do not need any texture on a model (just the color with opacity), you can control transparency via baseColor instance property:

material.baseColor = MaterialColorParameter.color(.init(red: 0.0,
                                                      green: 1.0, 
                                                       blue: 1.0, 
                                                      alpha: 0.5))

If your scene contains both types of objects – that made in Reality Composer and made programmatically in Xcode and you assign the same material to both objects – a compiled app is presenting some rendering artefacts (look at the picture below).

It's due to unstable work of RealityKit (because framework is too young at the moment). I think that in next version of RealityKit such bugs as missing texture on Reality Composer model and weird reflection left from sphere will be eliminated.




回答2:


I've found a several ways to do that.

  1. Without animation and the easiest is to use OcclusionMaterial():
let plane = ModelEntity(
                       mesh: .generatePlane(width: 0.1, depth: 0.1), 
                       materials: [OcculusionMaterial()]
            )

change existing Entity's opacity:

plane.model?.materials = [OcclusionMaterial()]
  1. With animation (you can tweak these snippets for your needs):
var planeColor = UIColor.blue

func fadeOut() {
        runTimer(duration: 0.25) { (percentage) in
            let color = self.planeColor.withAlphaComponent(1 - percentage)
            var material: Material = SimpleMaterial(color: color, isMetallic: false)
            if percentage >= 0.9 {
                material = OcclusionMaterial()
            }
            self.plane.model?.materials = [material]
        }

}

func fadeIn() {
        runTimer(duration: 0.25) { (percentage) in
            let color = self.planeColor.withAlphaComponent(percentage)
            let material: Material = SimpleMaterial(color: color, isMetallic: false)

            self.plane.model?.materials = [material]
        }
}

func runTimer(duration: Double, completion: @escaping (_ percentage: CGFloat) -> Void) {
        let startTime = Date().timeIntervalSince1970
        let endTime = duration + startTime

        Timer.scheduledTimer(withTimeInterval: 1 / 60, repeats: true) { (timer) in
            let now = Date().timeIntervalSince1970

            if now > endTime {
                timer.invalidate()
                return
            }
            let percentage = CGFloat((now - startTime) / duration)
            completion(percentage)

        }
}

hope this helped someone )



来源:https://stackoverflow.com/questions/59084240/realitykit-how-to-set-a-modelentitys-transparency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!