当前位置: 首页 > news >正文

animation unity 速度_[Unity+shader]无限循环背景的制作

9655a6d236f29d3527ecda7d18975cbc.png

slideshow Effect 2d更新了新版本,之前讲到的没有收录的效果已经都收录进去了。

老用户可以更新,新用户有兴趣可以支持一下。临近放假,犯懒不想写太长的文,毕竟画图也比较费劲,所以今天讲一下比较简单的内容。


制作无限循环背景的方法已经基本可以说是众所周知,就是在移动一张图片的时候,在边缘使用同样的图片来补充。在unity中,可以用非常直观的方法来实现。

首先准备一张四方连续的图片,如果只需要在一个方向滚动,那么而方连续也没问题。设置图片的import setting,将wrap mode设为repeat,之后将其作为标准材质的贴图,添加一个animation,让Offset的值从0到1变化就完成了。

6c1522a2ad64e5f7b2db6ff23d79d806.png

b18d15a8732981b7e206f7c4a63f872c.png

9bd280459f7a58dda6c481d2286cfb85.gif
一个最基础的循环滚动背景,如果让offset的x和y都从0到1的变化,就可以做成向斜上方移动的效果了。

然而这样做毕竟显得不那么高级,用来单独写一篇文章总归是不行的。于是我们照例先声明几个property,来设定图片滚动方向以及处于循环中的位置。

	Properties {
		_MainTex ("Main Texture", 2D) = "black" {}
		_Rotation("Rotation",  Range(0,360)) = 0.0				
		[Space(10)]
		_Progress("Progress", Range(0,1))=0
	}

为了方便直观,角度的值使用了0~360范围。

接下来在vert函数中根据角度和progress,计算当前帧里uv偏移的量。

由于对于整个图片来说,同一帧里所有位置的uv偏移量是一样的,所以这一计算可以在vert函数里进行。

		v2f vert(appdata_img v) {
			v2f o;
			o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
			float Rot = _Rotation * (3.1415926f/180.0f);
			float s = sin(Rot);
			float c = cos(Rot);
			o.uvTA=v.texcoord +fixed2(s,c)*_Progress ;
			return o;
		}

e08c6548d00aad6fb3ec722590485418.png
rotation是0的时候,原本uv.y是0的位置的逐渐向1靠近,结果就是,图片看起来逐渐向下滚动了。

由于vert函数中只对uv进行了操作,在frag函数中只需要根据偏移后的uv绘制贴图即可。

			return  tex2D(_MainTex, i.uvTA).rgba ;

看一下效果~:

ae4a6f7ad03b5f9453cbfbfda2de8222.gif

19e36fb54214e837b5b1728f5da8da57.gif

水平和竖直方向都很好的达到了我们想要的效果,但是当给rotation一个自由的角度时,问题出现了

e45add05d0a77155673e30834ace591a.gif
当角度是30°时,progress的值是0和1时并不能呈现出同样的偏移效果

看来这是由角度和偏移的计算方法导致的。在旋转一个角度后,x或y的方向的偏移量可能并不是一个整数,或者是贴图最小重复单元的整数倍数。

1b86821f3509d45d94189409e2e5f0ef.png
在rotation是0或90的倍数时,由于fixed2(s,c) 是整数而不会显现出问题

如果希望让progress为0和1时计算出的偏移量相同,可以分别定义x和y两个方向的速度。此速度是以偏移的倍数为单位的。

		_SpeedX("speedX",  Range(0,5)) = 1.0		
		_SpeedY("speedY",  Range(0,5)) = 1.0	

在计算uv时,也将x和y两个方向分别计算。

	o.uvTA=(v.texcoord) +fixed2(_SpeedX,_SpeedY)*_Progress ;

9656d5376491312df0249cb70a4ea55a.png
当speedx=2,speedy=1的时候,progress从0到1的过程跨越的是横向两倍纵向一倍的贴图大小

这回再看一下效果,问题解决了!

732442561bf629cf1f8bc2f1e7da351d.gif
加上了一个cell变量,来表示最小的循环单元的大小,在贴图上包含重复元素的时候比较方便使用

在贴图取色走马灯这一章中,我们有讲到系统时间 _Time的使用。

saku一只松鼠:[Unity+shader]从贴图中采样取色的走马灯​zhuanlan.zhihu.com
f11aac6205d4d8f579f3e9d9ee48f5d3.png

在制作贴图循环滚动效果的时候,同样可以使用这个东西。

首先声明几个property,来设定图片滚动的速度和方向。

	Properties {
		_MainTex ("Main Texture", 2D) = "black" {}		
		_Speed("speed",  Range(0,3)) = 1.0		
		_Rotation("Rotation",  Range(0,360)) = 0.0	//为了方便直观,角度的值使用了0~360范围	
	}

接下来我们要做的,就是根据角度和速度,计算当前帧里uv偏移的量。

关于unity内置的一些时间函数,可以阅读: https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html

		v2f vert(appdata_img v) {
			v2f o;
			o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

			float Rot = _Rotation * (3.1415926f/180.0f);
			float s = sin(Rot);
			float c = cos(Rot);
			o.uvTA=(v.texcoord)*_MainTex_ST.xy+fixed2(s,c)*(_Time.y * _Speed) -_MainTex_ST.zw;
			return o;
		}

与在 贴图中采样取色的走马灯这一章中略有不同,如果使用_SinTime的话,会得出不太一样的效果。

269ea64b4c779fa71c0b8e3ad249ed12.gif
单纯将time替换成sintime,就会成这个摇摇摆摆的样子

这里有个小小的缺陷:由于_Time给出的是从运行开始到现在所经过的时间,所以计算出的是从运行到当前时间的总的偏移量。也就是说,如果在运行途中更改了rotation的话,是下一帧的偏移量会直接跳到新计算出的值,而不会有平滑过渡的效果。

9fee05d7da340158d2c51757c7fd0b16.gif
转了角度之后一跳一跳的,虽然可能在实际应用中没多大影响

要解决这一缺陷,可以使用增加一个脚本的方法,将从运行开始累积的偏移量保存在脚本中,然后在每一帧都将新的偏移量传递到材质里。

在shader中增加两个变量,分别代表x和y方向的偏移。由于这两个值在使用的时候不需要被看到或手动修改,不必把它加入到properties里。

		float _uvx,_uvy;

在物体上新建一个脚本,由于每一帧的偏移量变化在脚本中实现,所以需要添加rotation和speed两个变量到脚本中,同时,shader里的rotation和speed就可以去掉了。

using UnityEngine;
public class tutLoopBG : MonoBehaviour {

	Material material;
	Vector2 offsetuv;

	[SerializeField,Range(0,360)]
	float rotation;
	[SerializeField]
	float speed;
	void Start () {
		if (gameObject.GetComponent<Renderer> () && material==null) {
			material = gameObject.GetComponent<Renderer> ().sharedMaterial;
			offsetuv=new Vector2(0,0);
		}	
	}
	void Update () {
		float s = Time.deltaTime* speed*Mathf.Sin (rotation * Mathf.Deg2Rad);
		float c = Time.deltaTime* speed*Mathf.Cos (rotation * Mathf.Deg2Rad);
		offsetuv.x += s;
		offsetuv.y += c;
		material.SetFloat ("_uvx", offsetuv.x);
		material.SetFloat ("_uvy", offsetuv.y);
	}
}

这里,首先在start函数中获取到当前物体上的材质,以备后用。在每次update时,使用deltatime计算偏移量与上一帧之间的变化,累加在offsetuv中。之后将累计过的偏移量传递给材质。

在shader的vert函数中,只需要加上最终的偏移量即可。

	o.uvTA=(v.texcoord*_MainTex_ST.xy-_MainTex_ST.zw)+fixed2( _uvx,_uvy);

7a38711edd28bb435ead225a08836105.gif
这下好了!

当然还有另一种方法:

		material.SetVector ("_MainTex_ST",new Vector4(1,1,offsetuv.x,offsetuv.y));

这里Vector4(1,1,offsetuv.x,offsetuv.y)的四个数值即xy方向的tilling与xy方向的offset。直接对贴图的tilling and offset进行赋值,这样就可以将_uvx,_uvy省略掉了。


这章所用到的资源在这里获取:

sakuraplus/make-terrain-with-google-elevation​github.com

获取更多特效,Buy me a coffee:

Asset Store​u3d.as

前几章讲到的内容已经在版本1.2中得到了更新。

相关文章:

  • gmt时间转换格式 js_《Vue系列》timeago.js将时间戳转换成“几天前”“几分钟前”等格式...
  • 接收对象数组_分享一些数组对象常用的API
  • 加了版本号会报错_新手常见的python报错及解决方案
  • 飞思卡尔芯片k66单片机溢出_PWM 初试溢出中断
  • 水卡修改金额_【技术分享】关于IC卡,水卡修改控制位教程
  • excel导出多重表头utils_java excel复杂表头和复杂数据导出
  • 程序异常退出的原因_Python异常处理详解(基础篇十一)
  • h5显示今天的时间_试驾红旗H5!红旗品牌卖得最火的车型,开起来究竟咋样?...
  • 雷迪9000使用说明_雷迪司UPS监控软件使用说明
  • libsvm python_LibSVM for Python 使用
  • 列表输出循环左移_Java Note-数据结构(3)列表
  • mysql 远程日志_将syslog ng日志写入MySQL(远程)数据库
  • mysql npe问题_万恶的 NPE 如何避免,几种你必须知道的方案!!!
  • dubbo monitor mysql_dubbox 的各种管理和监管
  • mysql传入Bean_mysql 表映射为java bean 手动生成。
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • ESLint简单操作
  • JavaScript的使用你知道几种?(上)
  • python docx文档转html页面
  • Redux系列x:源码分析
  • Sublime text 3 3103 注册码
  • Unix命令
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • Xmanager 远程桌面 CentOS 7
  • 第2章 网络文档
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # 计算机视觉入门
  • #pragma pack(1)
  • (4)事件处理——(7)简单事件(Simple events)
  • (C语言)fgets与fputs函数详解
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)ObjectiveC 深浅拷贝学习
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .Net 代码性能 - (1)
  • .NET框架设计—常被忽视的C#设计技巧
  • .Net语言中的StringBuilder:入门到精通
  • .NET中的Exception处理(C#)
  • .pop ----remove 删除
  • @Autowired和@Resource的区别
  • @JSONField或@JsonProperty注解使用
  • []T 还是 []*T, 这是一个问题
  • [Android View] 可绘制形状 (Shape Xml)
  • [BZOJ 4598][Sdoi2016]模式字符串
  • [C++][基础]1_变量、常量和基本类型
  • [C++打怪升级]--学习总目录
  • [DAU-FI Net开源 | Dual Attention UNet+特征融合+Sobel和Canny等算子解决语义分割痛点]
  • [JavaScript] JavaScript事件注册,事件委托,冒泡,捕获,事件流
  • [JDK工具-2] javap 类文件解析工具-帮助理解class文件,了解Java编译器机制
  • [leveldb] 2.open操作介绍
  • [luogu P1527]矩阵乘法(矩形k小)