water drop effect on umbrella

water drop effect on umbrella



foreword

The effect of water droplets on an umbrella is quite interesting

1. Actual effect

insert image description here

Second, the actual principle

1. General principle

The water drop effect is actually an application of uv coordinate offset and scaling.
The general principle is the source texture coordinates, plus the water drop texture coordinates to sample the effect of the main texture.
We need to figure out the texture coordinates of the water droplets. It is the result of our source texture coordinate offset and scaling.

2. Practical operation

Let's first use the after-screen effect as an example, which is more intuitive.
insert image description here
This is the effect of directly sampling the screen texture, which is also our source scene, and a panel is directly placed in the middle of the screen.

 fixed4 frag (v2f i) : SV_Target
            {
    
                                   
                float2 _uv = i.uv;                   
                fixed4 col = tex2D(_MainTex, i.uv );  
                return fixed4( col.rgb, 1);
            }

Next, we start to generate the uv coordinates of the water droplets.
We encapsulate the function Rains() to get it.

 fixed2 Rains(fixed2 uv) {
    
    
            
                float2 retVal  = float2(0.0,0.0);
                float aspectRatio = 4.0;//雨滴的宽高比 
                float tileNum = 5;//平铺数量                             
                uv *= fixed2(tileNum * aspectRatio,tileNum);//栅格化uv             
                uv = frac(uv);                    
                retVal = float2(uv);
                return retVal;
            }
             fixed4 frag (v2f i) : SV_Target
            {
    
                                   
                float2 _uv = i.uv;     
  
                float2 rainUV = float2(0.,0.); 
                
                rainUV = Rains(_uv*2.32);

                fixed4 col = tex2D(_MainTex, i.uv + rainUV);  
                return fixed4( col.rgb, 1);
                }

insert image description here
Our y-axis gets the dynamic effect
uv.y += _Time.y * 0.0618 through the time coefficient;
insert image description here

Add the irregular effect of water droplets floating up and down
insert image description here

 fixed2 Rains(fixed2 uv) {
    
    
            
                 float period = 5;//雨滴在格子中循环的周期
                float2 retVal  = float2(0.0,0.0);
                float aspectRatio = 4.0;//雨滴的宽高比 
                float tileNum = 5;//平铺数量
                float ySpd = 0.1;      
                uv.y += _Time.y * 0.0618;//加点y轴移动 =PI2 /period *0.45*0.55 / tileNum         
                uv *= fixed2(tileNum * aspectRatio,tileNum);//栅格化uv             
                 fixed idRand = Hash12(floor(uv));  
               
                uv = frac(uv); 
                float2 gridUV = uv;
                uv -=0.5;//(-0.5,0.5)
                float t = _Time.y * PI2 /period;
                t += idRand * PI2;//添加Y随机值
                
                uv.y += sin(t+sin(t+sin(t)*0.55))*0.45;
                uv.y *= aspectRatio;
                //添加x轴随机偏移
                uv.x += (idRand-.5)*.6;              
                retVal = float2(uv);
                return retVal;
            }.

we want him to do a little lean
insert image description here

 fixed4 frag (v2f i) : SV_Target
            {
    
                                   
                float2 _uv = i.uv;     
  
                float2 rainUV = float2(0.,0.); 
                float baseOffset = 0.1;             
                _uv *= float2(_ScreenParams.x/_ScreenParams.y,1.0);
                float x = (sin(_Time.y*.1)*.5+.5)*.3;
                x =x*x;
                x+= baseOffset;
                float s = sin(x);
                float c = cos(x);
                float2x2 rot = float2x2(c, -s, s, c);
                _uv = mul(rot,_uv);
                
                rainUV = Rains(_uv*2.32);

                fixed4 col = tex2D(_MainTex, i.uv + rainUV);  
                return fixed4( col.rgb, 1);
            }

Next, start to draw a circle, this place is very clever
float r = length(uv);
r = smoothstep(0.2,0.1,r);
retVal = float2(r * uv);
insert image description here

But at this time, this uv unit has only one water droplet. To enhance the effect, we will add a trail. Roughly the same as the previous principle, continue to divide uv in the y-axis direction

//添加尾迹
                float tailTileNum = 3.0;
                float2 tailUV =uv *  float2(1.0,tailTileNum);
                tailUV.y = frac(tailUV.y) - 0.5;
                tailUV.x *= tailTileNum;
                //在雨滴上面总共有
                float rtail = length(tailUV);
                //尾迹塑形
                rtail *= uv.y * 1.5;
                rtail = smoothstep(0.2,0.1,rtail);
                //切除掉大雨滴下面的部分
                rtail *= smoothstep(0.3,0.5,uv.y);
                retVal = float2(rtail*tailUV+r*uv);       

final effect
insert image description here

Let's apply it to Umbrella
insert image description here
Here is the full code for Umbrella

Shader "Unlit/WaterDrop"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
        _Color("Color", Color) = (1, 1, 1, 1) 
        _OutLineColor("OutLineColor", Color) = (1,1,1,1)
    }
    SubShader
    {
    
    
        Tags {
    
     "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 100
        GrabPass {
    
     "_RefractionTex" }
        Pass
        {
    
    
            Cull Front
            CGPROGRAM
            #define PI2 6.28318530718
            #pragma vertex vert
            #pragma fragment frag     

            #include "UnityCG.cginc"
            float4 _Color;
            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal :NORMAL;
            };

            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;              
                float4 vertex : SV_POSITION;
                float4 screenPos  : TEXCOORD1;               
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;          
            float4 _OutLineColor;
            sampler2D _RefractionTex;
            float4 _RefractionTex_TexelSize;
            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);   
                o.screenPos = ComputeGrabScreenPos(o.vertex);              
                return o;
            }


            float Hash12(float2 p)
            {
    
    
                float3 p3  = frac(float3(p.xyx) * .1031);
                p3 += dot(p3, p3.yzx + 19.19);
                return frac((p3.x + p3.y) * p3.z);
            }
            fixed2 Rains(fixed2 uv) {
    
    
                float period = 5;//雨滴在格子中循环的周期
                float2 retVal  = float2(0.0,0.0);
                float aspectRatio = 4.0;//雨滴的宽高比 
                float tileNum = 5;//平铺数量
                float ySpd = 0.1;
                uv.y += _Time.y * 0.0618;//加点y轴移动 =PI2 /period *0.45*0.55 / tileNum
                uv *= fixed2(tileNum * aspectRatio,tileNum);//栅格化uv
                //加点基于格子的随机值
                fixed idRand = Hash12(floor(uv));
                uv = frac(uv); 
                float2 gridUV = uv;
                uv -=0.5;//(-0.5,0.5)
                //此处uv值范围为(-0.5,0.5)
                //*0.45的原因 是让水滴在格子内游走刚好让上下两个格子之间游走,
                //从而在视觉上格子之间的水滴是可以碰撞的,从而克服格子的空间的分割感
                float t = _Time.y * PI2 /period;
                t += idRand * PI2;//添加Y随机值
                
                uv.y += sin(t+sin(t+sin(t)*0.55))*0.45;
                uv.y *= aspectRatio;
                //添加x轴随机偏移
                uv.x += (idRand-.5)*.6;

                float r = length(uv);
                r = smoothstep(0.2,0.1,r);
        
                //添加尾迹
                float tailTileNum = 3.0;
                float2 tailUV =uv *  float2(1.0,tailTileNum);
                tailUV.y = frac(tailUV.y) - 0.5;
                tailUV.x *= tailTileNum;
                //在雨滴上面总共有
                float rtail = length(tailUV);
                //尾迹塑形
                rtail *= uv.y * 1.5;
                rtail = smoothstep(0.2,0.1,rtail);
                //切除掉大雨滴下面的部分
                rtail *= smoothstep(0.3,0.5,uv.y);
                retVal = float2(rtail*tailUV+r*uv);
                return retVal;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
                                   
                float2 _uv = i.screenPos.xy / i.screenPos.w;     
                float baseOffset = 0.1;
                float2 uv = _uv;
                uv *= float2(_ScreenParams.x/_ScreenParams.y,1.0);
                float x = (sin(_Time.y*.1)*.5+.5)*.3;
                x =x*x;
                x+= baseOffset;
                float s = sin(x);
                float c = cos(x);
                float2x2 rot = float2x2(c, -s, s, c);
                uv = mul(rot,uv);
                float moveSpd = 0.1;
                float2 rainUV = float2(0.,0.); 
                
                rainUV = Rains(uv*2.32);

                fixed4 col = tex2D(_RefractionTex, _uv + rainUV*2.);    
                float3 fina_col = _OutLineColor  ;
                return fixed4(fina_col + col.rgb, 1);
            }
            ENDCG
        }
    }
}


Summarize

The above is the whole content of this sharing.

Guess you like

Origin blog.csdn.net/weixin_39289457/article/details/125468168