美文网首页SceneKit + ARKit
SceneKit_中级08_阴影详解

SceneKit_中级08_阴影详解

作者: 酷走天涯 | 来源:发表于2016-10-16 01:10 被阅读115次

    SceneKit_入门01_旋转人物
    SceneKit_入门02_如何创建工程
    SceneKit_入门03_节点
    SceneKit_入门04_灯光
    SceneKit_入门05_照相机
    SceneKit_入门06_行为动画
    SceneKit_入门07_几何体
    SceneKit_入门08_材质
    SceneKit_入门09_物理身体
    SceneKit_入门10_物理世界
    SceneKit_入门11_粒子系统
    SceneKit_入门12_物理行为
    SceneKit_入门13_骨骼动画
    SceneKit_中级01_模型之间的过渡动画
    SceneKit_中级02_SCNView 详细讲解
    SceneKit_中级03_切换照相机视角
    SceneKit_中级04_约束的使用
    SceneKit_中级05_力的使用
    SceneKit_中级06_场景的切换
    SceneKit_中级07_动态修改属性
    SceneKit_中级08_阴影详解
    SceneKit_中级09_碰撞检测
    SceneKit_中级10_滤镜效果制作
    SceneKit_中级11_动画事件
    SceneKit_高级01_GLSL
    SceneKit_高级02_粒子系统深入研究
    SceneKit_高级03_自定义力
    SceneKit_高级04_自定义场景过渡效果
    SceneKit_高级05 检测手势点击到节点
    SceneKit_高级06_加载顶点、纹理、法线坐标
    SceneKit_高级07_SCNProgram用法探究
    SceneKit_高级08_天空盒子制作
    SceneKit_高级09_雾效果
    SceneKit_大神01_掉落的文字
    SceneKit_大神02_弹幕来袭
    SceneKit_大神03_navigationbar上的3D文字

    先说几句,由于Swift 3.0 逐渐稳定,我之后所有的教程都会使用Swift 语言,如果学习请移步我亲写的学习教程

    让学习成为一种习惯

    学习目标

    掌握SceneKit 框架中的三种阴影创建方式

    阴影

    阴影类型 :静态,动态,投射

    • 静态

    这个方式很简单,就是给物体节点增加一个子节点,子节点设置一个图片作为它的阴影

    • 动态

    设置灯光的属性castsShadow 为YES 则,物体移动时,阴影也会跟着变化

    • 投射

    通过设置灯光的属性gobo,来捕捉阴影

    一起敲代码

    • 第一步 先创建工程
    让学习成为一种习惯
    • 第二步 添加库SceneKit
    让学习成为一种习惯
    • 第三步 创建游戏视图
        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

    今天我们的内容就学习到这里,希望对你有所帮助!

    相关文章

      网友评论

      本文标题:SceneKit_中级08_阴影详解

      本文链接:https://www.haomeiwen.com/subject/nfwpettx.html