ngsolve-webgpu 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ngsolve_webgpu/__init__.py +0 -0
- ngsolve_webgpu/_version.py +21 -0
- ngsolve_webgpu/animate.py +76 -0
- ngsolve_webgpu/cf.py +369 -0
- ngsolve_webgpu/clipping.py +155 -0
- ngsolve_webgpu/geometry.py +376 -0
- ngsolve_webgpu/isosurface.py +101 -0
- ngsolve_webgpu/jupyter.py +168 -0
- ngsolve_webgpu/lic.py +115 -0
- ngsolve_webgpu/mesh.py +424 -0
- ngsolve_webgpu/shaders/clipping/common.wgsl +120 -0
- ngsolve_webgpu/shaders/clipping/compute.wgsl +30 -0
- ngsolve_webgpu/shaders/clipping/render.wgsl +37 -0
- ngsolve_webgpu/shaders/compute.wgsl +59 -0
- ngsolve_webgpu/shaders/elements3d.wgsl +83 -0
- ngsolve_webgpu/shaders/eval/common.wgsl +14 -0
- ngsolve_webgpu/shaders/eval/seg.wgsl +30 -0
- ngsolve_webgpu/shaders/eval/tet.wgsl +61 -0
- ngsolve_webgpu/shaders/eval/trig.wgsl +121 -0
- ngsolve_webgpu/shaders/eval.wgsl +0 -0
- ngsolve_webgpu/shaders/geo_edge.wgsl +55 -0
- ngsolve_webgpu/shaders/geo_face.wgsl +47 -0
- ngsolve_webgpu/shaders/geo_vertex.wgsl +71 -0
- ngsolve_webgpu/shaders/isosurface/compute.wgsl +63 -0
- ngsolve_webgpu/shaders/isosurface/negative_clipping.wgsl +13 -0
- ngsolve_webgpu/shaders/isosurface/negative_surface.wgsl +15 -0
- ngsolve_webgpu/shaders/isosurface/render.wgsl +50 -0
- ngsolve_webgpu/shaders/line_integral_convolution.wgsl +100 -0
- ngsolve_webgpu/shaders/mesh.wgsl +296 -0
- ngsolve_webgpu/shaders/numbers.wgsl +40 -0
- ngsolve_webgpu/shaders/shader.wgsl +111 -0
- ngsolve_webgpu/shaders/uniforms.wgsl +93 -0
- ngsolve_webgpu-0.0.1.dist-info/METADATA +13 -0
- ngsolve_webgpu-0.0.1.dist-info/RECORD +37 -0
- ngsolve_webgpu-0.0.1.dist-info/WHEEL +5 -0
- ngsolve_webgpu-0.0.1.dist-info/licenses/LICENSE +504 -0
- ngsolve_webgpu-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
@group(0) @binding(24) var<storage> subtrigs: array<SubTrig>;
|
|
3
|
+
|
|
4
|
+
struct VertexOutputClip {
|
|
5
|
+
@builtin(position) fragPosition: vec4<f32>,
|
|
6
|
+
@location(0) p: vec3<f32>,
|
|
7
|
+
@location(1) n: vec3<f32>,
|
|
8
|
+
@location(2) lam: vec3<f32>,
|
|
9
|
+
@location(3) @interpolate(flat) elnr: u32
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
@vertex
|
|
13
|
+
fn vertex_main(@builtin(vertex_index) vertId: u32,
|
|
14
|
+
@builtin(instance_index) trigId: u32)
|
|
15
|
+
-> VertexOutputClip
|
|
16
|
+
{
|
|
17
|
+
let trig = subtrigs[trigId];
|
|
18
|
+
let points = get_tet_points(trig.id);
|
|
19
|
+
var lam = vec4<f32>(trig.lam[vertId], 1.);
|
|
20
|
+
lam[3] = 1.0 - lam[0] - lam[1] - lam[2];
|
|
21
|
+
var p = vec3<f32>(0.0, 0.0, 0.0);
|
|
22
|
+
for(var i = 0u; i < 4u; i = i + 1u) {
|
|
23
|
+
p = p + lam[i] * points[i];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return VertexOutputClip(cameraMapPoint(p), p, -u_clipping.plane.xyz, lam.xyz,
|
|
27
|
+
trig.id);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@fragment
|
|
31
|
+
fn fragment_main(input: VertexOutputClip) -> @location(0) vec4<f32>
|
|
32
|
+
{
|
|
33
|
+
let value = evalTet(&function_values_3d, input.elnr, 0, input.lam);
|
|
34
|
+
return lightCalcColor(input.n, getColor(value));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
@compute @workgroup_size(16, 16, 1)
|
|
2
|
+
fn create_mesh(@builtin(num_workgroups) n_groups: vec3<u32>, @builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {
|
|
3
|
+
let n: u32 = n_groups.x * 16;
|
|
4
|
+
let h: f32 = 1.0 / (f32(n) + 1.);
|
|
5
|
+
|
|
6
|
+
if lid.x == 0 && lid.y == 0 && wid.x == 0 {
|
|
7
|
+
create_mesh_trig_function_values[0] = 1.0;
|
|
8
|
+
create_mesh_trig_function_values[1] = 1.0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let ix: u32 = wid.x * 16u + lid.x;
|
|
12
|
+
let x: f32 = h * f32(ix);
|
|
13
|
+
for (var iy: u32 = wid.y * 16u + lid.y; iy < n + 1; iy += 16u) {
|
|
14
|
+
let y: f32 = h * f32(iy);
|
|
15
|
+
for (var k: u32 = 0u; k < 2u; k++) {
|
|
16
|
+
if iy < n {
|
|
17
|
+
let i = 2 * (ix + iy * n) + k;
|
|
18
|
+
let i1 = ix + iy * (n + 1);
|
|
19
|
+
var px: array<f32, 3>;
|
|
20
|
+
var py: array<f32, 3>;
|
|
21
|
+
if k == 0 {
|
|
22
|
+
px = array<f32, 3>(x, x + h, x);
|
|
23
|
+
py = array<f32, 3>(y, y, y + h);
|
|
24
|
+
} else {
|
|
25
|
+
px = array<f32, 3>(x + h, x + h, x);
|
|
26
|
+
py = array<f32, 3>(y, y + h, y + h);
|
|
27
|
+
}
|
|
28
|
+
create_mesh_trigs_p1[i].index = 1;
|
|
29
|
+
for (var pi: u32 = 0u; pi < 3u; pi++) {
|
|
30
|
+
create_mesh_trigs_p1[i].p[3 * pi + 0] = px[pi];
|
|
31
|
+
create_mesh_trigs_p1[i].p[3 * pi + 1] = py[pi];
|
|
32
|
+
create_mesh_trigs_p1[i].p[3 * pi + 2] = 0.0;
|
|
33
|
+
create_mesh_trig_function_values[2 + 3 * i + pi] = px[pi];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if k == 0 {
|
|
37
|
+
create_mesh_index_buffer[3 * i] = i1;
|
|
38
|
+
create_mesh_index_buffer[3 * i + 1] = i1 + 1;
|
|
39
|
+
create_mesh_index_buffer[3 * i + 2] = i1 + n + 1;
|
|
40
|
+
} else {
|
|
41
|
+
create_mesh_index_buffer[3 * i] = i1 + 1;
|
|
42
|
+
create_mesh_index_buffer[3 * i + 1] = i1 + n + 1 + 1;
|
|
43
|
+
create_mesh_index_buffer[3 * i + 2] = i1 + n + 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let iv = 3 * (ix + iy * (n + 1));
|
|
49
|
+
create_mesh_vertex_buffer[iv] = x;
|
|
50
|
+
create_mesh_vertex_buffer[iv + 1] = y;
|
|
51
|
+
create_mesh_vertex_buffer[iv + 2] = 0.0;
|
|
52
|
+
|
|
53
|
+
if ix + 1 == n {
|
|
54
|
+
create_mesh_vertex_buffer[iv + 3] = x + h;
|
|
55
|
+
create_mesh_vertex_buffer[iv + 4] = y;
|
|
56
|
+
create_mesh_vertex_buffer[iv + 5] = 0.;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
|
|
2
|
+
@group(0) @binding(12) var<storage> vertices : array<f32>;
|
|
3
|
+
@group(0) @binding(20) var<uniform> u_mesh : MeshUniforms;
|
|
4
|
+
@group(0) @binding(25) var<storage> u_tets : array<Tet>;
|
|
5
|
+
|
|
6
|
+
const TET_FACES = array(
|
|
7
|
+
vec3u(0u, 2u, 1u),
|
|
8
|
+
vec3u(0u, 1u, 3u),
|
|
9
|
+
vec3u(1u, 2u, 3u),
|
|
10
|
+
vec3u(2u, 0u, 3u)
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
struct MeshUniforms {
|
|
14
|
+
subdivision: u32,
|
|
15
|
+
shrink: f32,
|
|
16
|
+
|
|
17
|
+
padding0: f32,
|
|
18
|
+
padding1: f32,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
struct Tet { p: array<u32, 4>, index: u32, padding: u32};
|
|
22
|
+
|
|
23
|
+
struct MeshFragmentInput {
|
|
24
|
+
@builtin(position) fragPosition: vec4<f32>,
|
|
25
|
+
@location(0) p: vec3<f32>,
|
|
26
|
+
@location(1) n: vec3<f32>,
|
|
27
|
+
@location(2) @interpolate(flat) id: u32,
|
|
28
|
+
@location(3) @interpolate(flat) index: u32,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
fn calcMeshFace(p: array<vec3<f32>, 3>,
|
|
32
|
+
vertId: u32, nr: u32, index: u32,
|
|
33
|
+
lams: array<vec3<f32>,3>) -> MeshFragmentInput
|
|
34
|
+
{
|
|
35
|
+
let n = cross(p[1] - p[0], p[2] - p[0]);
|
|
36
|
+
let point = p[vertId % 3];
|
|
37
|
+
let position = cameraMapPoint(point);
|
|
38
|
+
return MeshFragmentInput(position, point, n, nr, index);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@vertex
|
|
43
|
+
fn vertex_main(@builtin(vertex_index) vertId: u32,
|
|
44
|
+
@builtin(instance_index) elId: u32)
|
|
45
|
+
-> MeshFragmentInput
|
|
46
|
+
{
|
|
47
|
+
const N: u32 = 4u;
|
|
48
|
+
let faceId: u32 = vertId / 3u;
|
|
49
|
+
let el = u_tets[elId];
|
|
50
|
+
var p: array<vec3<f32>, 4>;
|
|
51
|
+
|
|
52
|
+
var lam = vec4<f32>(0.0, 0.0, 0.0, 0.0);
|
|
53
|
+
var center = vec3<f32>(0.0, 0.0, 0.0);
|
|
54
|
+
for (var i = 0u; i < N; i++) {
|
|
55
|
+
let n = 3u * el.p[i];
|
|
56
|
+
p[i] = vec3<f32>(vertices[n], vertices[n + 1u], vertices[n + 2u]);
|
|
57
|
+
center += p[i] / f32(N);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
for (var i = 0u; i < 4u; i++) {
|
|
62
|
+
p[i] = mix(center, p[i], u_mesh.shrink);
|
|
63
|
+
}
|
|
64
|
+
var lams = array<vec3<f32>, 4>(
|
|
65
|
+
vec3<f32>(1.0, 0.0, 0.0),
|
|
66
|
+
vec3<f32>(0.0, 1.0, 0.0),
|
|
67
|
+
vec3<f32>(0.0, 0.0, 1.0),
|
|
68
|
+
vec3<f32>(0.0, 0.0, 0.0),
|
|
69
|
+
);
|
|
70
|
+
let pi = TET_FACES[faceId];
|
|
71
|
+
let points = array<vec3<f32>, 3>(p[pi[0]], p[pi[1]], p[pi[2]]);
|
|
72
|
+
|
|
73
|
+
return calcMeshFace(points, vertId, elId, el.index,
|
|
74
|
+
array<vec3<f32>, 3> (lams[pi[0]], lams[pi[1]], lams[pi[2]]));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@fragment
|
|
78
|
+
fn fragment_main(input: MeshFragmentInput) -> @location(0) vec4<f32>
|
|
79
|
+
{
|
|
80
|
+
checkClipping(input.p);
|
|
81
|
+
let color = vec4<f32>(1., 0., 0., 1.);
|
|
82
|
+
return lightCalcColor(input.n, color);
|
|
83
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
@group(0) @binding(13) var<storage> u_function_values_3d : array<f32>;
|
|
3
|
+
@group(0) @binding(10) var<storage> u_function_values_2d : array<f32>;
|
|
4
|
+
@group(0) @binding(14) var<storage> u_curvature_values_2d : array<f32>;
|
|
5
|
+
@group(0) @binding(15) var<uniform> u_curvature_subdivision : u32;
|
|
6
|
+
@group(0) @binding(16) var<storage> u_deformation_values_2d : array<f32>;
|
|
7
|
+
@group(0) @binding(17) var<uniform> u_deformation_scale : f32;
|
|
8
|
+
@group(0) @binding(55) var<storage> u_function_component: i32;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
// storing number of components and order of basis functions in first two entries
|
|
13
|
+
const VALUES_OFFSET: u32 = 2;
|
|
14
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#import eval/common
|
|
2
|
+
|
|
3
|
+
fn evalSeg(data: ptr<storage, array<f32>, read>, id: u32, icomp: u32, lam: f32) -> f32 {
|
|
4
|
+
let order: u32 = u32((*data)[1]);
|
|
5
|
+
let ncomp: u32 = u32((*data)[0]);
|
|
6
|
+
let ndof: u32 = order + 1;
|
|
7
|
+
|
|
8
|
+
let offset: u32 = ndof * id + VALUES_OFFSET;
|
|
9
|
+
let stride: u32 = ncomp;
|
|
10
|
+
|
|
11
|
+
var v: array<f32, 7>;
|
|
12
|
+
for (var i: u32 = 0u; i < ndof; i++) {
|
|
13
|
+
v[i] = (*data)[offset + i * stride];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
for (var i: u32 = 0u; i < ndof; i++) {
|
|
17
|
+
v[i] = (*data)[offset + i * stride];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let b = vec2f(lam, 1.0 - lam);
|
|
21
|
+
|
|
22
|
+
for (var n = order; n > 0; n--) {
|
|
23
|
+
for (var i = 0u; i < n; i++) {
|
|
24
|
+
v[i] = dot(b, vec2f(v[i], v[i + 1]));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return v[0];
|
|
29
|
+
}
|
|
30
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
|
|
2
|
+
fn factorial(n: u32) -> u32 {
|
|
3
|
+
var result: u32 = 1u;
|
|
4
|
+
var i: u32 = 2u;
|
|
5
|
+
while (i <= n) {
|
|
6
|
+
result = result * i;
|
|
7
|
+
i = i + 1u;
|
|
8
|
+
}
|
|
9
|
+
return result;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
fn mypow(val: f32, exp: u32) -> f32 {
|
|
13
|
+
var result: f32 = 1.0;
|
|
14
|
+
for (var i: u32 = 0u; i < exp; i = i + 1u) {
|
|
15
|
+
result = result * val;
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
fn evalTet(data: ptr<storage, array<f32>, read>,
|
|
21
|
+
id: u32, icomp: u32, lam: vec3<f32>) -> f32 {
|
|
22
|
+
let ncomp: u32 = u32((*data)[0]);
|
|
23
|
+
let order: u32 = u32((*data)[1]);
|
|
24
|
+
var ndof: u32 = ((order + 1u) * (order + 2u) * (order + 3u)) / 6u;
|
|
25
|
+
|
|
26
|
+
let offset: u32 = ndof * id + VALUES_OFFSET;
|
|
27
|
+
let stride: u32 = ncomp;
|
|
28
|
+
|
|
29
|
+
var value: f32 = 0.0;
|
|
30
|
+
var i = 0u;
|
|
31
|
+
for(var d: u32 = 0u; d < order+1u; d++) {
|
|
32
|
+
for(var c: u32 = 0u; c < order+1u-d; c++) {
|
|
33
|
+
for(var b: u32 = 0u; b < order+1u-c-d;b++) {
|
|
34
|
+
let a = order - b - c - d;
|
|
35
|
+
let fac = f32(factorial(order))/f32((factorial(a) * factorial(b) * factorial(c) * factorial(d)));
|
|
36
|
+
value = value + fac * (*data)[offset + i * stride] * mypow(lam.x, a) * mypow(lam.y, b) * mypow(lam.z, c) * mypow(1.0 - lam.x - lam.y - lam.z, d);
|
|
37
|
+
i++;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
// let dy = order + 1u;
|
|
43
|
+
// let dz = (order + 1u) * (order + 2u) / 2u;
|
|
44
|
+
// let b = vec4f(lam.x, lam.y, lam.z, 1.0 - lam.x - lam.y - lam.z);
|
|
45
|
+
|
|
46
|
+
// for (var n = order; n > 0u; n--) {
|
|
47
|
+
// var iz0 = 0u;
|
|
48
|
+
// for (var iz = 0u; iz < n; iz++) {
|
|
49
|
+
// var iy0 = iz0;
|
|
50
|
+
// for (var iy = 0u; iy < n - iz; iy++) {
|
|
51
|
+
// for (var ix = 0u; ix < n - iz - iy; ix++) {
|
|
52
|
+
// v[iy0 + ix] = dot(b, vec4f(v[iy0 + ix], v[iy0 + ix + 1u], v[iy0 + ix + dy - iy], v[iy0 + ix + dz - iz]));
|
|
53
|
+
// }
|
|
54
|
+
// iy0 += dy - iy - iz;
|
|
55
|
+
// }
|
|
56
|
+
// iz0 += dz - (n - 1u - iz);
|
|
57
|
+
// }
|
|
58
|
+
// }
|
|
59
|
+
|
|
60
|
+
// return v[0];
|
|
61
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#import eval/common
|
|
2
|
+
|
|
3
|
+
fn evalTrig(data: ptr<storage, array<f32>, read>, id: u32, icomp: i32, lam: vec2<f32>) -> f32 {
|
|
4
|
+
var order: i32 = i32((*data)[1]);
|
|
5
|
+
let ncomp: u32 = u32((*data)[0]);
|
|
6
|
+
var ndof: u32 = u32((order + 1) * (order + 2) / 2);
|
|
7
|
+
|
|
8
|
+
var v: array<f32, 28>;
|
|
9
|
+
let offset: u32 = ndof * id * ncomp + VALUES_OFFSET;
|
|
10
|
+
let stride: u32 = ncomp;
|
|
11
|
+
|
|
12
|
+
if icomp == -1 {
|
|
13
|
+
// norm of vector
|
|
14
|
+
for (var i: u32 = 0u; i < ndof; i++) {
|
|
15
|
+
v[i] = 0.0;
|
|
16
|
+
for (var j: u32 = 0u; j < ncomp; j++) {
|
|
17
|
+
v[i] += (*data)[offset + i * stride + j] * (*data)[offset + i * stride + j];
|
|
18
|
+
}
|
|
19
|
+
v[i] = sqrt(v[i]);
|
|
20
|
+
}
|
|
21
|
+
} else {
|
|
22
|
+
for (var i: u32 = 0u; i < ndof; i++) {
|
|
23
|
+
v[i] = (*data)[offset + u32(icomp) + i * stride];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let dy = order + 1;
|
|
28
|
+
let b = vec3f(lam.x, lam.y, 1.0 - lam.x - lam.y);
|
|
29
|
+
|
|
30
|
+
for (var n = order; n > 0; n--) {
|
|
31
|
+
var i0 = 0;
|
|
32
|
+
for (var iy = 0; iy < n; iy++) {
|
|
33
|
+
for (var ix = 0; ix < n - iy; ix++) {
|
|
34
|
+
v[i0 + ix] = dot(b, vec3f(v[i0 + ix], v[i0 + ix + 1], v[i0 + ix + dy - iy]));
|
|
35
|
+
}
|
|
36
|
+
i0 += dy - iy;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return v[0];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
fn _evalTrigVec3Data(order: i32, data: array<vec3f, 28>, lam: vec2f, dy: i32) -> vec3f {
|
|
44
|
+
let b = vec3f(lam.x, lam.y, 1.0 - lam.x - lam.y);
|
|
45
|
+
var v: array<vec3f, 28> = data;
|
|
46
|
+
|
|
47
|
+
for (var n = order; n > 0; n--) {
|
|
48
|
+
var i0 = 0;
|
|
49
|
+
for (var iy = 0; iy < n; iy++) {
|
|
50
|
+
for (var ix = 0; ix < n - iy; ix++) {
|
|
51
|
+
v[i0 + ix] = mat3x3<f32>(v[i0 + ix], v[i0 + ix + 1], v[i0 + ix + dy - iy]) * b;
|
|
52
|
+
}
|
|
53
|
+
i0 += dy - iy;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return v[0];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fn evalTrigVec3(data: ptr<storage, array<f32>, read>, id: u32, icomp: i32, lam: vec2<f32>) -> vec3f {
|
|
61
|
+
var order: i32 = i32((*data)[1]);
|
|
62
|
+
let ncomp: u32 = u32((*data)[0]);
|
|
63
|
+
var ndof: u32 = u32((order + 1) * (order + 2) / 2);
|
|
64
|
+
|
|
65
|
+
var v: array<vec3f, 28>;
|
|
66
|
+
let offset: u32 = ndof * id * ncomp + VALUES_OFFSET;
|
|
67
|
+
let stride: u32 = ncomp;
|
|
68
|
+
|
|
69
|
+
for (var i: u32 = 0u; i < ndof; i++) {
|
|
70
|
+
v[i].x = (*data)[offset + u32(icomp) + i * stride + 0];
|
|
71
|
+
v[i].y = (*data)[offset + u32(icomp) + i * stride + 1];
|
|
72
|
+
v[i].z = (*data)[offset + u32(icomp) + i * stride + 2];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return _evalTrigVec3Data(order, v, lam, order+1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fn evalTrigVec3Grad(data: ptr<storage, array<f32>, read>, id: u32, lam: vec2<f32>) -> mat3x3<f32> {
|
|
79
|
+
var order: i32 = i32((*data)[1]);
|
|
80
|
+
let ncomp: u32 = u32((*data)[0]);
|
|
81
|
+
var ndof: u32 = u32((order + 1) * (order + 2) / 2);
|
|
82
|
+
let dy = order + 1;
|
|
83
|
+
|
|
84
|
+
var v: array<vec3f, 28>;
|
|
85
|
+
let offset: u32 = ndof * id * ncomp + VALUES_OFFSET;
|
|
86
|
+
let stride: u32 = ncomp;
|
|
87
|
+
|
|
88
|
+
for (var i: u32 = 0u; i < ndof; i++) {
|
|
89
|
+
v[i].x = (*data)[offset + i * stride + 0];
|
|
90
|
+
v[i].y = (*data)[offset + i * stride + 1];
|
|
91
|
+
v[i].z = (*data)[offset + i * stride + 2];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var result: mat3x3<f32>;
|
|
95
|
+
|
|
96
|
+
result[0] = _evalTrigVec3Data(order, v, lam, dy);
|
|
97
|
+
var vd: array<vec3f, 28>;
|
|
98
|
+
|
|
99
|
+
var i0 = 0;
|
|
100
|
+
for (var iy = 0; iy < order; iy++) {
|
|
101
|
+
for (var ix = 0; ix < order - iy; ix++) {
|
|
102
|
+
vd[i0 + ix] = v[i0 + ix + 1] - v[i0 + ix];
|
|
103
|
+
}
|
|
104
|
+
i0 += dy - iy;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
result[1] = _evalTrigVec3Data(order-1, vd, lam, dy);
|
|
108
|
+
|
|
109
|
+
i0 = 0;
|
|
110
|
+
for (var iy = 0; iy < order; iy++) {
|
|
111
|
+
for (var ix = 0; ix < order - iy; ix++) {
|
|
112
|
+
vd[i0 + ix] = v[i0 + ix + dy - iy] - v[i0 + ix + 1];
|
|
113
|
+
}
|
|
114
|
+
i0 += dy - iy;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
result[2] = _evalTrigVec3Data(order-1, vd, lam, dy);
|
|
118
|
+
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
|
|
File without changes
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
@group(0) @binding(90) var<storage> u_vertices: array<f32>;
|
|
3
|
+
@group(0) @binding(91) var<storage> u_color: array<f32>;
|
|
4
|
+
@group(0) @binding(92) var<uniform> u_thickness: f32;
|
|
5
|
+
@group(0) @binding(93) var<storage> u_indices: array<u32>;
|
|
6
|
+
|
|
7
|
+
struct GeoEdgeInput
|
|
8
|
+
{
|
|
9
|
+
@builtin(position) position: vec4<f32>,
|
|
10
|
+
@location(1) @interpolate(flat) index: u32,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@vertex
|
|
15
|
+
fn vertex_main(@builtin(vertex_index) vertId: u32,
|
|
16
|
+
@builtin(instance_index) instanceId: u32) -> GeoEdgeInput
|
|
17
|
+
{
|
|
18
|
+
let p1 = vec3f(u_vertices[instanceId * 6],
|
|
19
|
+
u_vertices[instanceId * 6 + 1],
|
|
20
|
+
u_vertices[instanceId * 6 + 2]);
|
|
21
|
+
let p2 = vec3f(u_vertices[instanceId * 6 + 3],
|
|
22
|
+
u_vertices[instanceId * 6 + 4],
|
|
23
|
+
u_vertices[instanceId * 6 + 5]);
|
|
24
|
+
let tp1 = cameraMapPoint(p1);
|
|
25
|
+
let tp2 = cameraMapPoint(p2);
|
|
26
|
+
let v = normalize(tp2.xy*tp1.w - tp1.xy*tp2.w);
|
|
27
|
+
let v2 = vec2<f32>(-v.y, v.x);
|
|
28
|
+
var pos: vec4<f32>;
|
|
29
|
+
if(vertId == 0) {
|
|
30
|
+
pos = vec4<f32>(tp1.xy + (-0.5*v.xy + v2) * u_thickness/2.*tp1.w, tp1.zw); }
|
|
31
|
+
else if(vertId == 1) {
|
|
32
|
+
pos = vec4<f32>(tp1.xy + (-0.5*v.xy + - v2) * u_thickness/2.*tp1.w, tp1.zw); }
|
|
33
|
+
else if(vertId == 2) {
|
|
34
|
+
pos = vec4<f32>(tp2.xy + (0.5*v.xy + v2) * u_thickness/2.*tp2.w, tp2.zw); }
|
|
35
|
+
else {
|
|
36
|
+
pos = vec4<f32>(tp2.xy + (0.5*v.xy - v2) * u_thickness/2.*tp2.w, tp2.zw); }
|
|
37
|
+
|
|
38
|
+
return GeoEdgeInput(pos, u_indices[instanceId]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@fragment
|
|
42
|
+
fn fragment_main(input: GeoEdgeInput) -> @location(0) vec4<f32> {
|
|
43
|
+
if (u_color[input.index*4+3] == 0.0) {
|
|
44
|
+
discard;
|
|
45
|
+
}
|
|
46
|
+
return vec4<f32>(u_color[input.index * 4],
|
|
47
|
+
u_color[input.index * 4 + 1],
|
|
48
|
+
u_color[input.index * 4 + 2],
|
|
49
|
+
u_color[input.index * 4 + 3]);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@fragment
|
|
53
|
+
fn fragmentQueryIndex(input: GeoEdgeInput) -> @location(0) vec2<u32> {
|
|
54
|
+
return vec2<u32>(input.index, 1u);
|
|
55
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
@group(0) @binding(90) var<storage> u_vertices : array<f32>;
|
|
3
|
+
@group(0) @binding(91) var<storage> u_normals : array<f32>;
|
|
4
|
+
@group(0) @binding(92) var<storage> u_indices : array<u32>;
|
|
5
|
+
@group(0) @binding(93) var<storage> u_colors: array<f32>;
|
|
6
|
+
|
|
7
|
+
struct GeoFragmentInput {
|
|
8
|
+
@builtin(position) position: vec4<f32>,
|
|
9
|
+
@location(0) p: vec3<f32>,
|
|
10
|
+
@location(1) n: vec3<f32>,
|
|
11
|
+
@location(2) @interpolate(flat) id: u32,
|
|
12
|
+
@location(3) @interpolate(flat) index: u32,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
@vertex
|
|
16
|
+
fn vertex_main(@builtin(vertex_index) vertId: u32,
|
|
17
|
+
@builtin(instance_index) trigId: u32) -> GeoFragmentInput {
|
|
18
|
+
let point = vec3<f32>(u_vertices[trigId * 9 + vertId * 3],
|
|
19
|
+
u_vertices[trigId * 9 + vertId * 3 + 1],
|
|
20
|
+
u_vertices[trigId * 9 + vertId * 3 + 2]);
|
|
21
|
+
let normal = vec3<f32>(u_normals[trigId * 9 + vertId * 3],
|
|
22
|
+
u_normals[trigId * 9 + vertId * 3 + 1],
|
|
23
|
+
u_normals[trigId * 9 + vertId * 3 + 2]);
|
|
24
|
+
let position = cameraMapPoint(point);
|
|
25
|
+
return GeoFragmentInput(position,
|
|
26
|
+
point,
|
|
27
|
+
normal,
|
|
28
|
+
trigId, u_indices[trigId]);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@fragment
|
|
32
|
+
fn fragment_main(input: GeoFragmentInput) -> @location(0) vec4<f32> {
|
|
33
|
+
let color = vec4<f32>(u_colors[input.index * 4],
|
|
34
|
+
u_colors[input.index * 4 + 1],
|
|
35
|
+
u_colors[input.index * 4 + 2],
|
|
36
|
+
u_colors[input.index * 4 + 3]);
|
|
37
|
+
if (color.a == 0.) {
|
|
38
|
+
discard;
|
|
39
|
+
}
|
|
40
|
+
return lightCalcColor(input.n, color);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@fragment
|
|
44
|
+
fn fragmentQueryIndex(input: GeoFragmentInput) -> @location(0) vec2<u32>
|
|
45
|
+
{
|
|
46
|
+
return vec2<u32>(input.index, 2u);
|
|
47
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
|
|
2
|
+
@group(0) @binding(90) var<storage> u_vertices: array<f32>;
|
|
3
|
+
@group(0) @binding(91) var<storage> u_vertex_color: array<f32>;
|
|
4
|
+
@group(0) @binding(92) var<uniform> u_vertex_thickness: f32;
|
|
5
|
+
|
|
6
|
+
struct GeoVertexInput
|
|
7
|
+
{
|
|
8
|
+
@builtin(position) position: vec4<f32>,
|
|
9
|
+
@location(1) pos: vec4<f32>,
|
|
10
|
+
@location(2) pos2: vec4<f32>,
|
|
11
|
+
@location(3) p: vec3<f32>,
|
|
12
|
+
@location(4) @interpolate(flat) index: u32,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@vertex
|
|
17
|
+
fn vertex_main(@builtin(vertex_index) vertId: u32,
|
|
18
|
+
@builtin(instance_index) vertIndex: u32) -> GeoVertexInput
|
|
19
|
+
{
|
|
20
|
+
let point = vec3<f32>(u_vertices[vertIndex * 3u],
|
|
21
|
+
u_vertices[vertIndex * 3u + 1u],
|
|
22
|
+
u_vertices[vertIndex * 3u + 2u]);
|
|
23
|
+
let pos = cameraMapPoint(point);
|
|
24
|
+
var position = pos;
|
|
25
|
+
// draw a rectangle, we discard points outside the circle in the fragment shader
|
|
26
|
+
if(vertId == 0)
|
|
27
|
+
{
|
|
28
|
+
position.x -= u_vertex_thickness/2.;
|
|
29
|
+
position.y += u_vertex_thickness/2.;
|
|
30
|
+
}
|
|
31
|
+
else if(vertId == 1)
|
|
32
|
+
{
|
|
33
|
+
position.x -= u_vertex_thickness/2.;
|
|
34
|
+
position.y -= u_vertex_thickness/2.;
|
|
35
|
+
}
|
|
36
|
+
else if(vertId == 2)
|
|
37
|
+
{
|
|
38
|
+
position.x += u_vertex_thickness/2.;
|
|
39
|
+
position.y += u_vertex_thickness/2.;
|
|
40
|
+
}
|
|
41
|
+
else if(vertId == 3)
|
|
42
|
+
{
|
|
43
|
+
position.x += u_vertex_thickness/2.;
|
|
44
|
+
position.y -= u_vertex_thickness/2.;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return GeoVertexInput(position, position, pos, point, vertIndex);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@fragment
|
|
51
|
+
fn fragment_main(input: GeoVertexInput) -> @location(0) vec4<f32> {
|
|
52
|
+
if(length(input.pos.xy - input.pos2.xy) > u_vertex_thickness/2.) {
|
|
53
|
+
discard;
|
|
54
|
+
}
|
|
55
|
+
if (u_vertex_color[input.index*4+3] == 0.) {
|
|
56
|
+
discard;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return vec4<f32>(u_vertex_color[input.index * 4],
|
|
60
|
+
u_vertex_color[input.index * 4 + 1],
|
|
61
|
+
u_vertex_color[input.index * 4 + 2],
|
|
62
|
+
u_vertex_color[input.index * 4 + 3]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@fragment
|
|
66
|
+
fn fragmentQueryIndex(input: GeoVertexInput) -> @location(0) vec2<u32> {
|
|
67
|
+
if(length(input.pos.xy - input.pos2.xy) > u_vertex_thickness/2.) {
|
|
68
|
+
discard;
|
|
69
|
+
}
|
|
70
|
+
return vec2<u32>(input.index, 0u);
|
|
71
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
|
|
2
|
+
@group(0) @binding(21) var<storage, read_write> count_trigs: atomic<u32>;
|
|
3
|
+
@group(0) @binding(22) var<uniform> u_ntets: u32;
|
|
4
|
+
@group(0) @binding(23) var<uniform> only_count: u32;
|
|
5
|
+
@group(0) @binding(24) var<storage, read_write> subtrigs: array<SubTrig>;
|
|
6
|
+
@group(0) @binding(26) var<storage> levelset_values: array<f32>;
|
|
7
|
+
@group(0) @binding(27) var<uniform> u_subdivision: u32;
|
|
8
|
+
|
|
9
|
+
fn my_pow(x: u32, y: u32) -> u32 {
|
|
10
|
+
var res = 1u;
|
|
11
|
+
for(var i = 0u; i < y; i++) {
|
|
12
|
+
res *= x;
|
|
13
|
+
}
|
|
14
|
+
return res;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@compute @workgroup_size(256)
|
|
18
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
19
|
+
for (var i = id.x; i<u_ntets*my_pow(4u,u_subdivision); i+=256u*1024u) {
|
|
20
|
+
var b0 = vec4<f32> (1.0, 0.0, 0.0, 0.0);
|
|
21
|
+
var b1 = vec4<f32> (0.0, 1.0, 0.0, 0.0);
|
|
22
|
+
var b2 = vec4<f32> (0.0, 0.0, 1.0, 0.0);
|
|
23
|
+
var b3 = vec4<f32> (0.0, 0.0, 0.0, 1.0);
|
|
24
|
+
var elnr = i / my_pow(4u,u_subdivision);
|
|
25
|
+
var scale: f32 = 1.;
|
|
26
|
+
var ind = i;
|
|
27
|
+
for(var level = 0u; level < u_subdivision; level++)
|
|
28
|
+
{
|
|
29
|
+
var b = ind % 4u;
|
|
30
|
+
ind /= 4u;
|
|
31
|
+
if(b == 0u) {
|
|
32
|
+
b0 = (b0 + b1) * 0.5;
|
|
33
|
+
} else if(b == 1u) {
|
|
34
|
+
b1 = (b0 + b1) * 0.5;
|
|
35
|
+
} else if(b == 2u) {
|
|
36
|
+
b2 = (b2 + b3) * 0.5;
|
|
37
|
+
} else if(b == 3u) {
|
|
38
|
+
b3 = (b2 + b3) * 0.5;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
let p = get_tet_points(elnr);
|
|
42
|
+
let lam = array(b0.xyz,
|
|
43
|
+
b1.xyz,
|
|
44
|
+
b2.xyz,
|
|
45
|
+
b3.xyz);
|
|
46
|
+
let f = array(evalTet(&levelset_values, elnr, 0, b0.xyz),
|
|
47
|
+
evalTet(&levelset_values, elnr, 0, b1.xyz),
|
|
48
|
+
evalTet(&levelset_values, elnr, 0, b2.xyz),
|
|
49
|
+
evalTet(&levelset_values, elnr, 0, b3.xyz));
|
|
50
|
+
let cuts = clipTet(lam, f, elnr);
|
|
51
|
+
if(cuts.n == 0) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
let index = atomicAdd(&count_trigs, cuts.n);
|
|
55
|
+
if(only_count == u32(1)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
for(var k = 0u; k < cuts.n; k++) {
|
|
59
|
+
subtrigs[index+k] = cuts.trigs[k];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
@group(0) @binding(80) var<storage> levelset: array<f32>;
|
|
3
|
+
|
|
4
|
+
@fragment
|
|
5
|
+
fn fragment_neg_clip(input: VertexOutputClip) -> @location(0) vec4<f32>
|
|
6
|
+
{
|
|
7
|
+
let lvlset = evalTet(&levelset, input.elnr, 0, input.lam);
|
|
8
|
+
if(lvlset > 0.) {
|
|
9
|
+
discard;
|
|
10
|
+
}
|
|
11
|
+
let value = evalTet(&function_values_3d, input.elnr, 0, input.lam);
|
|
12
|
+
return lightCalcColor(input.n, getColor(value));
|
|
13
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
@group(0) @binding(80) var<storage> levelset_values : array<f32>;
|
|
3
|
+
|
|
4
|
+
@fragment
|
|
5
|
+
fn fragmentCheckLevelset(input: VertexOutput2d) -> @location(0) vec4<f32> {
|
|
6
|
+
checkClipping(input.p);
|
|
7
|
+
let p = &u_function_values_2d;
|
|
8
|
+
let value = evalTrig(p, input.id, 0, input.lam);
|
|
9
|
+
let pl = &levelset_values;
|
|
10
|
+
let levelset = evalTrig(pl, input.id, 0, input.lam);
|
|
11
|
+
if (levelset > 0.0) {
|
|
12
|
+
discard;
|
|
13
|
+
}
|
|
14
|
+
return lightCalcColor(-input.n, getColor(value));
|
|
15
|
+
}
|