from: http://blog.csdn.net/Oboe_b/article/details/77922344
简介:
上篇回顾:
ARKit初探篇(链接)中写到怎样开启一个AR项目,包括开发环境,建立项目,及基础代码实现,在git的demo添加了手势的处理,简单实现点击球体实现图片轮换
本篇介绍:
将虚拟世界与真实世界结合起来,那么真实世界是活的,那么虚拟世界也将是活的,这样才能让用户傻傻的分不清现实世界与虚拟世界;本篇我们将加入一些动画(自转/公转)让效果更炫酷,并且对光线进行一些处理,让效果看起来更加真实
正文:
效果展示:
![](https://i-blog.csdnimg.cn/blog_migrate/a68b9f8c646465414c1699de30830f4f.webp?x-image-process=image/format,png)
实现思路:
1.初始化几何节点
2.渲染(图,光线处理)
3.实现-->太阳自转,地球自转,月亮自转
4.根据之间自转与公转关系,处理黄道与白道节点
5.添加光照度看起来更真实
步骤:
1.初始化AR环境必备
@property (nonatomic,strong)ARSCNView *arSCNView;
@property (nonatomic,strong)ARSession *arSession;
@property (nonatomic,strong)ARConfiguration *arSessionConfiguration;
[self.view addSubview:self.arSCNView];
self.arSCNView.delegate = self;
之后懒加载
2.渲染
以太阳节点为例,渲染图
multiply和diffuse这里都设置一下,感觉会真实一点
_sunNode.geometry.firstMaterial.multiply.contents = @"sun";
_sunNode.geometry.firstMaterial.diffuse.contents = @"sun";
multiply (The multiply property specifies a color or an image used to multiply the output fragments with. The computed fragments are multiplied with the multiply value to produce the final fragments. This property may be used for shadow maps, to fade out or tint 3d objects.)
也就是说当我们用这个属性来渲染三维对象的话,会淡化,以太阳为例子,当我们仅仅设置了multiply,显示效果是比较淡的
![](https://i-blog.csdnimg.cn/blog_migrate/82841f89b3f2eca5f257ac7292cdb115.webp?x-image-process=image/format,png)
diffuse(The diffuse property specifies the amount of light diffusely reflected from the surface. The diffuse light is reflected equally in all directions and is therefore independent of the point of view)
diffuse这个属性渲染会均匀扩散到全局,每一个视角,以太阳为例子
![](http://upload-images.jianshu.io/upload_images/4156033-d9adbb0539fcc59b.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
当我们把所有两个渲染属性全部设置,那么效果是不是更加真实呢?
![](https://i-blog.csdnimg.cn/blog_migrate/11dd57c710e29d394c40fdcb038111cb.webp?x-image-process=image/format,png)
wrapS,wrapT,换行模式当我们的太阳转动起来效果就保持原样,看起来真实不会花掉
_sunNode.geometry.firstMaterial.multiply.wrapS =
_sunNode.geometry.firstMaterial.diffuse.wrapS =
_sunNode.geometry.firstMaterial.multiply.wrapT =
_sunNode.geometry.firstMaterial.diffuse.wrapT = SCNWrapModeRepeat;
wrapS从左到右(Determines the receiver's wrap mode for the s texture coordinate. Defaults to SCNWrapModeClamp),wrapT从上到下(Determines the receiver's wrap mode for the t texture coordinate. Defaults to SCNWrapModeClamp),以太阳为例子,假设我们不设置这个属性的话看看效果自转的时候看起来就会很花
![](https://i-blog.csdnimg.cn/blog_migrate/c0f5ae815625057c70f7c06e9b6da17b.webp?x-image-process=image/format,png)
设置地球的反光度,太阳照射到地球上的光泽,反多少光泽出去,并且设置反射出的光是什么颜色的光
_earthNode.geometry.firstMaterial.shininess = 0.1; // 光泽
_earthNode.geometry.firstMaterial.specular.intensity = 0.5; // 反射多少光出去
_moonNode.geometry.firstMaterial.specular.contents = [UIColor grayColor];//反射出去的光是什么光
_moonNode.geometry.firstMaterial.specular.contents = [UIColor redColor];当我们此处换为红色的时候地球反光区域所反射出来的光也就是红色
3.实现-->太阳自转,地球自转,月亮自转
以太阳为例子,我们只需要写一个rotateAnimation,设置动画锁需要的时间,旋转fromValue和toValue,然后设置执行次数,将动画添加到太阳节点上,当然与平面世界不同的是我们需要设施3D世界的旋转fromValue和toValue,代码如下
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"contentsTransform"];
animation.duration = 10.0;
从000的位置扩展//此时图片在不断的拉伸
animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DConcat(CATransform3DMakeTranslation(0, 0, 0), CATransform3DMakeScale(3, 3, 3))];
animation.toValue = [NSValue valueWithCATransform3D:CATransform3DConcat(CATransform3DMakeTranslation(1, 0, 0), CATransform3DMakeScale(5, 5, 5))];
animation.repeatCount = FLT_MAX;
[_sunNode.geometry.firstMaterial.diffuse addAnimation:animation forKey:@"sun-texture"];
4.根据之间自转与公转关系,处理黄道与白道节点
@property(nonatomic, strong)SCNNode * earthGroupNode;//地月节点
我们完成地球与月球自转后,首先来处理月球与地球的公转,把月球的公转节点添加为地月节点的子节点
以月球为例子的公转动画,代码如下
CABasicAnimation *moonRotationAnimation = [CABasicAnimation animationWithKeyPath:@"rotation"];
moonRotationAnimation.duration = 5.0;
moonRotationAnimation.toValue = [NSValue valueWithSCNVector4:SCNVector4Make(0, 1, 0, M_PI * 2)];
moonRotationAnimation.repeatCount = FLT_MAX;
[moonRotationNode addAnimation:moonRotationAnimation forKey:@"moon rotation around earth"];
[_earthGroupNode addChildNode:moonRotationNode];
地球与月球公转完成,此时我们需要去设置一个黄道,然后把地月节点在添加为黄道的子节点.并且实现地球的公转动画
//添加节点地球绕太阳的节点-黄道
SCNNode *earthRotationNode = [SCNNode node];
[_sunNode addChildNode:earthRotationNode];
[earthRotationNode addChildNode:_earthGroupNode];
此时我们展示效果就来了
![](https://i-blog.csdnimg.cn/blog_migrate/9c35823face4b0e583dbc2ea2afb199a.webp?x-image-process=image/format,png)
5.添加光照度看起来更真实
自转与公转完成后,基本的功能也就完成了,添加光照节点太让效果看起来更真实.光照效果随着距离而改变,此时我们就可以看到上文效果展示中的效果了
lightNode.light.attenuationEndDistance = 20.0;
lightNode.light.attenuationStartDistance = 1.0;
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:1];{
lightNode.light.color = [UIColor whiteColor];
_sunHaloNode.opacity = 0.5;
}
_sunHaloNode = [SCNNode node];
[_sunNode addChildNode:_sunHaloNode];
总结:
本章主要难点为公转与自转的关系,各个节点谁是谁的子节点,首先我们先设置地月节点,然后添加黄道,把动画添加在黄道节点,然后再去处理地球与太阳的关系,当然在动画的处理之后,添加光照度与更全面的渲染也是非常重要的
最后为大家献上本文代码地址,我在git中的demo中也写了注释,大家可以仔细看一下demo欢迎大家下载,star (其他demo--关于简单动画)