UnityShader学习笔记(二) 让贴图纹理动起来(河流瀑布特效、精灵序列帧实现)
发表于2017-01-22
大家好,我是Zander。这一章我们将使用纹理贴图实现动画、混合和真实特效来达到理想的效果。
纹理贴图可以使我们的着色器快速的实现逼真的效果,但是如果添加的纹理贴图过多,会非常影响游戏性能,特别是在移动设备上,需要将纹理贴图的数目降到最小,这样才能使应用程序加载更快,运行起来更加流畅。
下面带着大家用图片来实现一个河流的效果:
首先创建一个材质和一个新的着色器文件。为着色器添加属性如下:
1 2 3 4 5 6 | 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 } |
1 2 3 4 | fixed4 _MianTint; fixed _ScrollXSpeed; fixed _ScrollYSpeed; sampler2D _MainTex; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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,就可以看到河流的效果了
全部代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 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" } |
首先准备一张序列帧的图,
创建一个新的材质 和一个shader,
在新的着色器中添加属性:
1 2 3 4 5 6 | 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 } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 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" } |