UnityShader教程_逐帧动画 (转)

帧动画大家应该都不陌生,经常会看到把一个动画几帧的的状态按一定顺序整合在同一张图片上,如下图:



从上图中我们可以看出,这个图片动画一共有20帧,从左到右,从上到下依次排布(基本上都是这个规律).为了展示效果我们需要一个平面来作为模型,Unity里面自带的Panel就可以,不过最终的效果很可能是这个动画是倒着的,因为不清楚Unity自带Panel的顶点UV情况,只能是大家自己手动转一转调到合适的角度观察(如果你会建模的话自己做个平面导到Unity吧)。我们都知道一个贴图具体如何被映射到模型的表面是根据模型定点的UV值来决定的。假设不修改的话,一个平面的左下角的UV是(0,0),右上角是(1,1),那么你直接把这个贴图贴上去的话看到的效果就和上图一样,这显然不是我们想要的。在之前的教程中我们都是直接用模型自带的UV,UV是多少就按照它去到贴图上取对应颜色,这次我们就需要修改了,比如顶点的UV是(1,1)我们也不去贴图的(1,1)位置取。而是根据时间计算出当前播放到第几帧然后算出贴图上相应Sprite(也叫精灵,就是图片上一块一块具体的小图素)的UV位置.按照这个位置取贴图中取出对应颜色即可。千万不要以为模型顶点本身的UV信息变了,其实只是我们把他传递给我们的UV信息加工了一下获取我们想要的位置上的像素。

原理就是这样的,下面我们进行实例代码的分析:



1Shader"Esfog/SpriteUV"2{3Properties4{5_SpriteTex ("SpriteTexture (RGB)", 2D) ="white"{}6_SpriteRowCount ("RowCounts",float) =07_SpriteColumnCount ("ColumnCounts",float) =08_Speed ("AnimationSpeed",Range(0.01,10)) =49}10SubShader11{12Pass13{14Tags {"RenderType"="Opaque"}1516CGPROGRAM17#pragmavertex vert18#pragmafragment frag19#include"UnityCG.cginc"2021uniform sampler2D _SpriteTex;22uniformfloat_SpriteRowCount;23uniformfloat_SpriteColumnCount;24uniformfloat_Speed;2526structVertexOutput27{28float4 pos:SV_POSITION;29float2 uv:TEXCOORD0;30};3132VertexOutput vert(appdata_base input)33{34VertexOutput o;35o.pos =mul(UNITY_MATRIX_MVP,input.vertex);36o.uv =input.texcoord.xy;37returno;38}3940float4 frag(VertexOutput input):COLOR41{42floattotalSpriteCount = _SpriteRowCount *_SpriteColumnCount;43floatrowAvgPercent =1/_SpriteColumnCount;44floatcolumnAvgPercent =1/_SpriteRowCount;45floatSpriteIndex = fmod(_Time.y *_Speed,totalSpriteCount);46SpriteIndex =floor(SpriteIndex);47floatcolumnIndex =fmod(SpriteIndex,_SpriteColumnCount);48floatrowIndex = SpriteIndex /_SpriteColumnCount;49rowIndex = _SpriteRowCount -1-floor(rowIndex);50float2 spriteUV =input.uv;51spriteUV.x = (spriteUV.x + columnIndex) *rowAvgPercent;52spriteUV.y = (spriteUV.y + rowIndex) *columnAvgPercent;53float4 col =tex2D(_SpriteTex,spriteUV);54returncol;55}5657ENDCG58}59}60FallBack"Diffuse"61}



和之前一样,有一部分内容在之前的教程中已经提过了,不再赘述。

第5~8行,在Shader的属性部分,我们定义了用来存放动画图片的_SpriteTex.用来存放这个动画图片上一共有几行图素的_SpriteRowCount.存放图片上一共有几列图素的_SpriteColumnCount.以及控制动画播放速度的_Speed.其中_Speed应用了一种新的属性类型Range(x,y).这个属性会在材质球的Inspector面板上创建一共Slider滑块,他会返回一共滑块所处位置的float值.最左端为x,最右端为y.用户可以直接拖动,十分方便。

第42~44行,大家从代码可以看到VertexOutput和vert函数都很简单,因为我们的内容都在frag函数里呢,totalSpriteCount用来存放动画图片上精灵图素的总数量(一共有多少帧).rowAvgPercent用来存放在一行中一个精灵图素在横向上占得比例,因为一张图片的左下角是uv的(0,0),右上角是(1,1)。所以也可以认为是横向上每一个图素占得uv比例。从现在开始大家要注意代码中的row和column.有时候是代表横纵有的有时候却是代表纵横.不要被我搞晕了.我也觉得很别扭啊。这里的_SpriteColumnCount是我们之前定义的一共有几列,所以1/_SpriteColumnCount就是我们要的一行中每个图素占得比例了。columnAvgPercent同理。

第45~46行,因为我们是逐帧动画,就是一帧一帧的播放,那么必须记录当前播放在第几帧了,SpriteIndex就是用来干这个的。后面有个看上去比较陌生的表达式,其中_Time是一个Unity为我么提供的float4变量,_Time.y分量代表的就是游戏开始以后流逝的时间(s).关于_Time的更多解释可以查看unity的帮助文档中关于Shader内置变量的内容。而后面乘以一个_Speed是我们用来调节播放速度的,如果_Speed = 1那么我们就是1秒1桢的速度播放动画,如果_Speed = 2就是1秒2帧的速度播放。而整个fmod(_Time.y * _Speed,totalSpriteCount)其中fmod(x,y)是x对y取余。因为我们的动画是循环播放的,而且序号是从0开始计算的,所以整个取余操作可以根据当前的时间和播放速度来确定播放到第几帧了,并且是循环播放。因为是两个浮点数取余,余数可能含有小数位。而我们具体播放到第几帧是不可能为小数的.所以我们用floor函数对结果进行下取整,为什么不用上取整呢,大家自己思考一下吧。

第47~49行,这一步中,我们要去根据播放到第几帧去计算出相应图素在整个图素矩阵中的第几列第几行。这个我想大家上大学的时候一定见过很多了。其中SpriteIndex / _SpriteColumnCount用当前第几帧除以总列数就可以得到当前播放的图素处在第几行(从0开始算).而fmod(SpriteIndex,_SpriteColumnCount)用当前帧数对总列数取余得到当前图素处在第几列,为什么这次我们不需要对fmod结果进行取余呢,大家再思考一下吧。最后我们又对得到的rowIndex先进行了下取整,然后又用(总行数-1)去减去他得到结果,其中取整是因为第48行中的rowIndex是由两个浮点数相除而来,结果可能包含小数位。而用(_SpriteRowCount-1)去减它,是因为图片的UV原点是在左下角的那么我们算出来的第几行实际上是从下往上数的,这显然与我们期望的相反,而又由于行数是从0开始算的所以我们用(总行数-1)减去原来的rowIndex就能得到我们想要的图素在第几行了(从下往上数)。

第50行~53行,创建一个spriteUV并赋予原始的uv信息,然后我们开始对整个原始uv进行加工了,先对uv信息的x方向值进行加工,(spriteUV.x + columnIndex) * rowAvgPercent可以拆除spriteUV.x*rowAvgPercent + columnIndex*rowAvgPercent.加号左边是相当于我们把原来的uv.x(0~1)缩放到(0~rowAvgPercent),也就是一行图素中第一个图素所占的横向上的uv比例。实际上现在这个位置就相当于每一行中的第一个图素,而加号右面的值实际上是我们相对于把刚才计算出来的uv当做一个基地址然后加上这个偏移,一个图素在横向上占rowAvgPercent这么多的uv比例,那么他处在第columnIndex列所以就是说他相对于加号左面的基础位置偏移了(columnIndex*rowAvgPercent)这么多的uv比例。可能比较绕,大家好好想一想就明白了。后面spriteUV.y同理。最后用我们加工后的spriteUV作为新的UV值去贴图中取出相应的颜色返回就可以了。

(~ o ~)~系列教程的第六篇到此结束了,这篇的内容比较基础,就是解释起来比较绕,我也有段时间没写了,有些生疏了。还望大家见谅。日后会再接再厉,多多分享。现在都凌晨一点了,明天还要上班,希望大家有所收获吧。由于这个效果是动态的为了展示效果本人能力不足,只能用截图软件一帧一帧截屏然后合成成gif展示一下了.由于截图大小参差不齐,所以播放起来晃来晃去的。大家将就着看吧。洗洗睡了~~


转自,原文地址http://www.cnblogs.com/Esfog/p/4088597.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,376评论 25 707
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,456评论 6 30
  • 我愿做一头猪,只会吃饭睡觉的猪……
    一滴水的微笑阅读 117评论 1 0
  • 目录 上一章 在东方慧租住的这间两居室中,另一个卧室内住着的就是方小琼,她们住在一起已经很多年了。她们共同承担着...
    小静读童书阅读 1,364评论 3 6
  • 天怒: 骄阳罩顶晒似火, 夜半醒来犹觉热, 偷问天公为何怒, 概因地球人太作。 毁山废地绿太少, 沥青水泥路面多,...
    云之憾阅读 123评论 2 1