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. 《JavaScript权威指南》读书笔记(三)

    日期:2015-12-05 浏览器location和history: replace不会显示历史,location会: history对象脚本不能真正访问,但支持三种方法:back().foward( ...

  2. C语言指针(一)

    一.指针 定义指针变量 指针指向的数据类型 *指针变量名称; 例: int *p; *作用: 1.在定义变量的时候 * 是一个类型说明符,说明定义的这个变量是一个指针变量 2.在不是定义变量的时候 * ...

  3. 采用SHELL,通过SQL LOAD导入一定格式的txt文件至数据库中

    1. 准备工作,window中可直接通过sqlload直接导入文件,linux下,需要有sqlload的相关软件. 2. SQL脚本(MID_DFDZ.ctl) LOAD DATA INTO TABL ...

  4. 转:Linux 安装 Mysql

    前段时间安装了Mysql,但是有些问题,就想把他卸载了,重新安装一个,但是没想到在Linux卸载软件是一个很痛苦的事情.   我的Mysql是用命令的方式安装的,就是上一篇文章用到的那个命令(sudo ...

  5. 编程思考 PetShop读后感

    标准,插拔式的设计思想建立一致的标准是通向“复用”的通道.分层,使其得到的充分的独立.一个东西如果独立了[不是孤立],这个事物就具有很强大的力量,这个和一个人的成长是相同的道理.所以呢,在写程序的过程 ...

  6. hdu 4627 The Unsolvable Problem

    http://acm.hdu.edu.cn/showproblem.php?pid=4627 分类讨论一下就可以 代码: #include<iostream> #include<cs ...

  7. ASP.NET MVC学习之路由篇(3)

    根据路由输出链接 既然是网站开发自然少不了链接,我们已经学会了强大的路由,但是还缺少一步就是能够将这些路由的路径输出到页面,下面我们就开始学习如何输出路由路径. 首先我们的路由注册部分如下所示: 1 ...

  8. windbg调试C#代码(二)

    这篇主要讲如何分析高内存和高CPU. 1.如何分析高内存 注:如果抓Dump的同时,刚好在执行GC,抓出来的Dump执行命令多半会出错,用!VerifyHeap也能验证Dump有误,这种情况只能重新抓 ...

  9. 【STL】-迭代器的用法

    初始化: list<char>::iterator pos; 算法: 1. 遍历 for(pos = col1.begin(); pos != col1.end(); ++pos){... ...

  10. IT公司100题-5-查找最小的k个元素

    问题描述: 输入n 个整数,输出其中最小的k 个. 例如输入8, 7, 6, 5, 4, 3, 2, 1这8 个数字,则最小的3 个数字为3, 2, 1.   分析: 时间复杂度O(nlogn)方法: ...