OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
centroid.cs
Go to the documentation of this file.
1 #version 310 es
2 
3 /* Copyright (c) 2015-2017, ARM Limited and Contributors
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge,
8  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 precision highp float;
24 precision highp image3D;
25 layout (local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
26 layout (binding = 0, r32f) uniform readonly image3D inSurface;
27 layout (binding = 1, rgba8) uniform writeonly image3D outCentroid;
28 
29 layout (binding = 2) uniform atomic_uint outCount;
30 layout (binding = 3, std430) buffer IndexBuffer {
31  uint outIndices[];
32 };
33 
34 uniform float voxel_mode;
35 
36 // return: offset (x, y, z) in the local cell
37 // and: if the cell was on the surface (w)
38 vec4 ComputeCentroid(ivec3 texel)
39 {
40  // Load the isovalue at each corner of the cube
41  float val[8] = float[8](
42  imageLoad(inSurface, texel + ivec3(0, 0, 0)).r,
43  imageLoad(inSurface, texel + ivec3(1, 0, 0)).r,
44  imageLoad(inSurface, texel + ivec3(1, 0, 1)).r,
45  imageLoad(inSurface, texel + ivec3(0, 0, 1)).r,
46  imageLoad(inSurface, texel + ivec3(0, 1, 0)).r,
47  imageLoad(inSurface, texel + ivec3(1, 1, 0)).r,
48  imageLoad(inSurface, texel + ivec3(1, 1, 1)).r,
49  imageLoad(inSurface, texel + ivec3(0, 1, 1)).r
50  );
51 
52  // Construct a mask where a bit is set if the
53  // corner is below the isovalue
54  int mask = 0;
55  if (val[0] < 0.0) mask |= 1;
56  if (val[1] < 0.0) mask |= 2;
57  if (val[2] < 0.0) mask |= 4;
58  if (val[3] < 0.0) mask |= 8;
59  if (val[4] < 0.0) mask |= 16;
60  if (val[5] < 0.0) mask |= 32;
61  if (val[6] < 0.0) mask |= 64;
62  if (val[7] < 0.0) mask |= 128;
63 
64  // Early termination if we are either fully inside or
65  // fully outside the isosurface.
66  if (mask == 0 || mask == 0xff)
67  return vec4(0.0);
68 
69  vec3 cube_vertices[8] = vec3[8](
70  vec3(-1.0, -1.0, -1.0),
71  vec3(+1.0, -1.0, -1.0),
72  vec3(+1.0, -1.0, +1.0),
73  vec3(-1.0, -1.0, +1.0),
74  vec3(-1.0, +1.0, -1.0),
75  vec3(+1.0, +1.0, -1.0),
76  vec3(+1.0, +1.0, +1.0),
77  vec3(-1.0, +1.0, +1.0)
78  );
79 
80  // To make it easier to compute intersection points
81  // we store the indices of the edge's vertices. I.e.
82  // edge number 0 has endpoint number 0 and 1.
83  int cube_edges[24] = int[24](
84  0, 1,
85  1, 2,
86  2, 3,
87  3, 0,
88 
89  4, 5,
90  5, 6,
91  6, 7,
92  7, 4,
93 
94  0, 4,
95  1, 5,
96  2, 6,
97  3, 7
98  );
99 
100  // Like Paul Bourke, we construct an edge table which
101  // maps the above mask to which edges that cross the
102  // isoline level.
103  int edge_table[256] = int[256](
104  0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
105  0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
106  0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
107  0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
108  0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
109  0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
110  0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
111  0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
112  0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
113  0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
114  0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
115  0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
116  0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
117  0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
118  0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
119  0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
120  0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
121  0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
122  0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
123  0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
124  0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
125  0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
126  0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
127  0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
128  0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
129  0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
130  0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
131  0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
132  0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
133  0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
134  0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
135  0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 );
136 
137  int edge_mask = edge_table[mask];
138 
139  // For each edge in the cube
140  int edge_crossings = 0;
141  vec3 offset = vec3(0.0);
142  for (int i = 0; i < 12; i++)
143  {
144  // Skip if edge does not cross the zero level
145  if ((edge_mask & (1 << i)) == 0)
146  continue;
147 
148  // Unpack vertices of the edge on the cube
149  int ei0 = cube_edges[i * 2];
150  int ei1 = cube_edges[i * 2 + 1];
151  vec3 e0 = cube_vertices[ei0];
152  vec3 e1 = cube_vertices[ei1];
153 
154  // Unpack potential function values
155  float v0 = val[ei0];
156  float v1 = val[ei1];
157 
158  // Compute intersection point by linear interpolation
159  float t = clamp((0.0 - v0) / (v1 - v0), 0.0, 1.0);
160  offset += e0 + t * (e1 - e0); // And accumulate
161 
162  edge_crossings++;
163  }
164 
165  // Compute the average
166  offset /= float(edge_crossings);
167 
168  // If we don't offset the vertices we get a voxel-type mesh
169  offset *= 1.0 - voxel_mode;
170 
171  // Finally, since we were on the surface, we write out this
172  // cell's index to the index buffer.
173  ivec3 size = imageSize(outCentroid);
174  uint unique = atomicCounterIncrement(outCount);
175  int index = texel.z * size.x * size.y + texel.y * size.x + texel.x;
176  outIndices[unique] = uint(index);
177 
178  return vec4(offset, 1.0);
179 }
180 
181 void main()
182 {
183  ivec3 texel = ivec3(gl_GlobalInvocationID.xyz);
184  vec4 v = ComputeCentroid(texel);
185 
186  // Remap to fit into 8-bit
187  vec3 offset = vec3(0.5) + 0.5 * v.xyz;
188 
189  imageStore(outCentroid, texel, vec4(offset, v.w));
190 }
const GLfloat * v
Definition: gl2ext.h:2231
void main()
Definition: centroid.cs:181
Definition: matrix.h:51
GLboolean r
Definition: gl2ext.h:306
GLenum GLuint GLintptr offset
Definition: gl2ext.h:629
float clamp(float x, float min, float max)
Definition: noise.cpp:24
Definition: matrix.h:75
GLuint index
Definition: gl2ext.h:300
vec4 ComputeCentroid(ivec3 texel)
Definition: centroid.cs:38
precision highp float
Definition: centroid.cs:23
uniform float voxel_mode
Definition: centroid.cs:32
layout(local_size_x=4, local_size_y=4, local_size_z=4) in
float w
Definition: matrix.h:80
GLenum GLuint GLintptr GLsizeiptr size
Definition: gl2ext.h:629
void uniform(string name, const mat4 &v)
Definition: glutil.cpp:97
GLint GLint GLint GLint GLint x
Definition: gl2ext.h:574
GLenum GLuint buffer
Definition: gl2ext.h:628
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
Definition: gl2ext.h:575
GLint GLfloat v0
Definition: gl2ext.h:1484
GLint GLfloat GLfloat v1
Definition: gl2ext.h:1488
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition: gl2ext.h:818
precision highp image3D
Definition: centroid.cs:24