Unity Shaders学习笔记之通过修改UV坐标实现纹理贴图的滚动

Posted 程序员小毛驴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Shaders学习笔记之通过修改UV坐标实现纹理贴图的滚动相关的知识,希望对你有一定的参考价值。

一、简介

  纹理贴图可以使我们的着色器更有生命力,而且可以快速地实现非常逼真的效果。然而略显遗憾的是,你需要小心翼翼地控制用于着色器地纹理贴图的数目,因为如果添加的纹理图片过多,会非常影响游戏的性能。于是我们可以通过修改UV坐标实现纹理贴图的滚动,使用这种技术实现如瀑布,河流,熔岩流等效果

二、准备工作

  创建一个新的着色器文件和一个新的材质。这样,我们就创建一个简介漂亮的着色器,我们可以使用它来研究滚动效果。

三、如何操作

  首先,打开刚才创建的着色器文件,然后输入下面提到的代码  1.该着色器需要两个新的属性,我们可以用来控制纹理滚动的速度。因此,我们将添加x方向的速度属性和y方向的速度属性,如下代码所示:
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
	

2.修改位于CGPROGRAM部分的CG属性,添加两个新的属性变量便于以后访问
fixed4 _MainTint;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
sampler2D _MainTex;

3.修改surf()函数,通过tex2D()函数来改变UV坐标。然后使用内置的_Time变量来实现动态纹理,当我们点击Unity播放按钮时纹理会随时间动起来
void surf (Input IN, inout SurfaceOutput o) 
		
			
			fixed2 scrolledUV = IN.uv_MainTex;
			fixed xScrollValue = _ScrollXSpeed * _Time;
			fixed yScrollValue = _ScrollYSpeed * _Time;
			scrolledUV += fixed2(xScrollValue, yScrollValue);
			half4 c = tex2D (_MainTex, scrolledUV);
			o.Albedo = c.rgb * _MainTint;
			o.Alpha = c.a;
		

下图展示了使用滚动UV系统为你的环境创建一个简单河流运动的效果图



四、实现原理

  这套纹理滚动系统首先需要声明两个属性,使着色器的使用者能够提高或降低纹理的滚动速度。它的作用在于我们可以从材质Inspector面板中获取浮点值,然后传递给着色器里的surf函数。在程序的开始,我们首先将UV值存储在scrolledUV变量中。这个变量必须是一个float2或fixed2类型的变量,因为UV值是通过Input结构体传入的:

struct Input 

     float2 uv_MainTex;
;

 这样,当访问网格的UV时,我们可以使用滚动速度变量和内置的_Time变量对纹理进行便宜。该内置变量返回的是float4类型的值,这意味着当我们进入游戏时,变量的每个组成部分都包含不同的时间值。

    _Time变量为我们提供一个基于Unity游戏时钟的递增型浮点值。因此,我们可以使用该事件值在UV方向上移动我们的UV值,也可以通过滚动速度变量来加快或减慢时间。

     fixed xScrollValue = _ScrollXSpeed * _Time;
     fixed yScrollValue = _ScrollYSpeed * _Time;


  使用时间计算出正确的偏移量后,我们就可以添加新的偏移值到原有UV值上。这也是我们在下一行使用+=运算符的原因。我们要把原来的UV值,加上新的偏移量,然后传递给tex2D()函数作为新的UV纹理。这样我们就创建了一个物体表面的纹理运动效果。由于我们只对UV坐标进行修改,所以这些是模拟的纹理运动效果。

scrolledUV += fixed2(xScrollValue, yScrollValue);
half4 c = tex2D (_MainTex, scrolledUV);

五、全部代码

Shader "liulongling/ScrollingUVs" 
	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
		#pragma surface surf Lambert

		fixed4 _MainTint;
		fixed _ScrollXSpeed;
		fixed _ScrollYSpeed;
		sampler2D _MainTex;

		struct Input 
		
			float2 uv_MainTex;
		;

		void surf (Input IN, inout SurfaceOutput o) 
		
			
			fixed2 scrolledUV = IN.uv_MainTex;
			fixed xScrollValue = _ScrollXSpeed * _Time;
			fixed yScrollValue = _ScrollYSpeed * _Time;
			scrolledUV += fixed2(xScrollValue, yScrollValue);
			half4 c = tex2D (_MainTex, scrolledUV);
			o.Albedo = c.rgb * _MainTint;
			o.Alpha = c.a;
		
		ENDCG
	 
	FallBack "Diffuse"



本文参考了《Unity Shaders and Effects Cookbook》一书,感谢原书作者提供的学习资料

以上是关于Unity Shaders学习笔记之通过修改UV坐标实现纹理贴图的滚动的主要内容,如果未能解决你的问题,请参考以下文章

Unity Shaders学习笔记之表面着色器

Unity Shaders学习笔记之为创建Half Lambert光照模型

Unity Shaders学习笔记之为创建自定义慢反射光照模型

Unity Shaders学习笔记——SurfaceShaderBasicDiffuse和HalfLambert

Unity Shaders学习笔记——渲染管线

Unity Shaders学习笔记——SurfaceShader认识结构