In this blog, i am gonna use vertex normal to animate different meshes. This Bulge in and out animations in games can be used to highlight an object in the scene or for any other purpose. This can be achieved using shader by just shifting each vertex of the mesh along its normal and bringing back.
Each vertex has its own normal which is passed onto the vertex shader. This normal calculation of each mesh is automatically calculated by any 3D software. All we have to do is take that normal information for each vertex in Vertex input and animate, in vertex shader.
Hm, now that you know what are we gonna achieve, lets look into how?
Analyse this equation:
vertex = vertex + (normal * sin(_Time.y))
This equation shifts each vertex of a mesh, along its normal, periodically(sin wave).
_Time is the variable given by unity to animate vertices/Fragments with respect to time. It stores the time value from the start of the scene.
Initially at 0th second, as sin(0) = 0, vertex doesn't shift. As time passes, sin value increases up to 1 and the vertex keep shifting up. And then when sin value gradually decreases,the vertices keep shifting down. This create a "bulge in and out" animation for our mesh.
To further have complete control over that animation, Lets modify the above equation:
vertex = vertex + (normal * sin(_Time.y * speed)) * Amplitude)
Here by writing this equation as shown we have have more control over speed and amplitude of the bulge animation.
Code:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "ShaderLearning/Normals/JellyFishHead"
{
Properties
{
_Color("Main Color", Color) = (1,1,1,1)
_Texture("Basic Texture", 2D) = "white" {}
_Frequency("Frequency of flag wave", float) = 0
_Amplitude("Amplitude of flag wave", float) = 0
_Speed("Speed of flag wave", float) = 0
}
Subshader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform half4 _Color;
uniform sampler2D _Texture;
uniform float4 _Texture_ST;
uniform float _Frequency;
uniform float _Amplitude;
uniform float _Speed;
struct vertexInput
{
float4 vertex: POSITION;
float4 texcoorda: TEXCOORD0;
float4 normal: NORMAL;
};
struct vertexOutput
{
float4 pos : SV_POSITION;
float4 texcoorda: TEXCOORD0;
};
float4 BulgeAnimation(float4 vertex, float4 normal)
{
vertex += (normal) * (sin(_Time.y * _Speed) * _Frequency) * _Amplitude;
return vertex;
}
vertexOutput vert(vertexInput v)
{
vertexOutput o;
v.vertex = BulgeAnimation(v.vertex, v.normal);
o.pos = UnityObjectToClipPos(v.vertex);
o.texcoorda.xy = v.texcoorda + _Texture_ST.wz;
return o;
}
half4 frag(vertexOutput i) : COLOR
{
return tex2D(_Texture,i.texcoorda) * _Color.rgba;
}
ENDCG
}
}
}
Comentarios