Unity Shader inhales black hole effect

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;
}

Source code download

おすすめ

転載: blog.csdn.net/st75033562/article/details/129688811