有没有办法在 Scenekit 上制作 moving/changing 阴影(就像初升的太阳)?
Is there a way to make moving/changing shadows on Scenekit (like a rising sun)?
我的基本代码在该教程中几乎是这样的:
https://code.tutsplus.com/tutorials/an-introduction-to-scenekit-fundamentals--cms-23847
我想做日出行为。诸如 lightNode 之类的东西从与受约束的 cubeNode 相同的高度开始并将其向上移动,以便阴影随着时间的推移变得更小。
因此我尝试通过 SCNAction.move(to...).
移动节点
对 lightNode 的操作 -> 什么都没有发生
作用在受约束的立方体节点上 -> 阴影开始闪烁,但没有变化
我尝试了 shadowModes。我想我误解了这一点。没有找到有用的结果。
有谁知道 scenekit 是否支持动态改变阴影之类的东西?
我找到了一种方法。我的主要错误是:
不知何故无法访问 lightNode(当调用 lightNode
的操作时,它只是没有效果)
我试图通过 SCNAction.move(to...)
。答案是使用旋转而不是纵向移动。
答案是访问约束节点(而不是 lightNode)。在此代码中,cubeNode 被替换为不可见的 centerPoint
(作为 lightNode
必须查看的约束节点)。添加了 boxNode
用于制作阴影 canvas。 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 how to create a complex loading animation".
但是我没有找到改变阴影颜色的方法。在夜间有白色阴影而在白天有黑色阴影可能是一个不错的效果。 light.shadowColor
还没有帮助。如果有人有想法,我们将不胜感激。
是的。你可以做出漂亮的移动影子。如果您的聚光灯没有移动,可能是因为教程对它施加了限制。尝试删除它。
// lightNode.constraints = [constraint]
我的基本代码在该教程中几乎是这样的: https://code.tutsplus.com/tutorials/an-introduction-to-scenekit-fundamentals--cms-23847
我想做日出行为。诸如 lightNode 之类的东西从与受约束的 cubeNode 相同的高度开始并将其向上移动,以便阴影随着时间的推移变得更小。 因此我尝试通过 SCNAction.move(to...).
移动节点对 lightNode 的操作 -> 什么都没有发生
作用在受约束的立方体节点上 -> 阴影开始闪烁,但没有变化
我尝试了 shadowModes。我想我误解了这一点。没有找到有用的结果。
有谁知道 scenekit 是否支持动态改变阴影之类的东西?
我找到了一种方法。我的主要错误是:
不知何故无法访问 lightNode(当调用
lightNode
的操作时,它只是没有效果)我试图通过
SCNAction.move(to...)
。答案是使用旋转而不是纵向移动。
答案是访问约束节点(而不是 lightNode)。在此代码中,cubeNode 被替换为不可见的 centerPoint
(作为 lightNode
必须查看的约束节点)。添加了 boxNode
用于制作阴影 canvas。 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 how to create a complex loading animation".
但是我没有找到改变阴影颜色的方法。在夜间有白色阴影而在白天有黑色阴影可能是一个不错的效果。 light.shadowColor
还没有帮助。如果有人有想法,我们将不胜感激。
是的。你可以做出漂亮的移动影子。如果您的聚光灯没有移动,可能是因为教程对它施加了限制。尝试删除它。
// lightNode.constraints = [constraint]