SceneKit_大神03_navigationbar上的3D文字
先说几句,由于Swift 3.0 逐渐稳定,我之后所有的教程都会使用Swift 语言,如果学习请移步我亲写的学习教程
让学习成为一种习惯
掌握SceneKit 框架中的三种阴影创建方式
阴影类型 :静态,动态,投射
这个方式很简单,就是给物体节点增加一个子节点,子节点设置一个图片作为它的阴影
设置灯光的属性castsShadow 为YES 则,物体移动时,阴影也会跟着变化
通过设置灯光的属性gobo,来捕捉阴影
让学习成为一种习惯
让学习成为一种习惯
let scnView = SCNView(frame: self.view.bounds)
scnView.backgroundColor = UIColor.black
self.view.addSubview(scnView)
let scene = SCNScene()
scnView.scene = scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.camera?.automaticallyAdjustsZRange = true
cameraNode.position = SCNVector3(x: 0, y: 1000, z: 1000)
cameraNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: -Float(M_PI/4))
scnView.scene?.rootNode.addChildNode(cameraNode)
提示:
摄像机默认方向为 -Z 轴, 我设置它的位置为(0,1000,1000) ,沿自身坐标系x轴顺时针旋转了45度,这个是由于我的模型比较大,一般摄像机的位置是根据模型的大小进行调节的。
/// 1.先创建一个灯罩
let cone = SCNCone(topRadius: 1, bottomRadius: 25, height: 50)
cone.radialSegmentCount = 10
cone.heightSegmentCount = 5
/// 2.创建一个灯节点
let spotLight = SCNNode()
spotLight.geometry = cone
spotLight.geometry?.firstMaterial?.emission.contents = UIColor.yellow
spotLight.position = SCNVector3(0, 0, 0)
spotLight.light = SCNLight()
spotLight.light?.type = .spot
spotLight.light?.castsShadow = true
spotLight.light?.shadowMode = .forward
spotLight.light?.spotOuterAngle = 60
spotLight.light?.zFar = 2000
/// 创建一个支点,放等源
let handleSpot = SCNNode()
handleSpot.position = SCNVector3(0, 1000, 40)
handleSpot.addChildNode(spotLight)
scnView.scene?.rootNode.addChildNode(handleSpot)
提示:
灯光对象的属性 shadowMode 默认为.forward,如果你设置了这个属性,灯光效应下的阴影效果才能呈现出来,它会根据灯光效应去调节阴影颜色的阿尔法分量值
问题1:知道为什么要设置灯光的最远距离为2000吗?
因为灯光的最远注意默认值为100 ,由于我们将灯的指点放在1000 灯光照射不到那个距离,所以我们需要调节灯光照射的最远距离
问题2:为什么要给灯光添加一个支点,不添加可以吗?
不添加支点,是可以的,但是你要给灯光添加约束,让其对着模型,然后,你让这个灯光移动,这个时候,你会发现灯光节点一动不动,这里为什么不动,猜测是,行为和约束都要计算位置和角度,然而两者冲突了,优先使用约束。
let moveRight = SCNAction.move(to:SCNVector3(100, 1000, 40) , duration: 2)
let moveLeft = SCNAction.move(to:SCNVector3(-100, 1000, 40) , duration: 2)
let sequence = SCNAction.sequence([moveLeft,moveRight])
handleSpot.runAction(SCNAction.repeatForever(sequence))
let floor = SCNFloor()
floor.firstMaterial?.diffuse.contents = "floor.jpeg"
let floorNode = SCNNode(geometry: floor)
scnView.scene?.rootNode .addChildNode(floorNode)
let treeNode = SCNScene(named: "palm_tree.dae")?.rootNode.childNode(withName: "tree", recursively: true)
treeNode?.rotation = SCNVector4(x: 1, y: 0, z: 0, w: -Float(M_PI/2))
scene.rootNode.addChildNode(treeNode!)
let constaint = SCNLookAtConstraint(target: treeNode)
spotLight.constraints = [constaint]
友情提示:
各位小伙伴,注意了,一定要搞清楚这个约束谁是执行者添加给谁,这里的执行是是灯光节点自己,不是支点
以上我们演示了动态阴影的实现过程,我们运行看一下效果
让学习成为一种习惯
接下来演示一下,让灯光发射有形状的光
让学习成为一种习惯
spotLight.light?.castsShadow = false
spotLight.light?.gobo?.contents = "mip.jpg"
spotLight.light?.gobo?.intensity = 0.65
运行效果
让学习成为一种习惯
提示
一般如果我们使用这种效果的话,需要做如下设置
spotLight.light?.shadowMode = .modulated
再次运行
Scenekit_11.gif
今天我们的内容就学习到这里,希望对你有所帮助!