unity内置时间变量:
_Time float4 t是自该场景加载开始所经过的时间 (t/20,t.2t.3t)
_SinTime t是时间的正弦值 (t/8,t/4,t/2,t)
_CosTime t是时间的余弦值(t/8,t/4,t/2,t)
unity_DeltaTime dt是时间增量 (dt,dt/2,smoothDt,1/smoothDt)
纹理动画
序列帧动画
顶点着色器中完成顶点变换与定点纹理坐标存储到v2f中,片元着色器中,Time.y为加载该场景所用的时间,将Time.y与speed相乘模拟时间,并用floor函数取整,得到的time值除以行数得到行的索引,余数为列所欲i你,将原uv按行列数进行等分,在进行偏移得到子图像的纹理坐标。
vert:
v2f vert (a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
farg:
fixed4 frag (v2f i) : SV_Target {
float time = floor(_Time.y * _Speed);
float row = floor(time / _HorizontalAmount);
float column = time - row * _HorizontalAmount;
// half2 uv = float2(i.uv.x /_HorizontalAmount, i.uv.y / _VerticalAmount);
// uv.x += column / _HorizontalAmount;
// uv.y -= row / _VerticalAmount;
half2 uv = i.uv + half2(column, -row);
uv.x /= _HorizontalAmount;
uv.y /= _VerticalAmount;
fixed4 c = tex2D(_MainTex, uv);
c.rgb *= _Color;
return c;
}
滚动的背景
多个层模拟视差效果
_ScrollX/2X,表示两张纹理各自的水平移动速度,_Mulitipiler参数用于控制整体亮度。顶点着色器完成坐标变换以及将纹理坐标存储uv,使用内置时间函数与速度相乘的小数部分实现水平方向纹理的移动,frag中采样两张纹理后用第二张纹理的透明度进行插值,完成对他们的混合,最终结果×亮度。
frac函数表示取小数部分
v2f vert (a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex) + frac(float2(_ScrollX, 0.0) * _Time.y);
o.uv.zw = TRANSFORM_TEX(v.texcoord, _DetailTex) + frac(float2(_Scroll2X, 0.0) * _Time.y);
return o;
}
fixed4 frag (v2f i) : SV_Target {
fixed4 firstLayer = tex2D(_MainTex, i.uv.xy);
fixed4 secondLayer = tex2D(_DetailTex, i.uv.zw);
fixed4 c = lerp(firstLayer, secondLayer, secondLayer.a);
c.rgb *= _Multiplier;
return c;
}
顶点动画
流动河流
Tags中设置DisableBatching表示是否实现批处理,使用批处理模型各自的模型空间就会丢失,如果需要各个物体在各自的模型空间下对顶点位置进行偏移就需要将其取消。
广告牌
广告牌技术会根据视角方向来旋转一个纹理着色的多边形,使得多边形看起来好像总是面对摄像机,被用于很多应用如烟雾、云朵、闪光效果等。
本质是要构建旋转矩阵,使用表面法线向量、向上的方向向量以及向右的方向向量,并且指定一个锚点在旋转中保持不变。需求不同,构建的三个相互正交的基向量不同,在计算时一般固定法线或向上的向量中的某一个,如模拟草丛时,希望向上的方向固定,法线方向随视角变化,二模拟粒子效果希望法线固定,总是指向视角方向,向上的方向可以变化。这样叉乘就可以得到另一个,将结果与固定的向量叉乘得标准化的另一个,就获得了标准正交基。
_VerticalBillboarding用于调整是固定法线还是固定向上的向量,约束垂直方向的程度,subshader标签中 为透明效果需要设置:Queue=Transparent, IgnoreProjector=True,RenderType=Transparent,额外需要DisableBatching=True避免批处理让物体失去各自的模型空间信息。
frag中只需采样后再与颜色值相乘。
Shader "Shaders/Animation/Billboard"
{
Properties {
_MainTex ("Main Tex", 2D) = "white" {}
_Color ("Color Tint", Color) = (1, 1, 1, 1)
_VerticalBillboarding ("Vertical Restraints", Range(0, 1)) = 1
}
SubShader {
// Need to disable batching because of the vertex animation
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True"}
Pass {
Tags { "LightMode"="ForwardBase" }
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
fixed _VerticalBillboarding;
struct a2v {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (a2v v) {
v2f o;
// Suppose the center in object space is fixed
float3 center = float3(0, 0, 0);
float3 viewer = mul(unity_WorldToObject,float4(_WorldSpaceCameraPos, 1));
float3 normalDir = viewer - center;
// If _VerticalBillboarding equals 1, we use the desired view dir as the normal dir
// Which means the normal dir is fixed
// Or if _VerticalBillboarding equals 0, the y of normal is 0
// Which means the up dir is fixed
normalDir.y =normalDir.y * _VerticalBillboarding;
normalDir = normalize(normalDir);
// Get the approximate up dir
// If normal dir is already towards up, then the up dir is towards front
float3 upDir = abs(normalDir.y) > 0.999 ? float3(0, 0, 1) : float3(0, 1, 0);
float3 rightDir = normalize(cross(upDir, normalDir));
upDir = normalize(cross(normalDir, rightDir));
// Use the three vectors to rotate the quad
float3 centerOffs = v.vertex.xyz - center;
float3 localPos = center + rightDir * centerOffs.x + upDir * centerOffs.y + normalDir * centerOffs.z;
o.pos = UnityObjectToClipPos(float4(localPos, 1));
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
fixed4 c = tex2D (_MainTex, i.uv);
c.rgb *= _Color.rgb;
return c;
}
ENDCG
}
}
FallBack "Transparent/VertexLit"
}
取消批处理可能会影响性能。