Unity球形插值Slerp解析
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解析的更多相关文章
- Unity 消息发送机制 解析
该博客,只为解析,解析,解析,已经整理好,已经整理好,已经整理好.代码核心原理套用网上最流行的那一套,也是最常用游戏开发适用的消息机制.这里面加上自己的一些优化,极大的修正(哈哈),实测,没问题.万一 ...
- Unity中用Mono插件解析xml文件
1.解压压缩包,把文件夹拖到脚本文件夹下 Mono是第三方基金会开发的开源的东西,通过Mono基础上开发的程序可以在各个系统下运行.开发语言是C#. 用插件解析比较高效,平台运行稳定.使用简单. Un ...
- Unity骨骼动画资源解析与优化
一,背景 最近发现项目的动画文件有点大,不光内存大,而且文件也很大,所以从这2个方面下手处理 二,动画文件大小优化 为了优化动画文件大小,我们可以先分析下文件,Ctrl+D将动画文件从FBX拷贝出来, ...
- 【Unity】使用JSONObject解析Json
为何要用JSONObject 之前已经用过JsonUtility和Newton.Json来解析Json了,为什么现在又要用一个新的JSONObject来解析Json? 使用JsonUtility:ht ...
- 在Unity中使用LitJson解析json文件
LitJson 这个库需要找资源,找到LitJson.dll后将它放在Assets文件夹下,在脚本中使用using引入即可 测试代码 json文件: {"Archice":[{&q ...
- Unity C# CSV文件解析与加载(已更新移动端处理方式)
在游戏开发过程中,经常要用到Excel编辑各类数据,如果可以直接用Excel支持的文件格式来读取数据,修改将非常便捷. Excel支持导出CSV类型的文件,这类文件不仅可以用Excel直接打开修改,即 ...
- Unity 如何高效的解析数据
昨天和朋友聊天时,他遇到这么一个问题:现在有按照一定格式的数据,例如:#code==text 此处是注释100==确定101==取消key==value 这么个格式的,说白了就是怎样解析这些固定格式字 ...
- Unity3d 插值Lerp与Slerp
Lerp Lerp表示线性插值. Slerp 球形插值在Vector3.Quaternion等类都有使用,一般多在Quaternion的旋转操作时使用.
- Unity Json解析IPA
今天看到一个unity 自带的解析json的IPA,感觉比litjson好用很多,废话不多,上代码 using System.Collections; using System.Collections ...
随机推荐
- HackerRank "Permutation game"
A typical game theory problem - Recursion + Memorized Searchhttp://justprogrammng.blogspot.com/2012/ ...
- 利用maven的filter和profile实现不同环境使用不同的配制
在我们平常的java开发中,会经常使用到很多配制文件(xxx.properties,xxx.xml),而当我们在本地开发(dev),测试环境测试(test),线上生产使用(product)时,需要不停 ...
- jQuery-webcam(.NET)实现WEB摄像头监控
jQuery-webcam是一个非常好用的摄像头监控工具,DEMO可官方下载地址http://www.xarg.org/project/jquery-webcam-plugin/ 1.下载解压后,jq ...
- 删除指定的文件.bat
@echo offattrib -s -h -r /s /d C:\*Thumbs.dbattrib -s -h -r /s /d D:\*Thumbs.dbattrib -s -h -r /s /d ...
- Scala控制抽象
private def filesHere = (new java.io.File(".")).listFiles() def filesEnding(query: String) ...
- sublime好看的字体
真的没想到我这篇博客会成为阅读量最多的,那我就再分享一个字体吧! 字体是:Consolas Italic 代码在下面, 还有sublime也可以设置透明度哦 如果想弄 百度去下个插件就可以了 { &q ...
- 2011-2015年Journal of Mathematical Physics高引用文章
http://aip-info.org/1XPS-45FE9-0AC9S389C5/cr.aspx
- 在单线程中你最好使用ArrayList而不是Vector
<java核心技术卷一>571页上提到Vector类的所有方法都是同步的.可以由两个线程安全地访问同一个Vector对象.显然,如果可以确定我们不会在多个线程中对这个数组进行操作的话,我们 ...
- CLR和JIT
在使用IDE进行编译的时候,这个过程具体的叫法是,使用编译器面向CLR来生成代码.对于不同的开发语言,使用的的编译器也不一样,但是生成的代码都一样. “无论选用哪一个编译器,结果都是一个托管模块.” ...
- Javascript函数声明与函数表达式
在定义函数时,我们一般使用下面这两种方法: 使用函数声明定义: function sum (a, b) { return a + b; } 使用函数表达式定义: var sum = function ...