1pub const F32: &str = r#"const WORKGROUP_SIZE: u32 = {{WORKGROUP_SIZE}}u;
2
3struct VertexRaw { data: array<f32, 12u>, };
4struct Line3Params { color: vec4<f32>, count: u32, half_width_data: f32, line_style: u32, thick: u32, _pad: u32, };
5
6@group(0) @binding(0) var<storage, read> buf_x: array<f32>;
7@group(0) @binding(1) var<storage, read> buf_y: array<f32>;
8@group(0) @binding(2) var<storage, read> buf_z: array<f32>;
9@group(0) @binding(3) var<storage, read_write> out_vertices: array<VertexRaw>;
10@group(0) @binding(4) var<uniform> params: Line3Params;
11
12fn should_draw(segment: u32, style: u32) -> bool {
13 switch(style) {
14 case 0u: { return true; }
15 case 1u: { return (segment % 4u) < 2u; }
16 case 2u: { return (segment % 4u) < 2u; }
17 case 3u: { let m = segment % 6u; return (m < 2u) || (m == 3u); }
18 default: { return true; }
19 }
20}
21
22fn write_line_vertices(base: u32, p0: vec3<f32>, p1: vec3<f32>, color: vec4<f32>) {
23 write_vertex(base + 0u, p0, color);
24 write_vertex(base + 1u, p1, color);
25}
26
27fn write_thick_vertices(base: u32, p0: vec3<f32>, p1: vec3<f32>, color: vec4<f32>, half_width: f32) {
28 var dir = normalize(p1 - p0);
29 var normal = cross(dir, vec3<f32>(0.0, 0.0, 1.0));
30 if (length(normal) < 0.0001) {
31 normal = cross(dir, vec3<f32>(1.0, 0.0, 0.0));
32 }
33 normal = normalize(normal) * half_width;
34 let v0 = p0 + normal;
35 let v1 = p1 + normal;
36 let v2 = p1 - normal;
37 let v3 = p0 - normal;
38 write_vertex(base + 0u, v0, color);
39 write_vertex(base + 1u, v1, color);
40 write_vertex(base + 2u, v2, color);
41 write_vertex(base + 3u, v0, color);
42 write_vertex(base + 4u, v2, color);
43 write_vertex(base + 5u, v3, color);
44}
45
46fn write_vertex(index: u32, pos: vec3<f32>, color: vec4<f32>) {
47 var vertex: VertexRaw;
48 vertex.data[0u] = pos.x; vertex.data[1u] = pos.y; vertex.data[2u] = pos.z;
49 vertex.data[3u] = color.x; vertex.data[4u] = color.y; vertex.data[5u] = color.z; vertex.data[6u] = color.w;
50 vertex.data[7u] = 0.0; vertex.data[8u] = 0.0; vertex.data[9u] = 1.0; vertex.data[10u] = 0.0; vertex.data[11u] = 0.0;
51 out_vertices[index] = vertex;
52}
53
54@compute @workgroup_size(WORKGROUP_SIZE)
55fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
56 if (params.count < 2u) { return; }
57 let segments = params.count - 1u;
58 let idx = gid.x;
59 if (idx >= segments) { return; }
60 var color = params.color;
61 if (!should_draw(idx, params.line_style)) { color.w = 0.0; }
62 let p0 = vec3<f32>(buf_x[idx], buf_y[idx], buf_z[idx]);
63 let p1 = vec3<f32>(buf_x[idx + 1u], buf_y[idx + 1u], buf_z[idx + 1u]);
64 if (params.thick != 0u) {
65 let base = idx * 6u;
66 write_thick_vertices(base, p0, p1, color, params.half_width_data);
67 } else {
68 let base = idx * 2u;
69 write_line_vertices(base, p0, p1, color);
70 }
71}
72"#;
73
74pub const F64: &str = r#"const WORKGROUP_SIZE: u32 = {{WORKGROUP_SIZE}}u;
75
76struct VertexRaw { data: array<f32, 12u>, };
77struct Line3Params { color: vec4<f32>, count: u32, half_width_data: f32, line_style: u32, thick: u32, _pad: u32, };
78
79@group(0) @binding(0) var<storage, read> buf_x: array<f64>;
80@group(0) @binding(1) var<storage, read> buf_y: array<f64>;
81@group(0) @binding(2) var<storage, read> buf_z: array<f64>;
82@group(0) @binding(3) var<storage, read_write> out_vertices: array<VertexRaw>;
83@group(0) @binding(4) var<uniform> params: Line3Params;
84
85fn should_draw(segment: u32, style: u32) -> bool {
86 switch(style) {
87 case 0u: { return true; }
88 case 1u: { return (segment % 4u) < 2u; }
89 case 2u: { return (segment % 4u) < 2u; }
90 case 3u: { let m = segment % 6u; return (m < 2u) || (m == 3u); }
91 default: { return true; }
92 }
93}
94
95fn write_line_vertices(base: u32, p0: vec3<f32>, p1: vec3<f32>, color: vec4<f32>) {
96 write_vertex(base + 0u, p0, color);
97 write_vertex(base + 1u, p1, color);
98}
99
100fn write_thick_vertices(base: u32, p0: vec3<f32>, p1: vec3<f32>, color: vec4<f32>, half_width: f32) {
101 var dir = normalize(p1 - p0);
102 var normal = cross(dir, vec3<f32>(0.0, 0.0, 1.0));
103 if (length(normal) < 0.0001) {
104 normal = cross(dir, vec3<f32>(1.0, 0.0, 0.0));
105 }
106 normal = normalize(normal) * half_width;
107 let v0 = p0 + normal;
108 let v1 = p1 + normal;
109 let v2 = p1 - normal;
110 let v3 = p0 - normal;
111 write_vertex(base + 0u, v0, color);
112 write_vertex(base + 1u, v1, color);
113 write_vertex(base + 2u, v2, color);
114 write_vertex(base + 3u, v0, color);
115 write_vertex(base + 4u, v2, color);
116 write_vertex(base + 5u, v3, color);
117}
118
119fn write_vertex(index: u32, pos: vec3<f32>, color: vec4<f32>) {
120 var vertex: VertexRaw;
121 vertex.data[0u] = pos.x; vertex.data[1u] = pos.y; vertex.data[2u] = pos.z;
122 vertex.data[3u] = color.x; vertex.data[4u] = color.y; vertex.data[5u] = color.z; vertex.data[6u] = color.w;
123 vertex.data[7u] = 0.0; vertex.data[8u] = 0.0; vertex.data[9u] = 1.0; vertex.data[10u] = 0.0; vertex.data[11u] = 0.0;
124 out_vertices[index] = vertex;
125}
126
127@compute @workgroup_size(WORKGROUP_SIZE)
128fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
129 if (params.count < 2u) { return; }
130 let segments = params.count - 1u;
131 let idx = gid.x;
132 if (idx >= segments) { return; }
133 var color = params.color;
134 if (!should_draw(idx, params.line_style)) { color.w = 0.0; }
135 let p0 = vec3<f32>(f32(buf_x[idx]), f32(buf_y[idx]), f32(buf_z[idx]));
136 let p1 = vec3<f32>(f32(buf_x[idx + 1u]), f32(buf_y[idx + 1u]), f32(buf_z[idx + 1u]));
137 if (params.thick != 0u) {
138 let base = idx * 6u;
139 write_thick_vertices(base, p0, p1, color, params.half_width_data);
140 } else {
141 let base = idx * 2u;
142 write_line_vertices(base, p0, p1, color);
143 }
144}
145"#;