Welcome to mirror list, hosted at ThFree Co, Russian Federation.

effect_dof_filter_frag.glsl « shaders « eevee « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8fd8215da0f668ec81cca50c67ab01853aff328e (plain)
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

/**
 * Gather Filter pass: Filter the gather pass result to reduce noise.
 *
 * This is a simple 3x3 median filter to avoid dilating highlights with a 3x3 max filter even if
 * cheaper.
 **/

#pragma BLENDER_REQUIRE(effect_dof_lib.glsl)

uniform sampler2D colorBuffer;
uniform sampler2D weightBuffer;

in vec4 uvcoordsvar;

layout(location = 0) out vec4 outColor;
layout(location = 1) out float outWeight;

/* From:
 * Implementing Median Filters in XC4000E FPGAs
 * JOHN L. SMITH, Univision Technologies Inc., Billerica, MA
 * http://users.utcluj.ro/~baruch/resources/Image/xl23_16.pdf
 * Figure 1 */

/* Outputs low median and high value of a triple. */
void lmh(vec4 s1, vec4 s2, vec4 s3, out vec4 l, out vec4 m, out vec4 h)
{
  /* From diagram, with nodes numbered from top to bottom. */
  vec4 h1 = max(s2, s3);
  vec4 l1 = min(s2, s3);

  vec4 h2 = max(s1, l1);
  vec4 l2 = min(s1, l1);

  vec4 h3 = max(h2, h1);
  vec4 l3 = min(h2, h1);

  l = l2;
  m = l3;
  h = h3;
}

vec4 median_filter(sampler2D tex, vec2 uv)
{
  vec2 texel_size = 1.0 / vec2(textureSize(tex, 0).xy);
  vec4 samples[9];
  int s = 0;

  const vec2 ofs[9] = vec2[9](vec2(-1, -1),
                              vec2(0, -1),
                              vec2(1, -1),
                              vec2(-1, 0),
                              vec2(0, 0),
                              vec2(1, 0),
                              vec2(-1, 1),
                              vec2(0, 1),
                              vec2(1, 1));

  for (int s = 0; s < 9; s++) {
    samples[s] = textureLod(tex, uv + ofs[s] * texel_size, 0.0);
  }

  if (no_gather_filtering) {
    return samples[4];
  }

  for (int s = 0; s < 9; s += 3) {
    lmh(samples[s], samples[s + 1], samples[s + 2], samples[s], samples[s + 1], samples[s + 2]);
  }
  /* Some aliases to better understand what's happening. */
  vec4 L123 = samples[0 + 0], L456 = samples[3 + 0], L789 = samples[6 + 0];
  vec4 M123 = samples[0 + 1], M456 = samples[3 + 1], M789 = samples[6 + 1];
  vec4 H123 = samples[0 + 2], H456 = samples[3 + 2], H789 = samples[6 + 2];
  vec4 dummy, l, m, h;
  /* Left nodes. */
  h = max(max(L123, L456), L789);
  /* Right nodes. */
  l = min(min(H123, H456), H789);
  /* Center nodes. */
  lmh(M123, M456, M789, dummy, m, dummy);
  /* Last bottom nodes. */
  lmh(l, m, h, dummy, m, dummy);

  return m;
}

void main()
{
  /* OPTI(fclem) Could early return on some tiles. */

  outColor = median_filter(colorBuffer, uvcoordsvar.xy);
  outWeight = median_filter(weightBuffer, uvcoordsvar.xy).r;
}