UnityShader學習筆記(七) 讓貼圖紋理動起來(河流瀑布特效、精靈序列幀實現)

       大家好,我是Zander。這一章我們將使用紋理貼圖實現動畫、混合和真實特效來達到理想的效果。

       紋理貼圖可以使我們的着色器快速的實現逼真的效果,但是如果添加的紋理貼圖過多,會非常影響遊戲性能,特別是在移動設備上,需要將紋理貼圖的數目降到最小,這樣才能使應用程序加載更快,運行起來更加流暢。

      下面帶着大家用圖片來實現一個河流的效果:

     

       首先創建一個材質和一個新的着色器文件。爲着色器添加屬性如下:

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屬性,添加變量便於訪問

 

                fixed4  _MianTint;
		fixed   _ScrollXSpeed;
		fixed   _ScrollYSpeed;
		sampler2D _MainTex;
     修改surf()函數,通過tex2D()函數來改變UV座標,然後使用內置的_Time變量來實現動態紋理

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,就可以看到河流的效果了

全部代碼如下:

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,

在新的着色器中添加屬性:

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()函數裏面的內容:

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) 對輸入參數向上取整
全部代碼如下:


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 。或者關注我的公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章