shader实现毛玻璃效果解析,毛玻璃是很多项目需要的效果,以下是毛玻璃的效果代码:
Shader "Custom/WaterBlur" {
Properties {
_blurSizeXY("BlurSizeXY", Range(0,15)) = 2
}
SubShader {
Tags {
"IgnoreProjector"="True"
"Queue"="Transparent"
"RenderType"="Transparent"
"CanUseSpriteAtlas"="True"
"PreviewType"="Plane"
}
//获取屏幕纹理,必须的
GrabPass { }
// Render the object with the texture generated above
Pass {
CGPROGRAM
#pragma debug
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
//屏幕纹理定义
sampler2D _GrabTexture : register(s0);
float _blurSizeXY;
struct data {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f {
float4 position : POSITION;
float4 screenPos : TEXCOORD0;
};
v2f vert(data i){
v2f o;
o.position = UnityObjectToClipPos(i.vertex);
o.screenPos = o.position;
return o;
}
//核心逻辑就是使用多次采样纹理,然后混合多次,采样的对象是屏幕纹理,实现高斯模糊
half4 frag( v2f i ) : COLOR
{
//模糊的原理就是错开uv来采样,实现模糊
float2 screenPos = i.screenPos.xy / i.screenPos.w;
float depth= _blurSizeXY*0.0005;
screenPos.x = (screenPos.x + 1) * 0.5;
screenPos.y = 1-(screenPos.y + 1) * 0.5;
half4 sum = half4(0.0h,0.0h,0.0h,0.0h);
sum += tex2D( _GrabTexture, float2(screenPos.x-5.0 * depth, screenPos.y+3.0 * depth)) * 0.025;
sum += tex2D( _GrabTexture, float2(screenPos.x+5.0 * depth, screenPos.y-3.0 * depth)) * 0.025;
sum += tex2D( _GrabTexture, float2(screenPos.x-4.0 * depth, screenPos.y+2.5 * depth)) * 0.05;
sum += tex2D( _GrabTexture, float2(screenPos.x+4.0 * depth, screenPos.y-2.5 * depth)) * 0.05;
sum += tex2D( _GrabTexture, float2(screenPos.x-3.0 * depth, screenPos.y+2.0 * depth)) * 0.09;
sum += tex2D( _GrabTexture, float2(screenPos.x+3.0 * depth, screenPos.y-2.0 * depth)) * 0.09;
sum += tex2D( _GrabTexture, float2(screenPos.x-2.0 * depth, screenPos.y+1.5 * depth)) * 0.12;
sum += tex2D( _GrabTexture, float2(screenPos.x+2.0 * depth, screenPos.y-1.5 * depth)) * 0.12;
sum += tex2D( _GrabTexture, float2(screenPos.x-1.0 * depth, screenPos.y+1.0 * depth)) * 0.15;
sum += tex2D( _GrabTexture, float2(screenPos.x+1.0 * depth, screenPos.y-1.0 * depth)) * 0.15;
sum += tex2D( _GrabTexture, screenPos-3.0 * depth) * 0.025;
sum += tex2D( _GrabTexture, screenPos-2.5 * depth) * 0.05;
sum += tex2D( _GrabTexture, screenPos-2.0 * depth) * 0.09;
sum += tex2D( _GrabTexture, screenPos-1.5 * depth) * 0.12;
sum += tex2D( _GrabTexture, screenPos-1.0 * depth) * 0.15;
sum += tex2D( _GrabTexture, screenPos) * 0.16;
sum += tex2D( _GrabTexture, screenPos+3.0 * depth) * 0.15;
sum += tex2D( _GrabTexture, screenPos+2.5 * depth) * 0.12;
sum += tex2D( _GrabTexture, screenPos+2.0 * depth) * 0.09;
sum += tex2D( _GrabTexture, screenPos+1.5 * depth) * 0.05;
sum += tex2D( _GrabTexture, screenPos+1.0 * depth) * 0.025;
return sum/2;
}
ENDCG
}
}
Fallback Off
}
这是实现效果:
我们可以用Dotween插件来控制模糊的程度,可以实现很好的效果,有如下代码:
/// 主页按钮点击回调
///
private void HimebtnHundler()
{
_leftpic.transform.DOLocalMoveX(-746f, 1);
_rightpic.transform.DOLocalMoveX(787f, 1);
_material.DOFloat(0, "_blurSizeXY", 1);
_word.GetComponent().DOFade(0, 1f);
StartCoroutine(CloseErrorView());
}
这段代码,主要是增加CanvasGroup组件,实现对整个场景的alpha控制:
主要用DOFade来实现CanvasGroup,用DOFloat对材质球上的shader属性的控制!