Unity uses Shader to make glass windows in the rain learning notes
https://www.youtube.com/watch?v=EBrAdahFtuo Watch the notes after the oil pipe god's tutorial.
Blur background, simulate fog
- In the textured Inspector panel, checking Generate Mip Maps results in eight MipMaps with different levels of detail.
- tex2Dlod(_MainTex,float4(x,y,z,w)); in this texture sampling function, in addition to uv, you can control the level of detail, offset, and W control details.
- The Filter Mode in the textured Inspector panel represents how textures are filtered when stretched by a three-dimensional transformation.There are three options: Point has no filter, Bilinear blurs when viewed at close range, and Trilinear blurs between different Mip Level s one more than Bilinear.It just has more blurred levels and feels like stepless speed.
Make glass transparent
- Add GrabPass{"_GrabTexture"} to SubShader, meaning screenshots and storage for use.There are two problems: 1, incorrect connection with the background behind 2, the game object behind cannot be displayed because unit defaults to the first rendering near the camera.
- Question 1: Add variable float4 grabUv in V2F structure: TEXCOORD1; add statement o.grabUv = UNITY_PROJ_COORD (ComputeGrabScreenPos (o.vertex) in vertex shader;
Float4 UNITY_PROJ_COORD (float4) inputs a four-component vector and returns coordinates suitable for texture sampling.
Float4 ComputeGrabScreenPos (float4) enters the coordinates of the clip space and returns the coordinates used for GrabPass.
Question 2: Add Queue="Transparent" to SubShader's Tag to tell Unity that the object is transparent and needs to be rendered at the end.
Handwriting Fuzzy Algorithm
- Since textures obtained using GrabPass cannot use Mipmap, blurring is achieved by iterating the average value of each pixel and surrounding pixels, which is the simplest but costly blurring method.
//The blur is blurred and there is no fog covering where the water droplets pass float blur = _Blur * 7 * (1-drops.z); float2 projUv = i.grabUv.xy/i.grabUv.w; projUv+=drops.xy*_Distortion; blur*=0.01; const float numSamples = 16; //A is the starting position and the value is a random value within one period of the trigonometric function float a = N21(i.uv)*6.2831; for(float i = 0;i<numSamples;i++){ //offs is the offset coordinate of the surrounding pixel to be sampled relative to the intermediate pixel float2 offs = float2(sin(a),cos(a))*blur; //d To get a random number between 0 and 1 so that the sampled area is not a circle //Can reduce edges too sharp float d = frac(sin((i+1)*546.)*5425.); d = sqrt(d); offs *= d; col += tex2D(_GrabTexture,projUv+offs); a++; } col/=numSamples;
`Shader "Unlit/Window"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Size("Size",float) = 1
_t("Time",float) = 1
_Distortion("Distortion",Range(-5,5))=1
_Blur("blur",range(0,1)) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Transparent"}
LOD 100
GrabPass{"_GrabTexture"}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#define S(a,b,c) smoothstep(a,b,c)//Using S instead of this method is more convenient
#include "UnityCG.cginc"
struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 grabUv : TEXCOORD1; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex,_GrabTexture; float4 _MainTex_ST; float _Size,_t,_Distortion,_Blur; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.grabUv = UNITY_PROJ_COORD(ComputeGrabScreenPos(o.vertex)); UNITY_TRANSFER_FOG(o,o.vertex); return o; } //Generate a pseudo-random number using a two-dimensional vector float N21(float2 p){ p=frac(p*float2(123.34,345.45)); p+=dot(p,p+34.345);//Return two vector clicks return frac(p.x*p.y); } //The process of generating water droplets is encapsulated in a function Layer to increase the number of water droplets by multiple overlays. float3 Layer(float2 UV,float t){ //Double the grid x direction float2 aspect = float2(2,1); //size is used to control how many grids there are float2 uv = UV*_Size*aspect; //Achieving an overall slide uv.y+=t*0.25; //frac is decimal, gv is the coordinate within each cell, from left to right, from bottom to top is -0.5 to 0.5 float2 gv = frac(uv)-0.5; //Set id for each grid float2 id = floor(uv); //Each grid has a random number between 0 and 1 float n = N21(id); //Make the random x-distribution on a period of 0 and 2_to make the effect more random. t+=n*6.2831; //Setting height as a variable of the lateral offset function float w = UV.y*10; //Achieve lateral drip offset of water droplets between -0.4 and 0.4 to prevent the drip from drifting out of the grid float x=(n-0.5)*0.8; x += (0.4-abs(x)) * sin(3*w)*pow(sin(w),6)*0.45; //Offset function to realize the vertical movement of water droplets and the slow rise and fast fall of water droplets float y=-sin(t+sin(t+sin(t)*0.5))*0.45; //Change the shape of the water droplets to offset the change in x y-=(gv.x-x)*(gv.x-x); //The location of the droplet center, which controls the coordinate system within the square, (0, 0) the origin is the droplet Center float2 dropPos = (gv-float2(x,y))/aspect; //Display area of water droplets, 1 for display, 0 for no water droplets, edge for interpolation float drop = S(.05,.03,length(dropPos)); //Trailing beads float2 trailPos = (gv-float2(x,t*0.25))/aspect; trailPos.y=(frac(trailPos.y*8)-0.5)/8; float trail = S(.03,.01,length(trailPos)); //Set only water droplets with tails above them float fogtrail = S(-0.05,0.05,dropPos.y); //Dragging gradient of water droplets to the upper limit of the square fogtrail*=S(0.5,y,gv.y); trail*=fogtrail; //Fog effect of trailing fogtrail*=S(0.05,0.04,abs(dropPos.x)); //Test Code //col+=fogtrail*0.5; //col+=drop; //col+=trail; /* if(_textNum<0){ col*=0;col.rg+=dropPos; } */ //Offset the sampling coordinates where there are water droplets to represent the refraction of light float2 offs = drop*dropPos+trail*trailPos; //col= tex2D(_MainTex,i.uv+offs*_Distortion); return float3(offs,fogtrail); } fixed4 frag (v2f i) : SV_Target { //t means time, reset every two hours in case the time number is too large to cause the pseudo-random number to show up float t = fmod(_Time.y+_t,7200); float4 col = 0; float3 drops = Layer(i.uv,t); drops+=Layer(i.uv*1.11+8.43,t); //fwidth is a partial derivative that represents the difference between the pixel on the screen and the surrounding pixel. The closer the pixel is, the greater the distance is //saturate returns 0 for controlling variables between 0 and 1, 0 for less than 0, 1 for greater than 1 //The farther away from the object, the closer fade is to 0, the closer fade is to 1 float fade = 1-saturate(fwidth(i.uv)*60); //Fuzzy hierarchy for water droplets with no fog float blur = _Blur * 7 * (1-drops.z*fade); //col = tex2Dlod(_MainTex,float4(i.uv+drops.xy*_Distortion,_textNum,blur)); float2 projUv = i.grabUv.xy/i.grabUv.w; projUv+=drops.xy*_Distortion*fade; //Use the average value of each pixel and surrounding pixels to blur and simulate the fog effect blur*=0.01; //Number of iterations const float numSamples = 16; //Search for the start of nearby pixels, between 0 and 2_ float a = N21(i.uv)*6.2831; for(float i = 0;i<numSamples;i++){ float2 offs = float2(sin(a),cos(a))*blur; float d = frac(sin((i+1)*546.)*5425.); d = sqrt(d); offs *= d; col += tex2D(_GrabTexture,projUv+offs); a++; } col/=numSamples; return col*0.9; } ENDCG } }
}
`