File: fragment_flood.glsl

package info (click to toggle)
python-vispy 0.15.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,868 kB
  • sloc: python: 59,799; javascript: 6,800; makefile: 69; sh: 6
file content (159 lines) | stat: -rwxr-xr-x 5,690 bytes parent folder | download | duplicates (4)
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Jump flooding algorithm for EDT according
// to Danielsson (1980) and Guodong Rong (2007).
// Implementation by Stefan Gustavson 2010.
// This code is in the public domain.

// This code represents one iteration of the flood filling.
// You need to run it multiple times with different step
// lengths to perform a full distance transformation.

uniform sampler2D texture;
varying float stepu;
varying float stepv;
varying vec2 uv;

// Helper functions to remap unsigned normalized floats [0.0,1.0]
// coming from an integer texture to the range we need [-1, 1].
// The transformations are very specifically designed to map
// integer texel values exactly to pixel centers, and vice versa.
// (See fragment_seed.glsl for details.)

vec2 remap(vec4 floatdata) {
    vec2 scaleddata = vec2(floatdata.x * 65280. + floatdata.z * 255.,
                           floatdata.y * 65280. + floatdata.w * 255.);
    return scaleddata / 32768. - 1.0;
}

vec4 remap_inv(vec2 floatvec) {
    vec2 data = (floatvec + 1.0) * 32768.;
    float x = floor(data.x / 256.);
    float y = floor(data.y / 256.);
    return vec4(x, y, data.x - x * 256., data.y - y * 256.) / 255.;
}

void main( void )
{
  // Search for better distance vectors among 8 candidates
  vec2 stepvec; // Relative offset to candidate being tested
  vec2 newvec;  // Absolute position of that candidate
  vec3 newseed; // Closest point from that candidate (.xy) and its distance (.z)
  vec3 bestseed; // Closest seed so far
  bestseed.xy = remap(texture2D(texture, uv).rgba);
  bestseed.z = length(bestseed.xy);

  // This code depends on the texture having a CLAMP_TO_BORDER
  // attribute and a border color with R = 0.
  // The commented-out lines handle clamping to the edge explicitly
  // to avoid propagating incorrect vectors when looking outside
  // of [0,1] in u and/or v.
  // These explicit conditionals cause a slowdown of about 25%.
  // Sometimes a periodic transform with edge repeats might be
  // what you want. In that case, the texture wrap mode can be
  // set to GL_REPEAT, and the shader code can be left unchanged.

  stepvec = vec2(-stepu, -stepv);
  newvec = uv + stepvec;
  if ( all( bvec4( lessThan(newvec, vec2(1.0)), greaterThan(newvec, vec2(0.0)) ) ) ) {
    newseed.xy = remap(texture2D(texture, newvec).rgba);
    if(newseed.x > -0.99999) { // if the new seed is not "indeterminate distance"
      newseed.xy = newseed.xy + stepvec;
      newseed.z = length(newseed.xy);
      if(newseed.z < bestseed.z) {
        bestseed = newseed;
      }
    }
  }

  stepvec = vec2(-stepu, 0.0);
  newvec = uv + stepvec;
  if ( all( bvec4( lessThan(newvec, vec2(1.0)), greaterThan(newvec, vec2(0.0)) ) ) ) {
    newseed.xy = remap(texture2D(texture, newvec).rgba);
    if(newseed.x > -0.99999) { // if the new seed is not "indeterminate distance"
      newseed.xy = newseed.xy + stepvec;
      newseed.z = length(newseed.xy);
      if(newseed.z < bestseed.z) {
        bestseed = newseed;
      }
    }
  }

  stepvec = vec2(-stepu, stepv);
  newvec = uv + stepvec;
  if ( all( bvec4( lessThan(newvec, vec2(1.0)), greaterThan(newvec, vec2(0.0)) ) ) ) {
    newseed.xy = remap(texture2D(texture, newvec).rgba);
    if(newseed.x > -0.99999) { // if the new seed is not "indeterminate distance"
      newseed.xy = newseed.xy + stepvec;
      newseed.z = length(newseed.xy);
      if(newseed.z < bestseed.z) {
        bestseed = newseed;
      }
    }
  }

  stepvec = vec2(0.0, -stepv);
  newvec = uv + stepvec;
  if ( all( bvec4( lessThan(newvec, vec2(1.0)), greaterThan(newvec, vec2(0.0)) ) ) ) {
    newseed.xy = remap(texture2D(texture, newvec).rgba);
    if(newseed.x > -0.99999) { // if the new seed is not "indeterminate distance"
      newseed.xy = newseed.xy + stepvec;
      newseed.z = length(newseed.xy);
      if(newseed.z < bestseed.z) {
        bestseed = newseed;
      }
    }
  }

  stepvec = vec2(0.0, stepv);
  newvec = uv + stepvec;
  if ( all( bvec4( lessThan(newvec, vec2(1.0)), greaterThan(newvec, vec2(0.0)) ) ) ) {
    newseed.xy = remap(texture2D(texture, newvec).rgba);
    if(newseed.x > -0.99999) { // if the new seed is not "indeterminate distance"
      newseed.xy = newseed.xy + stepvec;
      newseed.z = length(newseed.xy);
      if(newseed.z < bestseed.z) {
        bestseed = newseed;
      }
    }
  }

  stepvec = vec2(stepu, -stepv);
  newvec = uv + stepvec;
  if ( all( bvec4( lessThan(newvec, vec2(1.0)), greaterThan(newvec, vec2(0.0)) ) ) ) {
    newseed.xy = remap(texture2D(texture, newvec).rgba);
    if(newseed.x > -0.99999) { // if the new seed is not "indeterminate distance"
      newseed.xy = newseed.xy + stepvec;
      newseed.z = length(newseed.xy);
      if(newseed.z < bestseed.z) {
        bestseed = newseed;
      }
    }
  }

  stepvec = vec2(stepu, 0.0);
  newvec = uv + stepvec;
  if ( all( bvec4( lessThan(newvec, vec2(1.0)), greaterThan(newvec, vec2(0.0)) ) ) ) {
    newseed.xy = remap(texture2D(texture, newvec).rgba);
    if(newseed.x > -0.99999) { // if the new seed is not "indeterminate distance"
      newseed.xy = newseed.xy + stepvec;
      newseed.z = length(newseed.xy);
      if(newseed.z < bestseed.z) {
        bestseed = newseed;
      }
    }
  }

  stepvec = vec2(stepu, stepv);
  newvec = uv + stepvec;
  if ( all( bvec4( lessThan(newvec, vec2(1.0)), greaterThan(newvec, vec2(0.0)) ) ) ) {
    newseed.xy = remap(texture2D(texture, newvec).rgba);
    if(newseed.x > -0.99999) { // if the new seed is not "indeterminate distance"
      newseed.xy = newseed.xy + stepvec;
      newseed.z = length(newseed.xy);
      if(newseed.z < bestseed.z) {
        bestseed = newseed;
      }
    }
  }

  gl_FragColor = remap_inv(bestseed.xy);
}