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. LeetCode "Binary Tree Vertical Order"

    BFS + HashTable class Solution { int maxl, minl; unordered_map<int, vector<int>> hm; pub ...

  2. ASP.NET MSSQL 依赖缓存设置方法

    更多的时候,我们的服务器性能损耗还是在查询数据库的时候,所以对数据库的缓存还是显得特别重要,上面几种方式都可以实现部分数据缓存功能.但问题是我们的数据有时候是在变化的,这样用户可能在缓存期间查询的数据 ...

  3. [git]Git与Repo入门

    转自:http://www.cnblogs.com/angeldevil/archive/2013/11/26/3238470.html 注:非常推荐的一篇关于git的博文 目录: 版本控制 一.原始 ...

  4. 如何缩短SQL Server 的启动时间

    将/nosplash添加到SQLServer Manageement Studio的快捷方式可以缩短启动时间.为此,右击SSMS快捷方式(位于你的桌面上.start菜单中或任务栏中)并选择Proper ...

  5. visual studio 声明数组太大,导致栈溢出

    在解释原因前我们先看一下一个由C/C++编译的程序占用的内存分为几个部分: 1.栈区(stack segment):由编译器自动分配释放,存放函数的参数的值,局部变量的值等.在Windows下,栈是向 ...

  6. Android SDK的docs访问速度很慢(新)

    #设置环境变量 名称:ANDROID_SDK_HOME 值:我的为-->E:\android\android-sdk #代码编译及运行 1.把下面的代码保存为:AndroidDocRepair. ...

  7. 黄聪:Mysql数据库还原备份提示MySQL server has gone away 的解决方法(备份文件数据过大)

    使用mysql做数据库还原的时候,由于有些数据很大,会出现这样的错误:The MySQL Server returned this Error:MySQL Error Nr. MySQL server ...

  8. [运维-服务器 – 2A] – nginx下绑定域名

    这个篇文章今天(2016-01-21)才有幸写了,因为自己对nginx部署以前没玩过,还得感谢下我们数字化的总经理.在这里记录下自己成长的经验,与遇到的问题. 因为自己的域名是在万网上买的,解析无法直 ...

  9. codeforces 439 E. Devu and Birthday Celebration 组合数学 容斥定理

    题意: q个询问,每一个询问给出2个数sum,n 1 <= q <= 10^5, 1 <= n <= sum <= 10^5 对于每一个询问,求满足下列条件的数组的方案数 ...

  10. wamp

    安装好wamp,但是图片没有变绿,大部分原因是80端口被占用. 修改端口号:可以从文件httpd.conf 将# Change this to Listen on specific IP addres ...