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 ...
随机推荐
- [转] matlab figure最大化
http://blog.163.com/yinhexiwen@126/blog/static/6404826620122942057214/ % figure 窗口最大化,坐标轴也随着窗口变大而相应变 ...
- mvc checked=\"checked\"
<input id="IsDiscount" type="checkbox" @(Model != null && Model.IsDis ...
- lucene 区分大小写 问题以及解决方案
转自:http://blog.csdn.net/huaishu/article/details/8543236 本文介绍lucene区分大小的原因,和解决方案.关于lucene大小写敏感问题我总结一下 ...
- CentOS 7.0系统安装配置图解教程
转自:http://www.osyunwei.com/archives/7829.html 操作系统:CentOS 7.0 64位 IP地址:192.168.21.128 网关:192.168.21. ...
- Visual Assist 生成注释功能
在Visual Studio环境中编码,Visual Assist是不可缺少的好工具.这工具功能非常强大,以前仅仅用到了代码提示,今天学习了生成注释功能,非常爽. 在代码编辑器中点击右键弹出菜单,在“ ...
- 【WP之一】]独立存储
介绍: 提供一个磁盘存储空间,他是一种虚拟的文件系统,能存储小量的数据:在默认的情况下,它只能存储1MB的文件.根据使用方式及功能的不同,独立存储空间又包含两部分:独立设置存储和独立文件存储.除非卸载 ...
- (WPF) MVVM: DataGrid Binding
Binding到DataGrid的时候,需要用到ObservableCollection. public ObservableCollection<Customer> Customers ...
- BigDecimal的equals
BigDecimal testA = new BigDecimal(79); BigDecimal testB = new BigDecimal("79.00"); System. ...
- HTTP Get请求URL最大长度
各浏览器HTTP Get请求URL最大长度并不相同,几类常用浏览器最大长度及超过最大长度后提交情况如下: IE6.0 :url最大长度2083个字符,超过最大长度后无法提 ...
- 打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问该文件夹
打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问 在win98,winme,win2000,win2003下都能正常上传文件夹,但在winxp+sp2下同样的文件夹就可能出现问题 1. 打开 ...