i am trying to add multiple 3d objects with shadows in my ARKit code.
I create node like this
func loadNodaA()
{
isObjectCoordinatesAtCentre = false
let scaleFactor = 0.005
let dragonScene = SCNScene(named:"art.scnassets/Lowpoly_tree_sample.dae")!
let queenNode = dragonScene.rootNode.childNode(withName: "Tree_lp_11", recursively: true)
let geometry : SCNGeometry = (queenNode?.geometry)!
geometry.materials = [self.CreateMaterialWithName("streakedmetal")];
nodeA = dragonScene.rootNode
nodeA.position = SCNVector3Zero
nodeA.scale = SCNVector3(x: Float(scaleFactor), y: Float(scaleFactor), z: Float(scaleFactor))
nodeA.position = SCNVector3Make(0,0,0)
}
And once ARKIT detects a plane, i create a plane like this:
func createPlaneNode(anchor: ARPlaneAnchor) -> SCNNode {
let floatwidth = anchor.extent.x
let floatlength = anchor.extent.z
let floatPlaneHeight : Float = 0.001
let planeGeometry = SCNBox(width: CGFloat(floatwidth), height: CGFloat(floatPlaneHeight), length: CGFloat(floatlength), chamferRadius:0)
planesGeometries[anchor.identifier] = planeGeometry
let planeNode = SCNNode(geometry: planeGeometry)
let transparentMaterial : SCNMaterial = SCNMaterial()
//transparentMaterial.diffuse.contents = UIImage.init(named: "art.scnassets/GridtextureGrayLines.png")
transparentMaterial.diffuse.contents = UIImage.init(named: "art.scnassets/sunmica.png")
//planeGeometry.materials = [transparentMaterial, transparentMaterial, transparentMaterial, transparentMaterial,self.CreateMaterialWithName("redbricks"), transparentMaterial];
//planeGeometry.materials = [transparentMaterial]
planeGeometry.firstMaterial = transparentMaterial
transparentMaterial.diffuse.contentsTransform = SCNMatrix4MakeScale(2,2, 0)
planeNode.geometry?.firstMaterial?.diffuse.wrapS = .repeat
planeNode.geometry?.firstMaterial?.diffuse.wrapT = .repeat
planeNode.position = SCNVector3Make(0, -(floatPlaneHeight/2), 0)
planeNode.physicsBody = SCNPhysicsBody(type: .kinematic, shape: SCNPhysicsShape(geometry: planeGeometry, options: nil))
//planeNode.castsShadow = true
self.setTextureScale(plane: planeNode, planeGeometry: planeGeometry)
return planeNode
}
And on tap of the plane i am adding tree objects with shadows to it. But the problem is when i clone these objects again and again, the plane below the trees gets more brightness i think light node that i am adding keeps on adding for each node although i am trying to delete it by name.
func insertGeometry(_ anchor : ARHitTestResult ) {
let h = CGFloat(selectedNode.boundingBox.max.y - selectedNode.boundingBox.min.y)
var insertionYOffset: Float = Float(h)/2.0;
if isObjectCoordinatesAtCentre == false
{
insertionYOffset = 0
}
let hitPointPosition = SCNVector3Make(
anchor.worldTransform.columns.3.x,
anchor.worldTransform.columns.3.y + insertionYOffset,
anchor.worldTransform.columns.3.z
);
var nodeClone = SCNNode.init()
if CurrentNodeChoise == 1
{
//This means draw tree
nodeClone = nodeA.clone()
}
nodeClone.position = hitPointPosition
sceneView.scene.rootNode.addChildNode(nodeClone)
guard let spotlightNode : SCNNode = (sceneView.scene.rootNode.childNode(withName: "LightForShadows", recursively: true)) else {
let spot = SCNLight()
spot.type = .spot
spot.castsShadow = true
spot.color = UIColor.darkGray
spot.shadowMode = .forward
spot.intensity = 2000
spot.shadowRadius = 5;
spot.shadowSampleCount = 20;
spot.shadowMapSize = CGSize(width: 4000, height: 4000)
spot.orthographicScale=50;
spot.zNear=1;
spot.zFar=1000;
spot.name = "myLight"
let spotNode = SCNNode()
spotNode.light = spot
spotNode.position = SCNVector3(x:4, y: 6, z: 0)
let lookAt = SCNLookAtConstraint.init(target: nodeClone)
constraintsArray.append(lookAt)
spotNode.constraints = constraintsArray
spotNode.name = "LightForShadows"
sceneView.scene.rootNode.addChildNode(spotNode)
return
}
let lookAt = SCNLookAtConstraint.init(target: nodeClone)
constraintsArray.append(lookAt)
spotlightNode.constraints = constraintsArray
}
i also tried to add light to the first node only and then for rest of the nodes by just updating the first light node. But this is also not working. I want trees to get added with shadows with plane below it remaining same. Also the shadows are not perfect is there a way to make them better?
See screenshots how plane below trees changes on adding trees one by one.
For every tree you add you add a light, of course that makes your plane brighter.
Stick with one light you create in your scene set up and just update it's constraint to point at the plane. You don't need to do anything with the lightning when you add other nodes. When your scene has a light that creates shadows this will effect every node you add.
To make your shadows "look better" - whatever that means - you need to play around with the different lightning modes and light parameters. I'd recommend creating a scene in the Xcode editor and play around with the properties.