blur_fragment.glsl 1.44 KB
Newer Older
Jan Möbius's avatar
   
Jan Möbius committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// depth preserving gaussian blur filter with 11 samples
// working on the x channel only

varying vec2 vTexCoord;

uniform sampler2D Tex;

// we need a z buffer to avoid color bleeding
uniform sampler2D DepthTex;

// TexelSize controls the direction of this pass
//  example: set TexelSize.y to 0 for a horizontal pass
uniform vec2 TexelSize;
uniform float Kernel[5]; // gaussian distribution in one direction only

const float DepthThreshold = 0.01;

Christopher Tenter's avatar
Christopher Tenter committed
18
19
uniform float EdgeBlur; // [0,1]: 0 -> no edge blurring, 1 -> blur everywhere

Jan Möbius's avatar
   
Jan Möbius committed
20
21
22
23
float GetDepthWeight(vec2 uv, float Depth)
{
	float SampleDepth = texture2D(DepthTex, uv).x;
	float DepthRange = abs(Depth - SampleDepth) / (Depth + 0.001);
Christopher Tenter's avatar
Christopher Tenter committed
24
	float DepthCheck = DepthRange > DepthThreshold ? EdgeBlur : 1.0;
Jan Möbius's avatar
   
Jan Möbius committed
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
52
53
54
55
56
57
	
	return DepthCheck;
}

void main(void)
{
	// kernel center:
	float Result = texture2D(Tex, vTexCoord).x * Kernel[0];
	
	float Depth = texture2D(DepthTex, vTexCoord).x;
	
	float WeightSum = Kernel[0]; // not necessarily 1 with enabled depth preserving
	
	// kernel sides:
	vec2 uv0 = vTexCoord, uv1 = vTexCoord;
	for (int i = 1; i < 5; ++i)
	{
		uv0 += TexelSize;
		uv1 -= TexelSize;
		
		float BlurWeight = Kernel[i] * GetDepthWeight(uv0, Depth);
		
		Result += texture2D(Tex, uv0).x * BlurWeight;
		WeightSum += BlurWeight;
		
		BlurWeight = Kernel[i] * GetDepthWeight(uv1, Depth);
		
		Result += texture2D(Tex, uv1).x * BlurWeight;
		WeightSum += BlurWeight;
	}
	
	gl_FragData[0] = vec4(Result / WeightSum, 0, 0, 0);
}