2017-03-10 1 views
0

mon code de base est à peu près ceci sur ce tutoriel: https://code.tutsplus.com/tutorials/an-introduction-to-scenekit-fundamentals--cms-23847Existe-t-il un moyen de faire bouger/changer les ombres sur Scenekit (comme un soleil levant)?

Je veux faire un comportement lever du soleil. Quelque chose comme lightNode commence à la même hauteur que le cubeNode contraint et le déplace vers le haut de sorte que l'ombre devienne plus petite au fil du temps. Par conséquent j'ai essayé de déplacer les noeuds via SCNAction.move (à ...).

action sur lightNode -> rien ne se passe

action sur le cubeNode contraint -> ombre commence à vaciller, mais aucun changement

j'ai essayé dans les shadowModes. Je pense que j'ai mal compris. Aucun résultat utile n'est apparu.

Est-ce que quelqu'un a une idée si scenekit prend en charge quelque chose comme des ombres changeant de façon dynamique?

+0

S'il vous plaît nous montrer ce que vous appelez un soi-soleil levant ressemble dans une image. –

+0

Ici, j'ai trouvé une vidéo qui montre l'effet de mouvement de l'ombre que je veux créer avec Scenekit: https://www.youtube.com/watch?v=305b3X_FDZM –

+0

Après avoir vu la vidéo YouTube, j'ai plus de questions qu'une réponse.Maintenant, je ne suis pas sûr de la partie de la vidéo que vous voulez créer avec un cube. De plus, quand vous dites "Action sur lightNode -> rien ne se passe", il est difficile de dire quoi que ce soit puisque vous ne montrez aucune ligne de code. Sans informations supplémentaires, je propose que ce sujet soit fermé. –

Répondre

1

J'ai trouvé un moyen de le faire. Mes principales erreurs ont été:

  1. D'une certaine façon, il ne fonctionne pas pour accéder au lightNode (il a juste aucun effet, lorsque des actions pour un lightNode sont appelés)

  2. J'ai essayé de passer par SCNAction.move(to...). La réponse est d'utiliser une rotation au lieu d'un mouvement longitudinal.

La réponse était l'accès au nœud de contrainte (au lieu du lightNode). Dans ce code, le cubeNode est remplacé par un centerPoint invisible (en tant que nœud de contrainte où le lightNode doit être consulté). Un boxNode a été ajouté pour faire une toile pour l'ombre. Le lightNode doit être ajouté au centerPoint, PAS à la scène. Il y a le viewDidLoad -method modifié. Si vous voulez vérifier cela, ouvrez Xcode, démarrez un nouveau projet en tant que SceneKit Game et remplacez le viewDidLoad par le code suivant.

override func viewDidLoad() { 
    super.viewDidLoad() 

    // create a new scene 
    let scene = SCNScene(named: "art.scnassets/ship.scn")! 

    // create and add a camera to the scene 
    let cameraNode = SCNNode() 
    cameraNode.camera = SCNCamera() 
    scene.rootNode.addChildNode(cameraNode) 

    // place the camera 
    cameraNode.position = SCNVector3(x: 0, y: 0, z: 15) 

    // create and add a light to the scene 
    let centerPoint = SCNNode.init() 
    centerPoint.position = SCNVector3Make(0, 0, 0) 
    scene.rootNode.addChildNode(centerPoint) 

    let light = SCNLight() 
    light.type = SCNLight.LightType.spot 
    light.spotInnerAngle = 30 
    light.spotOuterAngle = 80 
    light.castsShadow = true 
    light.color = UIColor.init(colorLiteralRed: 0.95, green: 0.8, blue: 0.8, alpha: 1) 
    light.zFar = 200 

    let lightNode = SCNNode() 
    lightNode.light = light 
    lightNode.position = SCNVector3Make(20, 100, 50) 

    let constraint = SCNLookAtConstraint(target: centerPoint) 
    constraint.isGimbalLockEnabled = true 
    lightNode.constraints = [constraint] 
    centerPoint.addChildNode(lightNode) 

    let ambientLight = SCNLight.init() 
    ambientLight.type = SCNLight.LightType.ambient 
    ambientLight.color = UIColor.darkGray 

    scene.rootNode.light = ambientLight 

    // retrieve the ship node 
    let material = SCNMaterial.init() 
    material.diffuse.contents = UIColor.yellow 
    material.lightingModel = SCNMaterial.LightingModel.phong 
    material.locksAmbientWithDiffuse = true 

    let boxNode = SCNNode.init(geometry: SCNBox.init(width: 10, height: 0.1, length: 10, chamferRadius: 0)) 
    boxNode.geometry?.firstMaterial = material 
    boxNode.position = SCNVector3Make(0, -2, 0) 

    scene.rootNode.addChildNode(boxNode) 

    // animate spot light rotation 
    centerPoint.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: CGFloat(M_PI), y: 0, z: CGFloat(M_PI), duration: 5))) 

    // animate color light change 
    let lightColorChange: CABasicAnimation = CABasicAnimation.init(keyPath: "color") 
    lightColorChange.fromValue = UIColor.init(colorLiteralRed: 0.95, green: 0.8, blue: 0.8, alpha: 1) 
    lightColorChange.toValue = UIColor.init(colorLiteralRed: 0, green: 0, blue: 0.4, alpha: 1) 
    lightColorChange.duration = 5.0 
    lightColorChange.autoreverses = true 
    lightColorChange.repeatCount = Float.infinity 
    light.addAnimation(lightColorChange, forKey: "changeLight") 

    // retrieve the SCNView 
    let scnView = self.view as! SCNView 

    // set the scene to the view 
    scnView.scene = scene 

    // allows the user to manipulate the camera 
    scnView.allowsCameraControl = true 

    // show statistics such as fps and timing information 
    scnView.showsStatistics = true 

    // configure the view 
    scnView.backgroundColor = UIColor.black 

    // add a tap gesture recognizer 
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))) 
    scnView.addGestureRecognizer(tapGesture) 
} 

Il existe également un changement de couleur de la lumière. Avec une CABasicAnimation, il est possible de changer la propriété light.color au fil du temps. Ce n'est pas comme un lever de soleil parfait avec toutes les étapes de couleurs, mais il y a aussi un moyen d'enchaîner ces animations pour le rendre plus complexe. (Pour cette recherche de "wenderlich comment créer une animation de chargement complexe"

Mais je n'ai pas trouvé un moyen de changer la couleur de l'ombre, cela pourrait être un bon effet d'avoir des ombres blanches le soir et des ombres noires le jour. Si quelqu'un a une idée, elle est très appréciée

1

Oui, vous pouvez faire une belle ombre en mouvement Si votre projecteur ne bouge pas, c'est peut-être parce que le tutoriel vous a mis une contrainte sur il. Essayez de le supprimer.

// lightNode.constraints = [constraint] 
+0

Merci pour votre réponse. J'ai essayé ceci avec tous les types de lumière. Avec 'omni' et' directional'it fonctionne quand je déplace le 'lightNode'. Mais il crée seulement des ombres sur la surface comme ceci: http://www.directupload.net/file/d/4657/oajhkka8_png.htm 'ambient' ne donne pas une option pour faire des ombres. Et - pour être honnête - avec 'spot' je n'étais pas capable de calibrer la tache lumineuse sur l'objet manuellement (lol). Sans la contrainte je n'ai aucune idée de comment je peux faire un bon positionnement pour un projecteur. Mais avec 'spot' vous pouvez faire ceci: http://www.directupload.net/file/d/4657/yh7e52ok_png.htm –

+0

Mais j'ai remarqué que le' SCNAction.move (to ...) 'apporte le mauvais effet. Mais une rotation fonctionne très bien comme l'effet de lever de soleil que je cherchais. J'ai posté un code où cela fonctionne. A propos, savez-vous faire un meilleur rendu des taches d'ombre sur le sol? J'ai essayé d'aller avec 'light.shadowSampleCount = 10', mais l'ombre a disparu et les performances de l'application sont devenues effroyables. –

+0

Essayez de régler zNear sur le projecteur. –