How can I reduce the opacity of the shadows in Rea

2020-03-07 08:08发布

问题:

I composed a scene in Reality Composer and added 3 objects in it. The problem is that the shadows are too intense (dark).

I tried using the Directional Light in RealityKit from this answer rather than a default light from Reality Composer (since you don't have an option to adjust light in it).

Update I implemented the spotlight Lighting as explained by @AndyFedo in the answer. The shadow is still so dark.

回答1:

In case you need soft and semi-transparent shadows in your scene, use SpotLight lighting fixture which is available when you implement HasSpotLight protocol. By default SpotLight is north-oriented. At the moment there's no opacity instance property for shadows in RealityKit.

outerAngleInDegrees instance property must be not more than 179 degrees.

import RealityKit

class Lighting: Entity, HasSpotLight {

    required init() {
        super.init()

        self.light = SpotLightComponent(color: .yellow,
                                    intensity: 50000,
                          innerAngleInDegrees: 90,
                          outerAngleInDegrees: 179,  // greater angle – softer shadows
                            attenuationRadius: 10)   // can't be Zero
    }
}

Then create shadow instance:

class ViewController: NSViewController {

    @IBOutlet var arView: ARView!

    override func awakeFromNib() { 
        arView.environment.background = .color(.black)

        let spotLight = Lighting().light
        let shadow = Lighting().shadow
        let boxAndCurlAnchor = try! Experience.loadBoxAndCurl()

        boxAndCurlAnchor.components.set(shadow!)
        boxAndCurlAnchor.components.set(spotLight)

        arView.scene.anchors.append(boxAndCurlAnchor)
    }
}

Here's an image produced without this line: boxAnchor.components.set(shadow!).

Here's an image produced with the following value outerAngleInDegrees = 140:

Here's an image produced with the following value outerAngleInDegrees = 179:

In a room keep SpotLight fixture at a height of 2...4 meters from a model.

For bigger objects you must use higher values for intensity and attenuationRadius:

self.light = SpotLightComponent(color: .white,
                            intensity: 625000,
                  innerAngleInDegrees: 10,
                  outerAngleInDegrees: 120,
                    attenuationRadius: 10000)



回答2:

The shadows appear darker when I use "Hide" action sequence on "Scene Start" and post a notification to call "Show" action sequence on tap gesture. The shadows were fixed when I scaled the Object to 0% and post Notification to call "Move,Rotate,Scale to" action sequence on tap gesture.

Scaled Image

Unhide Image

Object Difference with hidden and scaled actions

import UIKit

import RealityKit

import ARKit


class Lighting: Entity, HasDirectionalLight {
    required init() {
        super.init()
        self.light = DirectionalLightComponent(color: .red, intensity: 1000, isRealWorldProxy: true)
    }
}

class SpotLight: Entity, HasSpotLight {

    required init() {
        super.init()
        self.light = SpotLightComponent(color: .yellow,
                                        intensity: 50000,
                                        innerAngleInDegrees: 90,
                                        outerAngleInDegrees: 179, // greater angle – softer shadows
            attenuationRadius: 10) // can't be Zero

    }
}

class ViewController: UIViewController {

    @IBOutlet var arView: ARView!

    enum TapObjects {
        case None
        case HiddenChair
        case ScaledChair
    }    
    var furnitureAnchor : Furniture._Furniture!
    var tapObjects : TapObjects = .None

    override func viewDidLoad() {
        super.viewDidLoad()

        furnitureAnchor = try! Furniture.load_Furniture()
        arView.scene.anchors.append(furnitureAnchor)

        addTapGesture()

    }

    func addTapGesture() {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(onTap))
        arView.addGestureRecognizer(tapGesture)
    }

    @objc func onTap(_ sender: UITapGestureRecognizer) {

        switch tapObjects {
        case .None:
            furnitureAnchor.notifications.unhideChair.post()
            tapObjects = .HiddenChair
        case .HiddenChair:
            furnitureAnchor.notifications.scaleChair.post()
            tapObjects = .ScaledChair
        default:
            break
        }

    }
}