6.Vertex Functions
-
取顶点颜色:顶点实际上也可以包含颜色信息(默认材质一般不会显示),在vert()函数中可以从appdata_full中提取出来,并在surf()函数中使用它
-
定义input结构 struct Input { float2 uv_MainTex; float4 vertColor; };
-
在vert()函数中提取
void vert(inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input,o);
o.vertColor = v.color;
} -
在surf()函数中使用
void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = IN.vertColor.rgb * _MainTint.rgb;
}
-
取到的颜色是float4类型的,说明alpha值也是有效的
-
-
顶点wave动画
-
vert()
-
使用sin()函数获取一个波动的值(_Time作为变量),存在顶点颜色中
float time = _Time * _Speed;
float waveValueA = sin(time + v.vertex.x *** _Frequency**) * _Amplitude;
o.vertColor = float3(waveValueA,waveValueA,waveValueA);
-
使顶点向y方向位移一段,并修改法线方向,使效果更真实
v.vertex.xyz = float3(v.vertex.x, v.vertex.y + waveValueA, v.vertex.z);
v.normal = normalize(float3(v.normal.x + waveValueA, v.normal.y, v.normal.z));
-
-
surf()
-
使用顶点颜色在ColorA和B间插值,得到最终显示效果
float3 tintColor = lerp(_ColorA, _ColorB, IN.vertColor).rgb;
o.Albedo = c.rgb * (tintColor * _tintAmount);
o.Alpha = c.a;
-
-
书中默认效果很丑,把_Frequency调小之后会有不错的波浪效果
-
-
挤出模型
-
没啥好说的,顶点xyz往法向自增一个值,字面意义上的挤出,_Amount值为负就会往里缩
vert():
v.vertex.xyz += v.normal * _Amount;
-
改进:如果将_Amount值存在一张纹理图上(或者a通道上),可以实现控制哪些部分挤压何种程度
float extrusion = tex.r * 2 - 1;
乘2减一的意思是:tex的r值范围在0-0.5向内挤压,0.5不动,0.5-1向外挤压
-
-
实现雪景
-
改变颜色:法线方向接近于向上(_SnowDirection)的三角形绘制为白色
o.Normal = UnpackNormal(tex2D(_Bump, IN.uv_Bump))
if(dot(WorldNormalVector(IN, o.Normal), _SnowDirection.xyz) >= _Snow)//是雪
o.Albedo = _SnowColor.rgb;
else o.Albedo = c.rgb * _Color
WorldNormalVector是为了把模型的法线方向转换到世界坐标系
-
挤压积雪部分:在vert()中做类似的判断(法向点乘_SnowDirection,若正交为0;若几乎平行则接近1或-1)
由于执行vert()时还没有surf()中的SurfaceOutputStandard,不能直接用WorldNormalVector计算(无o.Normal),改用
float4 sn = mul(UNITY_MATRIX_IT_MV, _SnowDirection) //代替o.Normal
if (dot(v.normal, sn.xyz) >= _Snow)//是雪
v.vertex.xyz += (sn.xyz + v.normal) * _SnowDepth * _Snow;//向法向挤压模型,造成积雪效果
-
-
体积爆炸效果
-
挤压模型vert():使用一张噪声纹理和时间参数来进行顶点位移
float3 disp = tex2Dlod(_NoiseTex, float4(v.texcoord.xy,0,0));
float time = sin(_Time[3] *_Period + disp.r*10);
v.vertex.xyz += v.normal * disp.r * _Amount * time
disp:噪声纹理采样 time:用时间作参数的sin函数取得
-
改变颜色surf():使用在噪声纹理中取得的值在斜坡纹理上随机取得
float3 noise = tex2D(_NoiseTex, IN.uv_NoiseTex);//取噪声
float n = saturate(noise.r + _RampOffset);//_RampOffset使得n总体向一个方向偏移,saturate函数:使结果在0-1间
clip(_ClipRange - n);//剪切像素,负值时不绘制
half4 c = tex2D(_RampTex, float2(n,0.5));//最终得到的颜色
-