Reputation: 105
In the .scn file I created for my project using Xcode, the file looks like this (the missile file included in the attachments) in the perspective view. But in the .scn model that apple provide in the ARKit example project, the plane and file looks far more different. It has a shadow plane and the view also looks entirely different. So my question is, 1. How do I add a shadow plane in my file and what is the use of it. 2. What is the difference between the two files. The one apple provides me and the one I created. 3. The best practices for creating an AR application.
1.The image Apple provides
2.The file I created (source: turbosquid.com)
thank you
Upvotes: 1
Views: 2552
Reputation: 1611
There are two ways to cast shadow:
First put a plane under the model(or detected plane), set its colorBufferWriteMask to SCNColorMask(0). Use spotlight and set its castsShadow to true and shadowMode to deferred.
override func viewDidLoad() {
// setup ARScene
// Disable automatic lighting
sceneView.autoenablesDefaultLighting = false
sceneView.automaticallyUpdatesLighting = false
// create secondary light
lightNode.light = SCNLight()
lightNode.light!.type = .omni
lightNode.position = SCNVector3(x: 0, y: 1, z: 1)
scene.rootNode.addChildNode(lightNode)
// create main light that cast shadow
lightNode2.light = SCNLight()
lightNode2.light!.type = .spot
lightNode2.position = SCNVector3(x: -1, y: 10, z: 1)
lightNode2.eulerAngles = SCNVector3(-Float.pi/2, 0, 0)
lightNode2.light?.castsShadow = true // to cast shadow
lightNode2.light?.shadowMode = .deferred // to render shadow in transparent plane
lightNode2.light?.shadowSampleCount = 64 //remove flickering of shadow and soften shadow
lightNode2.light?.shadowMapSize = CGSize(width: 2048, height: 2048) //sharpen or detail shadow
scene.rootNode.addChildNode(lightNode2)
// create ambient light
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = .ambient
ambientLightNode.light!.color = UIColor.darkGray
scene.rootNode.addChildNode(ambientLightNode)
}
// match the lighting with real world
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
if let estimate = sceneView.session.currentFrame?.lightEstimate{
lightNode2.light?.intensity = estimate.ambientIntensity
lightNode2.light?.temperature = estimate.ambientColorTemperature
lightNode.light?.intensity = estimate.ambientIntensity/3
lightNode.light?.temperature = estimate.ambientColorTemperature
}
}
// place transparent plane to capture shadow
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
if anchor is ARPlaneAnchor{
// place object on the detected plane anchor
// place shadow plane under your object
let shadowPlane = SCNPlane(width: 2, height: 2)
shadowPlane.materials.first?.colorBufferWriteMask = SCNColorMask(rawValue:0)
let shadowPlaneNode = SCNNode(geometry: shadowPlane)
planeNode.transform = SCNMatrix4MakeRotation(-Float.pi/2, 1, 0, 0) // because plane is created vertical
node.addChildNode(shadowPlaneNode)
}
}
Use a plane with texture of shadow as in apples project. There is a plane for shadow in scn file for plate and in plate for spoon and cup. You can see it if you play around with them.
The only difference is apple know how to cleverly make their model look natural. Using shadow plane, PBR.
And for best practice it depends on what you are trying to achieve.
Upvotes: 12