有没有办法在Scenekit上移动/改变阴影(就像朝阳)?

时间:2017-03-10 22:00:40

标签: objective-c swift shader scenekit scnlight

我的基本代码几乎就是这个教程: https://code.tutsplus.com/tutorials/an-introduction-to-scenekit-fundamentals--cms-23847

我想做一个日出行为。像lightNode这样的东西在与受约束的cubeNode相同的高度上开始并向上移动,以便阴影随着时间的推移变小。 因此,我尝试通过SCNAction.move(to ...)移动节点。

对lightNode采取行动 - >没有任何反应

对受约束的cubeNode采取行动 - >阴影开始闪烁,但没有变化

我尝试使用shadowModes。我想我误解了这一点。没有出现有用的结果。

有人知道如果scenekit支持动态改变阴影吗?

2 个答案:

答案 0 :(得分:1)

我找到了一种方法来实现它。我的主要错误是:

  1. 以某种方式它无法访问lightNode(只有在调用lightNode的操作时才会起作用)

  2. 我试图通过SCNAction.move(to...)。答案是使用旋转而不是纵向移动。

  3. 答案是访问约束节点(而不是lightNode)。在此代码中,cubeNode被替换为不可见的centerPoint(作为lightNode必须查看的约束节点)。添加了boxNode用于制作阴影画布。必须将lightNode添加到centerPoint,而不是添加到场景中。

    有修改后的viewDidLoad - 方法。如果你想检查一下,打开Xcode,以SceneKit Game开始一个新项目,并用以下代码替换viewDidLoad

        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)
    }
    

    还考虑了光的颜色变化。使用CABasicAnimation,可以随时间更改light.color - 属性。它不像一个完美的日出,所有的颜色步骤,但也有一种方法来链接这些动画,使其更复杂。 (为此搜索" wenderlich如何创建复杂的加载动画"。

    但我没有找到改变阴影颜色的方法。在白天有白色阴影和白天有黑色阴影可能是一个很好的效果。 light.shadowColor没有帮助。如果有人有想法,我们非常感激。

答案 1 :(得分:1)

是。你可以制作一个美丽动人的影子。如果您的聚光灯没有移动,可能是因为教程已经对它施加了约束。尝试删除它。

// lightNode.constraints = [constraint]
相关问题