1 | #version 150 |
---|
2 | |
---|
3 | // Ogre port of Nvidia's IsoSurf.cg file |
---|
4 | // Modified code follows. See http://developer.download.nvidia.com/SDK/10/opengl/samples.html for original |
---|
5 | // |
---|
6 | // Cg port of Yury Uralsky's metaball FX shader |
---|
7 | // |
---|
8 | // Authors: Simon Green and Yury Urlasky |
---|
9 | // Email: sdkfeedback@nvidia.com |
---|
10 | // |
---|
11 | // Copyright (c) NVIDIA Corporation. All rights reserved. |
---|
12 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
13 | |
---|
14 | // Size of the sampling grid |
---|
15 | in VertexData { |
---|
16 | vec3 N; |
---|
17 | vec2 Field; |
---|
18 | } VertexIn[]; |
---|
19 | |
---|
20 | out vec3 oNormal; |
---|
21 | |
---|
22 | uniform float IsoValue; |
---|
23 | |
---|
24 | layout(lines_adjacency) in; |
---|
25 | layout(triangle_strip, max_vertices = 4) out; |
---|
26 | |
---|
27 | // TODO: Change this from outputting triangles to a triangle strip |
---|
28 | |
---|
29 | |
---|
30 | // Estimate where isosurface intersects grid edge with endpoints v0, v1 |
---|
31 | void CalcIntersection(vec4 Pos0, |
---|
32 | vec3 N0, |
---|
33 | vec2 Field0, |
---|
34 | vec4 Pos1, |
---|
35 | vec3 N1, |
---|
36 | vec2 Field1) |
---|
37 | { |
---|
38 | float t = (IsoValue - Field0.x) / (Field1.x - Field0.x); |
---|
39 | gl_Position = mix(Pos0, Pos1, t); |
---|
40 | oNormal = mix(N0, N1, t); |
---|
41 | EmitVertex(); |
---|
42 | } |
---|
43 | |
---|
44 | // Geometry shader |
---|
45 | // input: line with adjacency (tetrahedron) |
---|
46 | // outputs: zero, one or two triangles depending if isosurface intersects tetrahedron |
---|
47 | void main() |
---|
48 | { |
---|
49 | // construct index for this tetrahedron |
---|
50 | uint index = uint((int(VertexIn[0].Field.y) << 3) | |
---|
51 | (int(VertexIn[1].Field.y) << 2) | |
---|
52 | (int(VertexIn[2].Field.y) << 1) | |
---|
53 | int(VertexIn[3].Field.y)); |
---|
54 | |
---|
55 | // don't bother if all vertices out or all vertices inside isosurface |
---|
56 | if (index > uint(0) && index < uint(15)) |
---|
57 | { |
---|
58 | // Uber-compressed version of the edge table. |
---|
59 | uint edgeListHex[8] = |
---|
60 | uint[8](uint(0x0001cde0), uint(0x98b08c9d), uint(0x674046ce), uint(0x487bc480), |
---|
61 | uint(0x21301d2e), uint(0x139bd910), uint(0x26376e20), uint(0x3b700000)); |
---|
62 | |
---|
63 | uint edgeValFull = edgeListHex[index/uint(2)]; |
---|
64 | uint three = uint(0x3); |
---|
65 | uint edgeVal = (index % uint(2) == uint(1)) ? (edgeValFull & uint(0xFFFF)) : ((edgeValFull >> 16) & uint(0xFFFF)); |
---|
66 | ivec4 e0 = ivec4((edgeVal >> 14) & three, (edgeVal >> 12) & three, (edgeVal >> 10) & three, (edgeVal >> 8) & three); |
---|
67 | ivec4 e1 = ivec4((edgeVal >> 6) & three, (edgeVal >> 4) & three, (edgeVal >> 2) & three, (edgeVal >> 0) & three); |
---|
68 | |
---|
69 | CalcIntersection(gl_in[e0.x].gl_Position, VertexIn[e0.x].N, VertexIn[e0.x].Field, |
---|
70 | gl_in[e0.y].gl_Position, VertexIn[e0.y].N, VertexIn[e0.y].Field); |
---|
71 | CalcIntersection(gl_in[e0.z].gl_Position, VertexIn[e0.z].N, VertexIn[e0.z].Field, |
---|
72 | gl_in[e0.w].gl_Position, VertexIn[e0.w].N, VertexIn[e0.w].Field); |
---|
73 | CalcIntersection(gl_in[e1.x].gl_Position, VertexIn[e1.x].N, VertexIn[e1.x].Field, |
---|
74 | gl_in[e1.y].gl_Position, VertexIn[e1.y].N, VertexIn[e1.y].Field); |
---|
75 | |
---|
76 | // Emit additional triangle, if necessary |
---|
77 | if (e1.z != -1) { |
---|
78 | CalcIntersection(gl_in[e1.z].gl_Position, VertexIn[e1.z].N, VertexIn[e1.z].Field, |
---|
79 | gl_in[e1.w].gl_Position, VertexIn[e1.w].N, VertexIn[e1.w].Field); |
---|
80 | } |
---|
81 | EndPrimitive(); |
---|
82 | } |
---|
83 | } |
---|