前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SceneKit_中级08_阴影详解

SceneKit_中级08_阴影详解

作者头像
酷走天涯
发布2022-05-13 16:06:30
6530
发布2022-05-13 16:06:30
举报

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

让学习成为一种习惯

  • 第三步 创建游戏视图
代码语言:javascript
复制
    let scnView = SCNView(frame: self.view.bounds)
    scnView.backgroundColor = UIColor.black
    self.view.addSubview(scnView)
  • 第四步 创建游戏场景
代码语言:javascript
复制
    let scene = SCNScene()
    scnView.scene = scene
  • 第五步 创建一个照相机
代码语言:javascript
复制
    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度,这个是由于我的模型比较大,一般摄像机的位置是根据模型的大小进行调节的。

  • 第六步 创建一个聚光灯
代码语言:javascript
复制
    /// 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:为什么要给灯光添加一个支点,不添加可以吗?

不添加支点,是可以的,但是你要给灯光添加约束,让其对着模型,然后,你让这个灯光移动,这个时候,你会发现灯光节点一动不动,这里为什么不动,猜测是,行为和约束都要计算位置和角度,然而两者冲突了,优先使用约束。

  • 第七步 为了效果明显,给灯光支点添加一个移动的行为
代码语言:javascript
复制
 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))
  • 第八步,添加一个地板,让阴影有地方显示
代码语言:javascript
复制
let floor = SCNFloor()
floor.firstMaterial?.diffuse.contents = "floor.jpeg"
let floorNode = SCNNode(geometry: floor)
scnView.scene?.rootNode .addChildNode(floorNode)
  • 第九步 添加一个模型对象到场景中去
代码语言:javascript
复制
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!)
  • 第十步 我们想让灯光在移动过程中一直对着我们的模型,所以我们添加一个约束
代码语言:javascript
复制
let constaint = SCNLookAtConstraint(target: treeNode)
 spotLight.constraints = [constaint]

友情提示:

各位小伙伴,注意了,一定要搞清楚这个约束谁是执行者添加给谁,这里的执行是是灯光节点自己,不是支点

以上我们演示了动态阴影的实现过程,我们运行看一下效果

让学习成为一种习惯

接下来演示一下,让灯光发射有形状的光

  • 随便找一张图片

让学习成为一种习惯

  • 修改上面的灯光代码
代码语言:javascript
复制
spotLight.light?.castsShadow = false
spotLight.light?.gobo?.contents = "mip.jpg"
spotLight.light?.gobo?.intensity = 0.65

运行效果

让学习成为一种习惯

提示

一般如果我们使用这种效果的话,需要做如下设置

代码语言:javascript
复制
spotLight.light?.shadowMode = .modulated

再次运行

Scenekit_11.gif

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 学习目标
  • 阴影
  • 一起敲代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档