签到领奖

[再来一次] UnityShader学习笔记(二) 让贴图纹理动起来(河流瀑布特...

[复制链接]
查看: 3939|回复: 7
排名
401
昨日变化
发表于 2017-1-11 11:59:38 | 显示全部楼层 |阅读模式
       大家好,我是Zander。这一章我们将使用纹理贴图实现动画、混合和真实特效来达到理想的效果。
       纹理贴图可以使我们的着色器快速的实现逼真的效果,但是如果添加的纹理贴图过多,会非常影响游戏性能,特别是在移动设备上,需要将纹理贴图的数目降到最小,这样才能使应用程序加载更快,运行起来更加流畅。
      下面带着大家用图片来实现一个河流的效果:
     
       首先创建一个材质和一个新的着色器文件。为着色器添加属性如下:
[AppleScript] 纯文本查看 复制代码
Properties {
		_MainTint ("Diffuse Tint", Color) = (1,1,1,1)
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_ScrollXSpeed ("X Scroll Speed",Range(0,10)) = 2
		_ScrollYSpeed ("Y Scroll Speed",Range(0,10)) = 2
	}
      然后在SubShader中修改CGPROGRAM部分的CG属性,添加变量便于访问
[AppleScript] 纯文本查看 复制代码
	fixed4  _MianTint;[/size][/font][/color][/align]		fixed   _ScrollXSpeed;
		fixed   _ScrollYSpeed;
		sampler2D _MainTex;
     修改surf()函数,通过tex2D()函数来改变UV坐标,然后使用内置的_Time变量来实现动态纹理
[AppleScript] 纯文本查看 复制代码
void surf (Input IN, inout SurfaceOutputStandard o) 
		{
		    //创建一个变量 存储图片UV
		    fixed2 scrolledUV  = IN.uv_MainTex;

			//创建临时变量存储 X Y 
			fixed xScrollValue  = _ScrollXSpeed * _Time;
			fixed yScrollValue  = _ScrollYSpeed * _Time;

			//计算X Y 的偏移
			scrolledUV += fixed2(xScrollValue,yScrollValue);

			half4 c = tex2D(_MainTex,scrolledUV);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
所用的贴图



运行Unity,就可以看到河流的效果了
全部代码如下:
[AppleScript] 纯文本查看 复制代码
Shader "Custom/TexSurfaceShader" {
	Properties {
		_MainTint ("Diffuse Tint", Color) = (1,1,1,1)
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_ScrollXSpeed ("X Scroll Speed",Range(0,10)) = 2
		_ScrollYSpeed ("Y Scroll Speed",Range(0,10)) = 2
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		// Physically based Standard lighting model, and enable shadows on all light types
		#pragma surface surf Standard fullforwardshadows

		// Use shader model 3.0 target, to get nicer looking lighting
		#pragma target 3.0

		fixed4  _MianTint;
		fixed   _ScrollXSpeed;
		fixed   _ScrollYSpeed;
		sampler2D _MainTex;

		struct Input {
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutputStandard o) 
		{
		    //创建一个变量 存储图片UV
		    fixed2 scrolledUV  = IN.uv_MainTex;

			//创建临时变量存储 X Y 
			fixed xScrollValue  = _ScrollXSpeed * _Time;
			fixed yScrollValue  = _ScrollYSpeed * _Time;

			//计算X Y 的偏移
			scrolledUV += fixed2(xScrollValue,yScrollValue);

			half4 c = tex2D(_MainTex,scrolledUV);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}

接下来 我们来进一步扩展 。来实现一个类似于2D序列帧动画的效果。

   
首先准备一张序列帧的图,

创建一个新的材质 和一个shader,
在新的着色器中添加属性:
[AppleScript] 纯文本查看 复制代码
Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_TexWidth("Sheet Width",float)=0.0
		_CellAmout("Cell Amount",float) = 0.0
		_Speed("Speed",Range(0.01,32)) = 12
	}
修改Surf()函数里面的内容:
[AppleScript] 纯文本查看 复制代码
void surf (Input IN, inout SurfaceOutputStandard o) 
		{
		    float2 spriteUV  = IN.uv_MainTex; //将输入的UV值存储到临时变量

			float cellPixelWidth  = _TexWidth/_CellAmout; //得到每个精灵的宽度
			float cellUVPercentage = cellPixelWidth/_TexWidth ;  //计算每个精灵在整张图中的百分比

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

			float xValue  = spriteUV.x;

			//计算精灵在X方向上UV偏移量
			xValue += cellUVPercentage * timeVal * _CellAmout;  
			xValue *= cellUVPercentage;

			spriteUV = float2(xValue,spriteUV.y);
			// Albedo comes from a texture tinted by color
			fixed4 c = tex2D (_MainTex, spriteUV) ;
			o.Albedo = c.rgb;
		
			o.Alpha = c.a;
		}
里面用到的两个数学函数:
函数描述
fmod(x,y)返回x/y的余数,符号同x。如果y为0,结果不可预料
ceil(x)对输入参数向上取整
全部代码如下:

[AppleScript] 纯文本查看 复制代码
Shader "Custom/SpriteAnimationShader" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_TexWidth("Sheet Width",float)=0.0
		_CellAmout("Cell Amount",float) = 0.0
		_Speed("Speed",Range(0.01,32)) = 12
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		// Physically based Standard lighting model, and enable shadows on all light types
		#pragma surface surf Standard fullforwardshadows

		// Use shader model 3.0 target, to get nicer looking lighting
		#pragma target 3.0


		sampler2D _MainTex;
		fixed  _TexWidth;
		fixed   _CellAmout;
		fixed   _Speed;


		struct Input {
			float2 uv_MainTex;
		};



		void surf (Input IN, inout SurfaceOutputStandard o) 
		{
		    float2 spriteUV  = IN.uv_MainTex; //将输入的UV值存储到临时变量

			float cellPixelWidth  = _TexWidth/_CellAmout; //得到每个精灵的宽度
			float cellUVPercentage = cellPixelWidth/_TexWidth ;  //计算每个精灵在整张图中的百分比

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

			float xValue  = spriteUV.x;

			//计算精灵在X方向上UV偏移量
			xValue += cellUVPercentage * timeVal * _CellAmout;  
			xValue *= cellUVPercentage;

			spriteUV = float2(xValue,spriteUV.y);
			// Albedo comes from a texture tinted by color
			fixed4 c = tex2D (_MainTex, spriteUV) ;
			o.Albedo = c.rgb;
		
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}


好了,这一章就写到这,欢迎大家加入QQ群:280993838 。或者关注我的公众号


免费评分

参与人数 1泰斗币 +50 收起 理由
里斯 + 50 很给力!

查看全部评分

+1
1321°C
7
  • 里斯
  • nham123
  • 墨麟
  • kx88
  • Yaochilong
过: 他们
楼主热帖
5武林高手
1396/2000
排名
223
昨日变化
发表于 2017-1-11 15:20:21 | 显示全部楼层
看了LZ的帖子,我只想说一句很好很强大!
发表于 2017-1-11 17:32:20 | 显示全部楼层
gdfgsfd dfgsdfg sg sfdgdfs gfdsg fdsg fdg dg s  sgh
2武林新丁
112/200
排名
374
昨日变化
发表于 2017-1-12 09:34:26 | 显示全部楼层
看了LZ的帖子,我只想说一句很好很强大!
3江湖小虾
353/500
排名
23
昨日变化
发表于 2017-1-13 00:22:47 | 显示全部楼层
看了LZ的帖子,我只想说一句很好很强大!
2武林新丁
137/200
排名
613
昨日变化
1
发表于 2017-1-13 15:19:56 | 显示全部楼层
顶顶顶顶顶顶顶顶顶顶
排名
1004
昨日变化
发表于 2017-1-17 11:46:50 | 显示全部楼层
游戏资源哪里好,大神推荐泰斗找。
[发帖际遇]: 铁蛋儿 你天天对暗恋妹纸三笑留情,这是 6 泰斗币以表彰你的吊丝精神. 幸运榜 / 衰神榜
3江湖小虾
339/500
排名
139
昨日变化
发表于 2017-2-17 09:42:04 | 显示全部楼层
你们大神真会玩。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /3 下一条

在线客服(工作时间:9:00-22:00)
010-82609395
泰斗社区公众号

Copyright   ©2015-2016  【泰斗社区】-专注互联网游戏和应用的开发者平台  Powered by©Discuz!  技术支持:迪恩网络     ( 沪ICP备14023207号-9 )