您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 雾切酱 于 2019-4-17 12:13 编辑
转https://zhuanlan.zhihu.com/p/62393096 黄小明
时光飞逝,岁月如梭~
来~我们开始第二部分,记得还是要保持一颗失恋的心
PS:我是认真的:)
-------------------
先给贴上Part1部分我连的shaderforge
ShaderForge的话虽然说制作时候效果观察很方便,但是复杂的话不太好连,而且不好检查,有时候错了一下子都找不到头,不过如果不能写码的话就只能连线了
其实上一个部分我觉得最重要的是计算水滴+拖尾的位置以及大小的部分,然后就是X,Y值的偏移计算,这两个部分好好看看还是很有意思的,一步步先来画格子,算水滴然后再添加位移。
如果看不清,就去链接下载吧,ShaderForge制作的shader和流程图都放里面了
https://pan.baidu.com/s/1AZ1ocqC4CDYQccJt3sXI4g 密码:wm1t
-------------------
先说下这部分做什么,首先我们需要作出模糊,然后一层水滴肯定是不够的,不够丰富,而且也不够随机,所以我们需要添加多层水滴,再然后就是做真实玻璃的透明。
好的我们开始,回到上一部分结尾的代码上
- fixed4 frag (v2f i) : SV_Target
- {
- float t = fmod(_Time.y,7200);
- float4 col =0;
- float2 aspect = float2(2, 1);
- float2 uv = i.uv*_Size*aspect;
- uv.y += t * 0.25;
- float2 gv = frac(uv)-0.5;
- float2 id = floor(uv);
-
- float n =N21(id);
- t+= n*6.28631;
- float w = i.uv.y *10;
- float x = (n-0.5)*0.8;
- x += (0.4-abs(x))*sin(3*w)*pow(sin(w),6)*0.45;
- float y =-sin(t+sin(t+sin(t)*0.5))*0.45;
- y -= (gv.x-x)*(gv.x-x);
-
- float2 dropPos =(gv - float2(x, y))/aspect;
- float drop = smoothstep(0.05,0.03,length(dropPos));
-
- float2 dropTrailPos = (gv - float2(x, t*0.25)) / aspect;
- dropTrailPos.y = (frac(dropTrailPos.y* 8)/8)-0.03;
- float dropTrail = smoothstep(0.03, 0.02, length(dropTrailPos));
- float fogTrail = smoothstep(-0.05, 0.05, dropPos.y);
- fogTrail *= smoothstep(0.5, y, gv.y);
- dropTrail *= fogTrail;
- fogTrail *= smoothstep(0.05,0.04,abs(dropPos.x));
- col += fogTrail*0.5;
- col += dropTrail;
- col += drop;
-
- float2 offs = drop*dropPos+dropTrail*dropTrailPos;
- col = tex2D(_MainTex,i.uv+offs*_Distortion);
- return col;
- }
点击此处复制文本
我们先添加模糊效果,我们就不自己计算模糊了,直接用Mipmap然后在shader中使用Tex2Dlod,一定要注意使用的图片有没有打开MipMap,然后就是FilterMode的选择如果选择了Trilinear,point会产生块面模糊(像素风格), Bilinear是逐步模糊(阶梯化渐变),trilinear是会在两个模糊度上平滑过渡
做好以后我们修改下代码,如果没有模糊变化的话,检查下Texture的设置吧
- col = tex2Dlod(_MainTex,float4 (i.uv + offs * _Distortion,0,4));
点击此处复制文本
https://docs.microsoft.com/zh-cn ... phics-hlsl-tex2dlod
接下来我们给一个_Blur值来控制模糊程度
- float blur = _Blur * 7;
- float2 offs = drop * dropPos + dropTrail * dropTrailPos;
- col = tex2Dlod(_MainTex,float4 (i.uv + offs * _Distortion,0, blur));
- return col;
点击此处复制文本
目前的模糊结果
因为正常水滴划过的地方会更加清晰,所以我们来处理下
- //fogTrail是水滴的拖尾因为我们需要拖尾处清楚所以我们需要取个反减值
- float blur = _Blur * 7 * (1-fogTrail);
点击此处复制文本
现在得到的模糊效果
现在我们第一个部分模糊已经处理好了,开始制作多层水滴,新建一个Layer struct 输入一个uv值和t值返回我们需要的offs,fogTrail。
注意:i.uv需要换成UV了,还有一些col现在没有了,然后改一下frag里面的参数就行
每一个drops都是一层水滴,只要修改输入的UV值就可以得到大小不一位置不一样的水滴了
- float3 Layer(float2 UV,float t){
- float2 aspect = float2(2, 1);
- float2 uv = UV*_Size*aspect;
- uv.y += t * 0.25;
- float2 gv = frac(uv) - 0.5;
- float2 id = floor(uv);
- float n = N21(id);
- t += n * 6.28631;
- float w = UV.y * 10;
- float x = (n - 0.5)*0.8;
- x += (0.4 - abs(x))*sin(3 * w)*pow(sin(w),6)*0.45;
- float y = -sin(t + sin(t + sin(t)*0.5))*0.45;
- y -= (gv.x - x)*(gv.x - x);
- float2 dropPos = (gv - float2(x, y)) / aspect;
- float drop = smoothstep(0.05,0.03,length(dropPos));
- float2 dropTrailPos = (gv - float2(x, t*0.25)) / aspect;
- dropTrailPos.y = (frac(dropTrailPos.y * 8) / 8) - 0.03;
- float dropTrail = smoothstep(0.03, 0.02, length(dropTrailPos));
- float fogTrail = smoothstep(-0.05, 0.05, dropPos.y);
- fogTrail *= smoothstep(0.5, y, gv.y);
- dropTrail *= fogTrail;
- fogTrail *= smoothstep(0.05,0.04,abs(dropPos.x));
- // col += fogTrail * 0.5;
- // col += dropTrail;
- // col += drop;
-
- float2 offs = drop * dropPos + dropTrail * dropTrailPos;
- return float3(offs,fogTrail);
- }
- fixed4 frag(v2f i) : SV_Target
- {
- float t = fmod(_Time.y,7200);
- float4 col = 0;
- //水滴层
- float3 drops = Layer(i.uv,t);
- //*是放大UV向量+,—是位移UV向量,瞎j8乘
- drops += Layer(i.uv*1.35+7.51,t);
- drops += Layer(i.uv*0.95+1.54,t);
- drops += Layer(i.uv*1.57-6.54,t);
- //fogTrail是水滴的拖尾因为我们需要拖尾处清楚所以我们需要取个反减值
- float blur = _Blur * 7 * (1-drops.z);
- col = tex2Dlod(_MainTex,float4 (i.uv +drops.xy* _Distortion,0, blur));
- return col;
- }
点击此处复制文本
现在我们做第三部分,透明这里用GrapPass,其实用GrapPass很耗性能,不过反正这也不是一个低性能的shader
不BB开始,添加一个GrapPass,输入col看一下,然后需要设置Queue到Transparent,在Transparent这个渲染序列下才能在所有Geometry和AlphaTest渲染后,再从后向前渲染一遍
- Shader "Billy/RainGlass_OP"
- {
- Properties
- {
- _MainTex("Texture", 2D) = "white" {}
- _Size("Size",Float) = 1
- _Distortion("Distortion",range(0,1)) = 1
- _Blur("Blur",range(0,1)) = 1
- }
- SubShader
- {
- Tags { "RenderType" = "Opaque" "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
- {
- float2 uv : TEXCOORD0;
- float4 vertex : SV_POSITION;
- };
- sampler2D _MainTex;
- sampler2D _GrabTexture;
- float4 _MainTex_ST;
- float _Size;
- float _Distortion;
- float _Blur;
- v2f vert(appdata v)
- {
- v2f o;
- o.vertex = UnityObjectToClipPos(v.vertex);
- o.uv = TRANSFORM_TEX(v.uv, _MainTex);
- return o;
- }
- float N21(float2 p) {
- p = frac(p*float2(123.34,345.45));
- p += dot(p,p + 34.345);
- return frac(p.x*p.y);
- }
- float3 Layer(float2 UV,float t){
- float2 aspect = float2(2, 1);
- float2 uv = UV*_Size*aspect;
- uv.y += t * 0.25;
- float2 gv = frac(uv) - 0.5;
- float2 id = floor(uv);
- float n = N21(id);
- t += n * 6.28631;
- float w = UV.y * 10;
- float x = (n - 0.5)*0.8;
- x += (0.4 - abs(x))*sin(3 * w)*pow(sin(w),6)*0.45;
- float y = -sin(t + sin(t + sin(t)*0.5))*0.45;
- y -= (gv.x - x)*(gv.x - x);
- float2 dropPos = (gv - float2(x, y)) / aspect;
- float drop = smoothstep(0.05,0.03,length(dropPos));
- float2 dropTrailPos = (gv - float2(x, t*0.25)) / aspect;
- dropTrailPos.y = (frac(dropTrailPos.y * 8) / 8) - 0.03;
- float dropTrail = smoothstep(0.03, 0.02, length(dropTrailPos));
- float fogTrail = smoothstep(-0.05, 0.05, dropPos.y);
- fogTrail *= smoothstep(0.5, y, gv.y);
- dropTrail *= fogTrail;
- fogTrail *= smoothstep(0.05,0.04,abs(dropPos.x));
- // col += fogTrail * 0.5;
- // col += dropTrail;
- // col += drop;
-
- float2 offs = drop * dropPos + dropTrail * dropTrailPos;
- return float3(offs,fogTrail);
- }
- fixed4 frag(v2f i) : SV_Target
- {
- float t = fmod(_Time.y,7200);
- float4 col = 0;
- //水滴层
- float3 drops = Layer(i.uv,t);
- //*是放大UV向量+,—是位移UV向量,瞎j8乘
- drops += Layer(i.uv*1.35+7.51,t);
- drops += Layer(i.uv*0.95+1.54,t);
- drops += Layer(i.uv*1.57-6.54,t);
- //fogTrail是水滴的拖尾因为我们需要拖尾处清楚所以我们需要取个反减值
- float blur = _Blur * 7 * (1-drops.z);
- col = tex2Dlod(_MainTex,float4 (i.uv +drops.xy* _Distortion,0, blur));
- col = tex2D(_GrabTexture,i.uv);
- return col;
- }
- ENDCG
- }
- }
- }
点击此处复制文本
接下来我们就对齐GrapPassTex到屏幕坐标就好了,很开心UNity有这个宏UNITY_PROJ_COORD(ComputeGrabScreenPos(o.vertex)
https://www.jianshu.com/p/df878a386bec
先贴上最后代码,立个Flag过两天再接着写
- Shader "Billy/RainGlass"
- {
- Properties
- {
- _MainTex("Texture", 2D) = "white" {}
- _Size("Size",Float) = 1
- _Distortion("Distortion",range(0,5)) = 4
- _Blur("Blur",range(0,1)) = 1
- }
- SubShader
- {
- Tags { "RenderType" = "Opaque" "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
- {
- float2 uv : TEXCOORD0;
- float4 vertex : SV_POSITION;
- float4 grabUv : TEXCOORD1;
- };
- sampler2D _MainTex;
- sampler2D _GrabTexture;
- float4 _MainTex_ST;
- float _Size;
- float _Distortion;
- float _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));
- return o;
- }
- float N21(float2 p) {
- p = frac(p*float2(123.34,345.45));
- p += dot(p,p + 34.345);
- return frac(p.x*p.y);
- }
- float3 Layer(float2 UV,float t){
- float2 aspect = float2(2, 1);
- float2 uv = UV*_Size*aspect;
- uv.y += t * 0.25;
- float2 gv = frac(uv) - 0.5;
- float2 id = floor(uv);
- float n = N21(id);
- t += n * 6.28631;
- float w = UV.y * 10;
- float x = (n - 0.5)*0.8;
- x += (0.4 - abs(x))*sin(3 * w)*pow(sin(w),6)*0.45;
- float y = -sin(t + sin(t + sin(t)*0.5))*0.45;
- y -= (gv.x - x)*(gv.x - x);
- float2 dropPos = (gv - float2(x, y)) / aspect;
- float drop = smoothstep(0.05,0.03,length(dropPos));
- float2 dropTrailPos = (gv - float2(x, t*0.25)) / aspect;
- dropTrailPos.y = (frac(dropTrailPos.y * 8) / 8) - 0.03;
- float dropTrail = smoothstep(0.03, 0.02, length(dropTrailPos));
- float fogTrail = smoothstep(-0.05, 0.05, dropPos.y);
- fogTrail *= smoothstep(0.5, y, gv.y);
- dropTrail *= fogTrail;
- fogTrail *= smoothstep(0.05,0.04,abs(dropPos.x));
- // col += fogTrail * 0.5;
- // col += dropTrail;
- // col += drop;
-
- float2 offs = drop * dropPos + dropTrail * dropTrailPos;
- return float3(offs,fogTrail);
- }
- fixed4 frag(v2f i) : SV_Target
- {
- float t = fmod(_Time.y,7200);
- float4 col = 0;
- //水滴层
- float3 drops = Layer(i.uv,t);
- //*是放大UV向量+,—是位移UV向量,瞎j8乘
- drops += Layer(i.uv*1.35+7.51,t);
- drops += Layer(i.uv*0.95+1.54,t);
- drops += Layer(i.uv*1.57-6.54,t);
- //fogTrail是水滴的拖尾因为我们需要拖尾处清楚所以我们需要取个反减值
- float fade = 1-saturate(fwidth(i.uv)*60);
- float blur = _Blur * 7 * (1-drops.z*fade);
- // col = tex2Dlod(_MainTex,float4(i.uv+drops.xy*_Distortion,0,blur));
- float2 projUv = i.grabUv.xy / i.grabUv.w;
- projUv += drops.xy*_Distortion*fade;
- blur *= 0.01;
- const float numSamples =32;
- 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)*5421);
- d = sqrt(d);
- offs *=d;
- col += tex2D(_GrabTexture,projUv+offs);
- a++;
- }
- col /= numSamples;
- return col;
- }
- ENDCG
- }
- }
- }
点击此处复制文本 |