使用shader去做屏幕模糊特效很多人肯定以为是高斯模糊,但本篇文章介绍的并不是,这里反而要给大家介绍的是在Unity中利用 shader实现屏幕模糊特效。
shader代码:C#代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
Shader
"Tut/Effects/Blur"
{
Properties {
_MainTex (
"Base (RGB)"
, 2D) =
""
{}
}
Subshader {
Pass {
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma fragmentoption ARB_precision_hint_fastest
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct
v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
// 启用3个纹理坐标,就能使用6个tex2D
float4 uv01 : TEXCOORD1;
float4 uv23 : TEXCOORD2;
float4 uv45 : TEXCOORD3;
};
float4 offsets;
sampler2D _MainTex;
v2f vert (appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = v.texcoord.xy;
// 将uv向右上和左下做偏移,*2放大2倍
o.uv01 = v.texcoord.xyxy + offsets.xyxy * float4(1,1, -1,-1);
o.uv23 = v.texcoord.xyxy + offsets.xyxy * float4(1,1, -1,-1) * 2.0;
o.uv45 = v.texcoord.xyxy + offsets.xyxy * float4(1,1, -1,-1) * 3.0;
return
o;
}
half4 frag (v2f i) : COLOR {
half4 color = float4 (0,0,0,0);
color += 0.40 * tex2D (_MainTex, i.uv);
// 这样每个像素点的颜色叠加周围6个点的颜色,形成模糊效果
color += 0.15 * tex2D (_MainTex, i.uv01.xy);
color += 0.15 * tex2D (_MainTex, i.uv01.zw);
color += 0.10 * tex2D (_MainTex, i.uv23.xy);
color += 0.10 * tex2D (_MainTex, i.uv23.zw);
color += 0.05 * tex2D (_MainTex, i.uv45.xy);
color += 0.05 * tex2D (_MainTex, i.uv45.zw);
return
color;
}
ENDCG
}
}
Fallback off
}
|
【挂在摄像机上】:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
using
UnityEngine;
using
System.Collections;
public
class
_DepthOfField_1 : MonoBehaviour
{
public
Shader blurShader ;
private
Material blurMat =
null
;
// 假设屏幕宽高为512
// 这里就是一个像素在值域为[0,1]上的值
private
float
onePixelWidth = 1.0f / 512.0f;
private
float
onePixelHeight = 1.0f / 512.0f;
void
Start ()
{
blurMat =
new
Material(blurShader);
}
///
/// 在所有渲染完成后被调用,来渲染图片的后期处理效果
/// source理解为进入shader过滤器的纹理
/// destination理解为渲染完成的纹理
///
void
OnRenderImage (RenderTexture source ,RenderTexture destination )
{
blurMat.SetVector(
"offsets"
,
new
Vector4(0.0f, onePixelHeight, 0.0f, 0.0f));
// Graphics.Blit拷贝源纹理到目的渲染纹理,通过shader
// 先修改y偏移
Graphics.Blit(source, source, blurMat);
// 再修改x偏移
blurMat.SetVector(
"offsets"
,
new
Vector4(onePixelHeight, 0.0f, 0.0f, 0.0f));
Graphics.Blit(source, destination, blurMat);
}
}
|