renderings
principle
Ideas Let's first transfer the model space to the world space.
At this time, subtract the world coordinates of the model vertices from the coordinates of the small ball, so that the distance from each vertex in the model to the small ball can be obtained
Then interpolate the distance through the variable, and add the offset to the original model vertex
Specific steps
parameter definition
Properties
{
_MainTex ("Texture", 2D) = "white" {}
//物体的y坐标上限
_TopY("Top Y", Float) = 0
//物体的y坐标下限
_BottomY("Bottom Y", Float) = 0
//控制条
_Control("Control Squash", Range(0, 2)) = 0
//黑洞坐标
_BlackHolePos("Position of the Black Hole", Vector) = (0, 0, 0, 1)
}
Vertex function
The core idea is to get the different interpolation values of the distance between the model vertex and the center point of the ball through the control of _Control, and then add this value to the original model offset.
v2f vert (appdata v)
{
v2f o;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
float3 toBlackHolePos = mul(unity_WorldToObject, (_BlackHolePos - worldPos)).xyz;
float normalizedDist = GetNormalizedDist(worldPos.y);//对所有顶点的Y坐标进行归一化
float val = max(0, _Control - normalizedDist);
v.vertex.xyz += toBlackHolePos * val;
//模型顶点
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
Fragment function
clip filters the part that exceeds the black hole
fixed4 frag (v2f i) : SV_Target
{
//clip(x) Discards the current pixel, if any component of x is less than zero.
//过滤超过黑洞的部分
clip(_BlackHolePos.y - i.worldPos.y);
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}