Unity球形插值,官方有个太阳升降的例子:

http://docs.unity3d.com/ScriptReference/Vector3.Slerp.html

一开始主观认为这个球形插值Slerp应该本来就是两点之间画弧线,貌似很简单,但该官方例子实现太阳升降却写得很复杂,虽没几行代码却不明白做了些什么事- -

向量即既有长度同时有方向,看介绍可以知道,相比线性插值Lerp将Vector3当作空间的点,球形插值Slerp则是将Vector3当作方向,返回的Vector3的长度是两点之前的距离插值,方向是两个向量之间的夹角度数的插值。

注意这里的“夹角度数”,我觉得理解这个夹角度数比较重要,不然仅仅靠Slerp是在两向量之间做距离插值的同时也对方向做插值还是不太好理解Slerp的最终效果会是个什么样的弧线。

为了能形象的理解Slerp是怎样在做“插值”,我将每一帧的状态都以图形的方式画在了场景中,代码如下,仅仅在官方代码基础上增加了画图功能:

 void Start ()
{
startTime = Time.time;
DrawLine (sunrise.position, Color.red);
DrawLine (sunset.position, Color.cyan);
StartCoroutine (UpdateLine ());
} IEnumerator ShowSlerp ()
{
while (Vector3.Distance (transform.position, sunset.position) > 0.05f)
{
Vector3 center = (sunrise.position + sunset.position) * 0.5F;
DrawLine (center, Color.yellow);
yield return null;
center -= new Vector3 (, , );
DrawLine (center, Color.gray);
yield return null; Vector3 riseRelCenter = sunrise.position - center;
DrawLine (riseRelCenter, Color.green);
yield return null;
Vector3 setRelCenter = sunset.position - center;
DrawLine (setRelCenter, Color.blue);
yield return null; float fracComplete = (Time.time - startTime) / journeyTime;
transform.position = Vector3.Slerp (riseRelCenter, setRelCenter, fracComplete);
DrawLine (transform.position, Color.magenta);
yield return null;
transform.position += center;
DrawLine (transform.position, Color.white);
yield return null;
}
}

暂停然后一帧一帧运行即可看到效果,如下图,请将线条颜色对应代码行查看(其中曲线运动轨迹不是官方代码,未帖进上面代码中):

这样代码逻辑就显而意见了:原本是在红向量与浅蓝(蓝绿)向量间做Slerp,转变为绿向量与蓝向量间做Slerp,从而产生紫(品红)向量尾部相连的运动轨迹,最终再形成类似太阳升降的白向量尾部相连的曲线运动轨迹。

至此基本明白Slerp代码之外的其他代码的作用了:sunrise与sunset两向量如果共线则直接做Slerp运动是水平方向的曲线!由于这两个点并未指定初始值而是用户可以任调整的值,所以说做这些多就只是为了将任意值的起点与终点作偏移使得运动轨迹初终能更符合太阳升降的曲线。

当看到绿蓝向量间做Slerp运动可以形成紫向量那样的运动轨迹时,可能有的童鞋也可以猜到了,只要两条向量间的夹角不是180度,Slerp的结果就不会是水平方向的弧线。看下图:

上面那条曲线即是将起点和终点向量稍微上移之后直接进行Slerp运动时的轨迹。可见相比直接Slerp,转换过后的曲线弯曲程度也得到了调节更符合太阳升起降落的轨迹。

由此知道两向量直接进行Slerp球形插值时是能直接产生一个曲线弧形的轨迹,不同位置的向量可以产生不同面上的弧形,在两向量位置固定不可变时可以像官方例子这样调整两向量获得中间向量再Slerp。

官方代码说明到此结束,至此Slerp为什么被称作球形插值也就明白了,看下图:

当两向量长度相同时,Slerp的结果即是两向量所在球形表面两点之间的弧线!

如此,当两向量为180度水平共线时为什么会形成水平方向的弧形了也就很显然了,因为两点所在球面上的弧线本来就是这样一条弧线。

Unity球形插值Slerp解析的更多相关文章

  1. Unity 消息发送机制 解析

    该博客,只为解析,解析,解析,已经整理好,已经整理好,已经整理好.代码核心原理套用网上最流行的那一套,也是最常用游戏开发适用的消息机制.这里面加上自己的一些优化,极大的修正(哈哈),实测,没问题.万一 ...

  2. Unity中用Mono插件解析xml文件

    1.解压压缩包,把文件夹拖到脚本文件夹下 Mono是第三方基金会开发的开源的东西,通过Mono基础上开发的程序可以在各个系统下运行.开发语言是C#. 用插件解析比较高效,平台运行稳定.使用简单. Un ...

  3. Unity骨骼动画资源解析与优化

    一,背景 最近发现项目的动画文件有点大,不光内存大,而且文件也很大,所以从这2个方面下手处理 二,动画文件大小优化 为了优化动画文件大小,我们可以先分析下文件,Ctrl+D将动画文件从FBX拷贝出来, ...

  4. 【Unity】使用JSONObject解析Json

    为何要用JSONObject 之前已经用过JsonUtility和Newton.Json来解析Json了,为什么现在又要用一个新的JSONObject来解析Json? 使用JsonUtility:ht ...

  5. 在Unity中使用LitJson解析json文件

    LitJson 这个库需要找资源,找到LitJson.dll后将它放在Assets文件夹下,在脚本中使用using引入即可 测试代码 json文件: {"Archice":[{&q ...

  6. Unity C# CSV文件解析与加载(已更新移动端处理方式)

    在游戏开发过程中,经常要用到Excel编辑各类数据,如果可以直接用Excel支持的文件格式来读取数据,修改将非常便捷. Excel支持导出CSV类型的文件,这类文件不仅可以用Excel直接打开修改,即 ...

  7. Unity 如何高效的解析数据

    昨天和朋友聊天时,他遇到这么一个问题:现在有按照一定格式的数据,例如:#code==text 此处是注释100==确定101==取消key==value 这么个格式的,说白了就是怎样解析这些固定格式字 ...

  8. Unity3d 插值Lerp与Slerp

    Lerp Lerp表示线性插值. Slerp 球形插值在Vector3.Quaternion等类都有使用,一般多在Quaternion的旋转操作时使用.

  9. Unity Json解析IPA

    今天看到一个unity 自带的解析json的IPA,感觉比litjson好用很多,废话不多,上代码 using System.Collections; using System.Collections ...

随机推荐

  1. Python-While刷博爬虫

    仅用于测试 #!/usr/bin/python import webbrowser as web import time import os url = 'www.abc.com' while Tru ...

  2. POI按照源单元格设置目标单元格格式

    原文:http://jjw198874.blog.163.com/blog/static/1889845522011102401854234/ POI按照源单元格设置目标单元格格式 poi按照一个源单 ...

  3. SVN switch 用法详解

    一直知道SVN有个switch命令,但是对它的介绍教程却很少,大多是生硬的svn帮助文档里的文字,从而一直不怎么会用.今天看了这篇文章,突觉豁然开朗,整理下来以备查阅. 使用SVN,自然是需要与别人合 ...

  4. Metro 应用无法打开解决办法

    1.恢复默认UAC设置: 2.恢复自带防火墙服务启动类型为自动: 3.设置IE为默认浏览器(搜索和应用中): 4.如有可能使用Microsoft帐户,而不是本地帐户(仅使用有限的几个Metro应用): ...

  5. Bellman-Ford & SPFA 算法——求解单源点最短路径问题

    Bellman-Ford算法与另一个非常著名的Dijkstra算法一样,用于求解单源点最短路径问题.Bellman-ford算法除了可求解边权均非负的问题外,还可以解决存在负权边的问题(意义是什么,好 ...

  6. i标签和em标签的区别

    很多人以为i标签和em标签都只是HTML用于斜体的标签,并不知道他们有什么区别. 其实对于熟悉SEO的人来说,他们的区别挺大的(普通用户略过). i标签的作用:仅仅是为了让字体显示斜体,对于SEO没什 ...

  7. 黄聪:使用WORDPRESS自带AJAX方法

    例如给网站每页logo后面的一句名言,点击“换一条”就会ajax动态加载一条,使用了wordpress的自带ajax方法.下面介绍如何使用wordpress自带ajax方法: 1.在header.ph ...

  8. 黄聪:手机移动站Web响应式开发工具Viewport Resizer插件(360浏览器、谷歌Chrome浏览器兼容)

    插件作用: 移植自@MalteWassermann的脚本,一个可以测试响应式布局的chrome扩展. 插件截图: 插件下载地址(需FQ): https://chrome.google.com/webs ...

  9. C#学习笔记五: C#3.0Lambda表达式及Linq解析

    最早使用到Lambda表达式是因为一个需求:如果一个数组是:int[] s = new int[]{1,3,5,9,14,16,22};例如只想要这个数组中小于15的元素然后重新组装成一个数组或者直接 ...

  10. SparkSQL的解析详解

    SparkSQL继承自Hive的接口,由于hive是基于MapReduce进行计算的,在计算过程中大量的中间数据要落地于磁盘,从而消耗了大量的I/O,降低了运行的效率,从而基于内存运算的SparkSQ ...