实现思路

1、扭曲材质赋于面片

2、抓取当前一帧的图片内容

3、获取屏幕坐标

4、利用屏幕坐标对抓取的图片采样

5、再采样张扰动贴图做扭曲

Shader "Unlit/NewUnlitShader"
{
     Properties {
        _DistortTex ("扰动贴图 (RGB)", 2D) = "bump" {}
        _DistortPower ("扭曲强度", Range(0, 0.1)) = 0.05
        _Speed ("扰动速度", Range(0, 5)) = 1
    }
    
    SubShader {
        Tags { "Queue"="Transparent" }
        
        // 抓取屏幕内容
        GrabPass { "_GrabTexture" }
        
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f {
                float4 pos : SV_POSITION;
                float4 grabPos : TEXCOORD0;
                float2 uv : TEXCOORD1;
            };

            sampler2D _GrabTexture;
            sampler2D _DistortTex;
            float _DistortPower;
            float _Speed;

            v2f vert (appdata v) {
                v2f o;
                // 顶点位置变换
                o.pos = UnityObjectToClipPos(v.vertex);
                
                // 计算抓取纹理坐标
                o.grabPos = ComputeGrabScreenPos(o.pos);
                
                // 扰动贴图UV动画(随时间滚动)
                o.uv = v.uv + frac(float2(0, _Time.y * _Speed));
                return o;
            }

            fixed4 frag (v2f i) : SV_Target {
                // 采样扰动贴图
                half2 distort = UnpackNormal(tex2D(_DistortTex, i.uv)).rg;
                
                // 计算偏移量
                float2 offset = distort * _DistortPower;
                
                // 应用偏移到抓取纹理坐标
                i.grabPos.xy += offset;
                
                // 采样抓取纹理
                fixed4 col = tex2Dproj(_GrabTexture, i.grabPos);
                return col;
            }
            ENDCG
        }
    }
}

更多推荐