您的位置:首页 > 移动开发 > Unity3D

UnityShader学习笔记(七) 让贴图纹理动起来(河流瀑布特效、精灵序列帧实现)

2017-01-11 12:07 507 查看
       大家好,我是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 。或者关注我的公众号:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息