bu efekti aşağıdaki adımları izleyerek yapabilirsiniz:
parçacık
RenderTextuer
RenderTexture'ı kullanarak sonucu saklayabilirsiniz. bu shadertoy'daki multipass örneğidir:
https://www.shadertoy.com/view/ltccRl
iñigo quilez: Shadertoy, "Buffer" başına bir tane olmak üzere birden çok geçiş kullanır. Adından da anlaşılacağı gibi, bu geçişler sonuçları bir arabellekte saklar. Bir tampon sadece bir dokudur. Birlik, dokuları da oluşturmanıza izin verecektir.
Parçacıkları RenderTexture'a dönüştürmek için bir kamera oluşturdum:
GrabPassing
Distorsiyon uygulamak için pas alabilirsiniz
Bu yazıda açıkladım:
Quantum Break'in bozulma parçacık etkisini nasıl çoğaltabilirim?
bulanıklık
Lifetime üzerinde alfa rengini kullanarak basit bulanıklığa sahibiz
daha iyi sonuç almak için basit bulanıklığı kullanmak daha iyidir, ancak bulanıklığı nasıl elde ederiz?
Evrişim matrisi
Görüntü işlemede, bir çekirdek, evrişim matrisi veya maske küçük bir matristir. Bulanıklaştırma, bileme, kabartma, kenar algılama ve daha fazlası için kullanılır. Bu, bir çekirdek ile bir imge arasında bir kıvrım yapılarak gerçekleştirilir.
daha fazla bilgi için lütfen bu bağlantıyı takip edin
Shader "Smkgames/Convolution"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[Enum(kerEdgeDetectionA,1,kerEdgeDetectionB,2,kerEdgeDetectionC,3,kerSharpen,4,kerBoxBlur,5)]
_Kernel("Kernel", Float) = 1
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
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;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float3x3 GetData(int channel, sampler2D tex, float2 uv, float4 size)
{
float3x3 mat;
for (int y=-1; y<2; y++)
{
for(int x=-1; x<2; x++)
{
mat[x+1][y+1]=tex2D(tex, uv + float2(x*size.x, y*size.y))[channel];
}
}
return mat;
}
float3x3 GetMean(float3x3 matr, float3x3 matg, float3x3 matb)
{
float3x3 mat;
for (int y=0; y<3; y++)
{
for(int x=0; x<3; x++)
{
mat[x][y] = (matr[x][y] + matg[x][y] + matb[x][y]) / 3.0;
}
}
return mat;
}
float Convolve(float3x3 kernel, float3x3 pixels, float denom, float offset)
{
float res = 0.0;
for (int y=0; y<3; y++)
{
for(int x=0; x<3; x++)
{
res += kernel[2-x][2-y]*pixels[x][y];
}
}
return res;
}
float _Kernel;
fixed4 frag (v2f i) : SV_Target
{
float3x3 kerEdgeDetectionA = float3x3 ( 0.0, 0, -1.0,
1.0, 0, -1.0,
0.0, 1.0, 0.0);
float3x3 kerEdgeDetectionB = float3x3 (0.0, 1.0, 0.0,
1.0, -4.0, 1.0,
0.0, 1.0, 0.0);
float3x3 kerEdgeDetectionC = float3x3 (-1.0, -1.0, -1.0,
-1.0, 8.0, -1.0,
-1.0, -1.0, -1.0);
float3x3 kerSharpen = float3x3 (0.0, -1.0, 0.0,
-1.0, 5.0, -1.0,
0.0, -1.0, 0.0);
float3x3 kerBoxBlur = (1.0/9.0)*float3x3 ( 1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0);
float3x3 kernelSelection;
if(_Kernel == 1){
kernelSelection = kerEdgeDetectionA;
}else if(_Kernel == 2){
kernelSelection = kerEdgeDetectionB;
}else if(_Kernel == 3){
kernelSelection = kerEdgeDetectionC;
}else if(_Kernel == 4){
kernelSelection = kerSharpen;
}else if(_Kernel == 5){
kernelSelection = kerBoxBlur;
}
float3x3 matr = GetData(0, _MainTex, i.uv, _MainTex_TexelSize);
float3x3 matg = GetData(1, _MainTex, i.uv, _MainTex_TexelSize);
float3x3 matb = GetData(2, _MainTex, i.uv, _MainTex_TexelSize);
float3x3 mata = GetMean(matr, matg, matb);
// kernel
float4 gl_FragColor = float4(Convolve(kernelSelection,matr,1.0,0.0),
Convolve(kernelSelection,matg,1.0,0.0),
Convolve(kernelSelection,matb,1.0,0.0),
1.0);
return gl_FragColor;
}
ENDCG
}
}
}
Kutu bulanıklığı
Bir kutu bulanıklığı (kutu doğrusal filtresi olarak da bilinir), sonuçtaki görüntüdeki her pikselin giriş görüntüsündeki komşu piksellerin ortalama değerine eşit bir değere sahip olduğu bir uzaysal alan doğrusal filtresidir. Düşük geçişli ("bulanıklaştırma") bir filtredir. 3'e 3 kutu bulanıklığı matris olarak yazılabilir
https://en.wikipedia.org/wiki/Box_blur
Shader "Smkgames/Simple Box Blur"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha
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;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float4 box(sampler2D tex, float2 uv, float4 size)
{
float4 c = tex2D(tex, uv + float2(-size.x, size.y)) + tex2D(tex, uv + float2(0, size.y)) + tex2D(tex, uv + float2(size.x, size.y)) +
tex2D(tex, uv + float2(-size.x, 0)) + tex2D(tex, uv + float2(0, 0)) + tex2D(tex, uv + float2(size.x, 0)) +
tex2D(tex, uv + float2(-size.x, -size.y)) + tex2D(tex, uv + float2(0, -size.y)) + tex2D(tex, uv + float2(size.x, -size.y));
return c / 9;
}
float4 frag (v2f i) : SV_Target
{
float4 col = box(_MainTex, i.uv, _MainTex_TexelSize);
return col;
}
ENDCG
}
}
}
Tekrarlama
önceki kareyi kaydetmek için Rendertexture'ı kullanabilirsiniz. böylece önceki kareyi yakalayıp bulanıklaştırabilirsiniz. bunu tekrarlayarak bulanıklık elde edersiniz.
Normal
float4 distortion = tex2D(_MainTex,i.uv);
float3 distortionNormal = UnpackNormal(distortion);
Sonuç
Son gölgelendirici:
Shader "Smkgames/BrokenGlass3D"
{
Properties{
_MainTex("MainTex",2D) = "white"{}
_NormalIntensity("NormalIntensity",Float) = 1
_Alpha("Alpha",Float) = 1
}
SubShader
{
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha
GrabPass
{
"_GrabTexture"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float2 grabPos : TEXCOORD1;
float3 normal :NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 grabPos : TEXCOORD1;
half3 worldNormal :TEXCOORD2;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float _Intensity,_Alpha;
v2f vert (appdata v)
{
v2f o;
o.uv = v.uv;
o.vertex = UnityObjectToClipPos(v.vertex);
o.grabPos = ComputeGrabScreenPos(o.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
sampler2D _GrabTexture;
float _NormalIntensity;
fixed4 frag (v2f i) : SV_Target
{
float4 distortion = tex2D(_MainTex,i.uv);
float3 distortionNormal = UnpackNormal(distortion);
distortionNormal.xy *= _NormalIntensity;
normalize(distortionNormal);
fixed4 col = tex2Dproj(_GrabTexture, i.grabPos+float4(distortionNormal.rgb,0));
return col;
}
ENDCG
}
}
}
ömür boyu alfa renk kullanmadan:
ömür boyu alfa renkli kullanarak:
Kaynak mevcut:
https://github.com/smkplus/RainDrop
Fazlası var!
ayrıca Ripples yapabilirsiniz
kullanışlı bağlantılar
https://80.lv/articles/breakdown-animated-raindrop-material-in-ue4/
https://seblagarde.wordpress.com/2013/01/03/water-drop-2b-dynamic-rain-and-its-effects/