SCNNode clone() добавляет больше света в сцену при клонировании узлов

Я пытаюсь добавить несколько 3D-объектов с тенями в моем коде ARKit.

Я создаю такой узел

  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)

}

И как только ARKIT обнаруживает плоскость, я создаю плоскость, подобную этой:

  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

}

И по касанию самолета я добавляю к нему древовидные объекты с тенями. Но проблема в том, что когда я снова и снова клонирую эти объекты, плоскость под деревьями становится более яркой, я думаю, что добавляемый мной световой узел продолжает добавляться для каждого узла, хотя я пытаюсь удалить его по имени.

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
}

я также попытался добавить свет только для первого узла, а затем для остальных узлов, просто обновив первый узел света. Но это тоже не работает. Я хочу, чтобы деревья были добавлены с тенями с плоскостью под ним, оставаясь неизменным. Также тени не идеальны, есть ли способ сделать их лучше?

Смотрите скриншоты, как плоскость под деревьями меняется при добавлении деревьев одно за другим.

Первое изображение

Второе изображение

Третье изображение

1 ответ

Решение

Для каждого дерева, которое вы добавляете, вы добавляете свет, что делает ваш самолет ярче.

Придерживайтесь одного источника света, созданного вами в вашей сцене, и просто обновите ограничение, чтобы оно указывало на плоскость. Вам не нужно ничего делать с молнией, когда вы добавляете другие узлы. Когда ваша сцена имеет источник света, который создает тени, это повлияет на каждый добавляемый вами узел.

Чтобы ваши тени "выглядели лучше" - что бы это ни значило - вам нужно поиграться с различными режимами освещения и параметрами освещения. Я бы порекомендовал создать сцену в редакторе Xcode и поэкспериментировать со свойствами.

Другие вопросы по тегам