Unity3D ShaderLab 模拟精灵动画

在上一篇,介绍了通过Shader 模拟纹理运动,那么更深一步讲,我们也可以把帧动画的精灵纹理运动通过shader实现。

虽然大家都是在游戏脚本中做更高一级的控制。但是有钱就是任性,码代码的也可以码任性啊,我们就来试试做精灵的运动动画,遍历播放每一帧。

首先呢,准备一个精灵的动画序列帧,没有的找度娘要。然后创建一个新的材质球和新的着色器。然后把准备好的序列帧图拖动到材质的纹理上。

不用多说,_MainTex ("Base (RGB)", 2D) = "white" {},就传递了我们设置好的帧图。

接下来,还要通过Properties来创建动画的数量 速度等。

1:add>

Properties {

_MainTex ("Base (RGB)", 2D) = "white" {}

_TexWidht("Image Width",float)=

_SpriteSize("Sprite Size",float)=

_Speed("Sprite Speed",Range(0.01,))=

}

上面声明的3个对象,同时也要在SubShader的CGPROGRAM下原样申明;

2:add>

sampler2D _MainTex;

float _TexWidht;

float _SpriteSize;

float _Speed;

然后我们要把输入的uv值存入独立的变量,保证在代码中的使用。

3:add>

void surf (Input IN, inout SurfaceOutput o) {

//uv值存入spriteuv;

float2 spriteUV = IN.uv_MainTex;

//计算单元格的百分比;

float pixeWidth = _TexWidht/_SpriteSize;

float uvPercentage = pixeWidth/_TexWidht;

float timeVal = fmod(_Time.y*_Speed,_SpriteSize);

timeVal = ceil(timeVal);

//计算sprite x方向上的偏移;

float xValue = spriteUV.x;

xValue+=uvPercentage*timeVal*_SpriteSize;

xValue*=uvPercentage;

//刷新uv值;

spriteUV = float2(xValue,spriteUV.y);

//传递新的uv值;

half4 c = tex2D (_MainTex, spriteUV);

o.Albedo = c.rgb;

o.Alpha = c.a;

}

保存代码,回到编辑器中预览吧。

通过上面的逻辑实现,我们不难看出我们首先从input结构体中获得到了uv值,把他存入到变量spriteUV 中,这个变量同时包含了uv的x和y坐标。

接下来,我们获得在gui面板中传入的纹理宽度TexWidht和精灵数量SpriteSize,通过这两个纹理的参数获得了每一个sprite的宽度和每一个sprite在uv中所占的比例值,

这个比例值uvPercentage 表示我们的sprite从上一个精灵单元格到下一个精灵单元格的uv偏移量。

最后,我们通过计算时间递增获得了最新的偏移值,在计算过程中用到了fmod()和ceil()函数。

最终我们得到了当前的uv值,传递给tex2D()函数,这样我们的sprite就像播放动画一样动起来;

fmod(x,y):返回x/y的余数,符号同x。y不可为0!

ceil(x):对输入参数向上取整,直到其值等于SpriteSize他就从新归0;

上面我们使用了x方向上的uv偏移,同理也可以加入y方向的uv偏移。从而满足更大的精灵表单循环。

code start-------------------------------------------------

Shader "91YGame/BasicSpriteAni" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_TexWidht("Image Width",float)=
_SpriteSize("Sprite Size",float)=
_Speed("Sprite Speed",Range(0.01,))=
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD CGPROGRAM
#pragma surface surf Lambert sampler2D _MainTex;
float _TexWidht;
float _SpriteSize;
float _Speed; struct Input {
float2 uv_MainTex;
}; void surf (Input IN, inout SurfaceOutput o) {
//uv值存入spriteuv;
float2 spriteUV = IN.uv_MainTex;
//计算单元格的百分比;
float pixeWidth = _TexWidht/_SpriteSize;
float uvPercentage = pixeWidth/_TexWidht; float timeVal = fmod(_Time.y*_Speed,_SpriteSize);
timeVal = ceil(timeVal);
//计算sprite x方向上的偏移;
float xValue = spriteUV.x;
xValue+=uvPercentage*timeVal*_SpriteSize;
xValue*=uvPercentage;
//刷新uv值;
spriteUV = float2(xValue,spriteUV.y);
//传递新的uv值;
half4 c = tex2D (_MainTex, spriteUV);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

code end---------------------------------------------------

Unity3D ShaderLab 模拟精灵动画的更多相关文章

  1. Unity3D ShaderLab 模拟纹理运动

    Unity3D ShaderLab 模拟纹理运动 这一篇,我们要说到着色器上的uv贴图的滚动效果,这样的场景可以用在河流,瀑布,熔岩等效果.算是创建纹理动画的基础技术之一. 所以 准备一个新的着色器文 ...

  2. Unity3D NGUI Sprite精灵动画

    NGUI 2.6.1下载: part1 part2 NGUI 实现Sprite精灵动画很简单: 1.先制作图像集合.打开NGUI菜单下Atlas Maker,选中切好的图片,点击Add/Update按 ...

  3. Unity3D ShaderLab BRDF模拟

    Unity3D ShaderLab BRDF模拟 在上一篇,说到了使用渐变纹理着色,使用一个值来控制纹理的uv坐标,但是这也就表示我们只能得到一个线性的光照效果. 那么我们能不能通过观察方向的向量结合 ...

  4. 时光煮雨 Unity3D实现2D人物动画① UGUI&Native2D序列帧动画

    系列目录 [Unity3D基础]让物体动起来①--基于UGUI的鼠标点击移动 [Unity3D基础]让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoT ...

  5. Unity3D ShaderLab 简单的立方体图反射

    Unity3D ShaderLab 简单的立方体图反射 反射是着色器模拟现实环境的一个关键因素,它能使我们的着色器渲染效果更加具备视觉冲击,因为他利用了我们周围的环境, 让着色器反射外界的场景信息并将 ...

  6. Unity3D ShaderLab 各向异性高光

    Unity3D ShaderLab 各向异性高光 各向异性时一种模拟物体表面沟槽方向性的高光反射类型,它会修改或延伸垂直方向上的高光.当我们想模拟金属拉丝高光的时候,它非常适合.下面就一步一步实现. ...

  7. Unity3D ShaderLab法线贴图

    Unity3D ShaderLab法线贴图 说到法线贴图,应该算是我们最常使用的一种增强视觉效果的贴图.将法线贴图的各个像素点座位模型的法线,这样我们的光照可以模拟出高分辨率的效果, 同时也保持较低的 ...

  8. 原创:CSS3技术-雪碧图自适应缩放与精灵动画方案

    花了一个礼拜完成了慕课网定制的七夕主题效果,其中有一个没实现好的功能,就是雪碧图的自适应缩放 ps: 以下实现都是基于移动端的处理 原图如下: 人物是采用的是雪碧图,通过坐标绝对数据取值 问题很明显, ...

  9. 利用pixi.js制作精灵动画

    CSS Sprites 技术对于广大的前端工程师来说应该是一点也不陌生.国内开发者昵称为CSS精灵,通过一定的技术手段,让精灵动起来,我称其为精灵动画,那么目前有哪些实现方式 呢?下面让我们详细的聊聊 ...

随机推荐

  1. BZOJ1029: [JSOI2007]建筑抢修(贪心)

    题目链接:BZOJ1029: [JSOI2007]建筑抢修 题解:贪心思想,按结束时间从小到大排序,选花费时间尽量短的建筑维修,用堆维护. #include<stdio.h> #inclu ...

  2. Objective-C(二、类和对象)

     类和对象 #import是include的升级版,可以自动防止重复包含,所以注意:大家以后在引入头文件的时候都使用import Foundation是一个框架,Foundation.h是Founda ...

  3. 【转】Session ID/session token 及和cookie区别

    Session + Cookie  知识收集! cookie机制采用的是在客户端保持状态的方案.它是在用户端的会话状态的存贮机制,他需要用户打开客户端的cookie支持.cookie的作用就是为了解决 ...

  4. php变量与数组相互转换的方法(extract与compact

    #php变量与数组相互转换的方法(extract与compact) #compact 多个变量转数组 $name = 'sui'; $email = 'sui@qq.com'; $arr = comp ...

  5. DB2存储过程语法规则

    如何声明一个存储过程CREATE PROCEDURE 存储过程名(IN 输入变量名 输入变量类型,OUT 输出变量名 输出变量类型)紧跟其后的是存储过程属性列表            常用的有:LAN ...

  6. "数学口袋精灵"bug的发现

    团队成员的博客园地址: 曾治业:http://www.cnblogs.com/zzy999/ 陈焕恳:http://www.cnblogs.com/4249ken/ 蓝叶:http://www.cnb ...

  7. USB鼠标按键驱动

    现象:把USB设备接到PC 1. 右下角弹出"发现android phone" 2. 跳出一个对话框,提示你安装驱动程序 问1. 既然还没有"驱动程序",为何能 ...

  8. Linux 常用命令杂记

    移动光标:h:向左移动j:向下移动k:向上移动l:向上移动 与window 光标移动键功能一致. 常用命令行:shift + ^ 行首shift + $ 行尾ctrl + v 可视模式 , 选择一个范 ...

  9. SQL 插入日期时间 变量值

    --看看吧^^ CREATE TABLE #temp ( test datetime ) go --SQL: INSERT #temp SELECT 1.1 UNION ALL GO --SQL: I ...

  10. UINavigationController 子控制器管理原理

    UINavigationController 显示在导航控制器上的控制器 永远是栈顶控制器 后进先出  先进后出原则 /** * 程序获得焦点才能获取触摸事件 * */- (void)applicat ...