@ifc-lite/renderer 5.0.0 → 6.0.1

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.
Files changed (284) hide show
  1. package/dist/camera-projection.d.ts +2 -0
  2. package/dist/camera-projection.d.ts.map +1 -1
  3. package/dist/camera-projection.js +46 -0
  4. package/dist/camera-projection.js.map +1 -1
  5. package/dist/chunk-grid.d.ts +21 -0
  6. package/dist/chunk-grid.d.ts.map +1 -1
  7. package/dist/chunk-grid.js +25 -7
  8. package/dist/chunk-grid.js.map +1 -1
  9. package/dist/clash-solid-pipeline.d.ts.map +1 -1
  10. package/dist/clash-solid-pipeline.js +4 -2
  11. package/dist/clash-solid-pipeline.js.map +1 -1
  12. package/dist/deviation/deviation-computer.d.ts +4 -0
  13. package/dist/deviation/deviation-computer.d.ts.map +1 -1
  14. package/dist/deviation/deviation-computer.js +20 -0
  15. package/dist/deviation/deviation-computer.js.map +1 -1
  16. package/dist/deviation/deviation-readback.d.ts +18 -0
  17. package/dist/deviation/deviation-readback.d.ts.map +1 -0
  18. package/dist/deviation/deviation-readback.js +67 -0
  19. package/dist/deviation/deviation-readback.js.map +1 -0
  20. package/dist/edge-pass.d.ts +16 -0
  21. package/dist/edge-pass.d.ts.map +1 -1
  22. package/dist/edge-pass.js +75 -1
  23. package/dist/edge-pass.js.map +1 -1
  24. package/dist/entity-color-table.d.ts +140 -0
  25. package/dist/entity-color-table.d.ts.map +1 -0
  26. package/dist/entity-color-table.js +238 -0
  27. package/dist/entity-color-table.js.map +1 -0
  28. package/dist/gpu-upload-guard.d.ts +1 -1
  29. package/dist/gpu-upload-guard.js +1 -1
  30. package/dist/hover-mesh-cache.d.ts +29 -0
  31. package/dist/hover-mesh-cache.d.ts.map +1 -0
  32. package/dist/hover-mesh-cache.js +31 -0
  33. package/dist/hover-mesh-cache.js.map +1 -0
  34. package/dist/index.d.ts +14 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +146 -161
  37. package/dist/index.js.map +1 -1
  38. package/dist/individual-mesh-upload.d.ts +24 -0
  39. package/dist/individual-mesh-upload.d.ts.map +1 -0
  40. package/dist/individual-mesh-upload.js +85 -0
  41. package/dist/individual-mesh-upload.js.map +1 -0
  42. package/dist/instanced-render.d.ts +19 -9
  43. package/dist/instanced-render.d.ts.map +1 -1
  44. package/dist/instanced-render.js +36 -24
  45. package/dist/instanced-render.js.map +1 -1
  46. package/dist/instanced-rte.d.ts +68 -7
  47. package/dist/instanced-rte.d.ts.map +1 -1
  48. package/dist/instanced-rte.js +98 -17
  49. package/dist/instanced-rte.js.map +1 -1
  50. package/dist/instanced-vertex-layout.d.ts +26 -0
  51. package/dist/instanced-vertex-layout.d.ts.map +1 -0
  52. package/dist/instanced-vertex-layout.js +61 -0
  53. package/dist/instanced-vertex-layout.js.map +1 -0
  54. package/dist/mesh-rte-uniforms.d.ts +4 -2
  55. package/dist/mesh-rte-uniforms.d.ts.map +1 -1
  56. package/dist/mesh-rte-uniforms.js +4 -2
  57. package/dist/mesh-rte-uniforms.js.map +1 -1
  58. package/dist/model-translation.d.ts.map +1 -1
  59. package/dist/model-translation.js +0 -7
  60. package/dist/model-translation.js.map +1 -1
  61. package/dist/outline-params.d.ts +45 -0
  62. package/dist/outline-params.d.ts.map +1 -0
  63. package/dist/outline-params.js +54 -0
  64. package/dist/outline-params.js.map +1 -0
  65. package/dist/overlay-routing.d.ts +8 -8
  66. package/dist/overlay-routing.js +2 -2
  67. package/dist/overlay-routing.js.map +1 -1
  68. package/dist/overlay-theme.d.ts +9 -3
  69. package/dist/overlay-theme.d.ts.map +1 -1
  70. package/dist/overlay-theme.js.map +1 -1
  71. package/dist/partial-batch-requests.d.ts +2 -2
  72. package/dist/pick-mesh-budget.d.ts +28 -0
  73. package/dist/pick-mesh-budget.d.ts.map +1 -0
  74. package/dist/pick-mesh-budget.js +74 -0
  75. package/dist/pick-mesh-budget.js.map +1 -0
  76. package/dist/picker-rte-uniforms.d.ts +7 -1
  77. package/dist/picker-rte-uniforms.d.ts.map +1 -1
  78. package/dist/picker-rte-uniforms.js +9 -1
  79. package/dist/picker-rte-uniforms.js.map +1 -1
  80. package/dist/picker.d.ts.map +1 -1
  81. package/dist/picker.js +15 -28
  82. package/dist/picker.js.map +1 -1
  83. package/dist/picking-manager.d.ts.map +1 -1
  84. package/dist/picking-manager.js +4 -47
  85. package/dist/picking-manager.js.map +1 -1
  86. package/dist/pipeline.d.ts +7 -1
  87. package/dist/pipeline.d.ts.map +1 -1
  88. package/dist/pipeline.js +37 -59
  89. package/dist/pipeline.js.map +1 -1
  90. package/dist/point-picker.d.ts.map +1 -1
  91. package/dist/point-picker.js +7 -2
  92. package/dist/point-picker.js.map +1 -1
  93. package/dist/pointcloud/point-cloud-node.js +1 -1
  94. package/dist/pointcloud/point-cloud-node.js.map +1 -1
  95. package/dist/pointcloud/point-cloud-renderer.d.ts.map +1 -1
  96. package/dist/pointcloud/point-cloud-renderer.js +3 -1
  97. package/dist/pointcloud/point-cloud-renderer.js.map +1 -1
  98. package/dist/pointcloud/point-cloud-uniforms.d.ts +5 -1
  99. package/dist/pointcloud/point-cloud-uniforms.d.ts.map +1 -1
  100. package/dist/pointcloud/point-cloud-uniforms.js +7 -1
  101. package/dist/pointcloud/point-cloud-uniforms.js.map +1 -1
  102. package/dist/post-pass-chain.d.ts +14 -1
  103. package/dist/post-pass-chain.d.ts.map +1 -1
  104. package/dist/post-pass-chain.js +31 -2
  105. package/dist/post-pass-chain.js.map +1 -1
  106. package/dist/raycast-engine.d.ts +5 -1
  107. package/dist/raycast-engine.d.ts.map +1 -1
  108. package/dist/raycast-engine.js +20 -8
  109. package/dist/raycast-engine.js.map +1 -1
  110. package/dist/raycast-point-cloud-query.d.ts +2 -0
  111. package/dist/raycast-point-cloud-query.d.ts.map +1 -1
  112. package/dist/raycast-point-cloud-query.js +7 -0
  113. package/dist/raycast-point-cloud-query.js.map +1 -1
  114. package/dist/raycast-source-curve-query.d.ts +13 -0
  115. package/dist/raycast-source-curve-query.d.ts.map +1 -0
  116. package/dist/raycast-source-curve-query.js +17 -0
  117. package/dist/raycast-source-curve-query.js.map +1 -0
  118. package/dist/reference-image-pipeline.d.ts.map +1 -1
  119. package/dist/reference-image-pipeline.js +4 -2
  120. package/dist/reference-image-pipeline.js.map +1 -1
  121. package/dist/relative-to-eye-abi.d.ts +36 -0
  122. package/dist/relative-to-eye-abi.d.ts.map +1 -0
  123. package/dist/relative-to-eye-abi.js +72 -0
  124. package/dist/relative-to-eye-abi.js.map +1 -0
  125. package/dist/relative-to-eye.d.ts +15 -35
  126. package/dist/relative-to-eye.d.ts.map +1 -1
  127. package/dist/relative-to-eye.js +46 -74
  128. package/dist/relative-to-eye.js.map +1 -1
  129. package/dist/render-stats.d.ts +5 -1
  130. package/dist/render-stats.d.ts.map +1 -1
  131. package/dist/render-stats.js +1 -1
  132. package/dist/render-stats.js.map +1 -1
  133. package/dist/renderer-overlays.d.ts.map +1 -1
  134. package/dist/renderer-overlays.js +3 -2
  135. package/dist/renderer-overlays.js.map +1 -1
  136. package/dist/scene-batch-rebuild.d.ts +1 -2
  137. package/dist/scene-batch-rebuild.d.ts.map +1 -1
  138. package/dist/scene-batch-rebuild.js +4 -8
  139. package/dist/scene-batch-rebuild.js.map +1 -1
  140. package/dist/scene-batch-upload.d.ts.map +1 -1
  141. package/dist/scene-batch-upload.js +7 -3
  142. package/dist/scene-batch-upload.js.map +1 -1
  143. package/dist/scene-contents.d.ts +1 -1
  144. package/dist/scene-contents.d.ts.map +1 -1
  145. package/dist/scene-derived-batches.d.ts +19 -64
  146. package/dist/scene-derived-batches.d.ts.map +1 -1
  147. package/dist/scene-derived-batches.js +16 -51
  148. package/dist/scene-derived-batches.js.map +1 -1
  149. package/dist/scene-device-recovery.d.ts +3 -3
  150. package/dist/scene-device-recovery.d.ts.map +1 -1
  151. package/dist/scene-device-recovery.js +12 -9
  152. package/dist/scene-device-recovery.js.map +1 -1
  153. package/dist/scene-geometry.d.ts +6 -6
  154. package/dist/scene-geometry.d.ts.map +1 -1
  155. package/dist/scene-geometry.js +8 -9
  156. package/dist/scene-geometry.js.map +1 -1
  157. package/dist/scene-instance-bounds.d.ts +1 -1
  158. package/dist/scene-instance-bounds.d.ts.map +1 -1
  159. package/dist/scene-instance-bounds.js +4 -16
  160. package/dist/scene-instance-bounds.js.map +1 -1
  161. package/dist/scene-instance-materialization.d.ts.map +1 -1
  162. package/dist/scene-instance-materialization.js +4 -4
  163. package/dist/scene-instance-materialization.js.map +1 -1
  164. package/dist/scene-instance-translation.d.ts +6 -10
  165. package/dist/scene-instance-translation.d.ts.map +1 -1
  166. package/dist/scene-instance-translation.js +9 -31
  167. package/dist/scene-instance-translation.js.map +1 -1
  168. package/dist/scene-instance-types.d.ts +11 -2
  169. package/dist/scene-instance-types.d.ts.map +1 -1
  170. package/dist/scene-instance-types.js +7 -1
  171. package/dist/scene-instance-types.js.map +1 -1
  172. package/dist/scene-model-translation.d.ts +1 -2
  173. package/dist/scene-model-translation.d.ts.map +1 -1
  174. package/dist/scene-model-translation.js +4 -3
  175. package/dist/scene-model-translation.js.map +1 -1
  176. package/dist/scene-precision.d.ts +1 -1
  177. package/dist/scene-precision.d.ts.map +1 -1
  178. package/dist/scene-precision.js +11 -2
  179. package/dist/scene-precision.js.map +1 -1
  180. package/dist/scene.d.ts +43 -38
  181. package/dist/scene.d.ts.map +1 -1
  182. package/dist/scene.js +121 -129
  183. package/dist/scene.js.map +1 -1
  184. package/dist/section-2d-line-buffer.d.ts +2 -2
  185. package/dist/section-2d-line-buffer.d.ts.map +1 -1
  186. package/dist/section-2d-line-buffer.js +10 -11
  187. package/dist/section-2d-line-buffer.js.map +1 -1
  188. package/dist/section-2d-overlay.d.ts +6 -4
  189. package/dist/section-2d-overlay.d.ts.map +1 -1
  190. package/dist/section-2d-overlay.js +45 -21
  191. package/dist/section-2d-overlay.js.map +1 -1
  192. package/dist/section-2d-types.d.ts +1 -1
  193. package/dist/section-2d-types.d.ts.map +1 -1
  194. package/dist/section-2d-types.js +1 -1
  195. package/dist/section-2d-types.js.map +1 -1
  196. package/dist/section-plane.d.ts.map +1 -1
  197. package/dist/section-plane.js +3 -1
  198. package/dist/section-plane.js.map +1 -1
  199. package/dist/selection-mask-pass.d.ts +85 -0
  200. package/dist/selection-mask-pass.d.ts.map +1 -0
  201. package/dist/selection-mask-pass.js +170 -0
  202. package/dist/selection-mask-pass.js.map +1 -0
  203. package/dist/selection-mask-pipelines.d.ts +57 -0
  204. package/dist/selection-mask-pipelines.d.ts.map +1 -0
  205. package/dist/selection-mask-pipelines.js +150 -0
  206. package/dist/selection-mask-pipelines.js.map +1 -0
  207. package/dist/selection-outline-frame.d.ts +47 -0
  208. package/dist/selection-outline-frame.d.ts.map +1 -0
  209. package/dist/selection-outline-frame.js +122 -0
  210. package/dist/selection-outline-frame.js.map +1 -0
  211. package/dist/shaders/depth-reconstruct.wgsl.d.ts +7 -2
  212. package/dist/shaders/depth-reconstruct.wgsl.d.ts.map +1 -1
  213. package/dist/shaders/depth-reconstruct.wgsl.js +8 -3
  214. package/dist/shaders/depth-reconstruct.wgsl.js.map +1 -1
  215. package/dist/shaders/edges.wgsl.d.ts +18 -0
  216. package/dist/shaders/edges.wgsl.d.ts.map +1 -1
  217. package/dist/shaders/edges.wgsl.js +99 -0
  218. package/dist/shaders/edges.wgsl.js.map +1 -1
  219. package/dist/shaders/entity-color-table.wgsl.d.ts +2 -0
  220. package/dist/shaders/entity-color-table.wgsl.d.ts.map +1 -0
  221. package/dist/shaders/entity-color-table.wgsl.js +85 -0
  222. package/dist/shaders/entity-color-table.wgsl.js.map +1 -0
  223. package/dist/shaders/main.wgsl.d.ts +1 -1
  224. package/dist/shaders/main.wgsl.d.ts.map +1 -1
  225. package/dist/shaders/main.wgsl.js +45 -113
  226. package/dist/shaders/main.wgsl.js.map +1 -1
  227. package/dist/shaders/mesh-uniforms.wgsl.d.ts +2 -0
  228. package/dist/shaders/mesh-uniforms.wgsl.d.ts.map +1 -0
  229. package/dist/shaders/mesh-uniforms.wgsl.js +53 -0
  230. package/dist/shaders/mesh-uniforms.wgsl.js.map +1 -0
  231. package/dist/shaders/section-2d-overlay.wgsl.d.ts +1 -0
  232. package/dist/shaders/section-2d-overlay.wgsl.d.ts.map +1 -1
  233. package/dist/shaders/section-2d-overlay.wgsl.js +3 -2
  234. package/dist/shaders/section-2d-overlay.wgsl.js.map +1 -1
  235. package/dist/shaders/selection-mask.wgsl.d.ts +16 -0
  236. package/dist/shaders/selection-mask.wgsl.d.ts.map +1 -0
  237. package/dist/shaders/selection-mask.wgsl.js +138 -0
  238. package/dist/shaders/selection-mask.wgsl.js.map +1 -0
  239. package/dist/shaders/shadow.wgsl.d.ts +1 -1
  240. package/dist/shaders/shadow.wgsl.d.ts.map +1 -1
  241. package/dist/shaders/shadow.wgsl.js +3 -3
  242. package/dist/shadow-occluders.d.ts.map +1 -1
  243. package/dist/shadow-occluders.js +1 -0
  244. package/dist/shadow-occluders.js.map +1 -1
  245. package/dist/shadow-pass.d.ts +0 -1
  246. package/dist/shadow-pass.d.ts.map +1 -1
  247. package/dist/shadow-pass.js +26 -32
  248. package/dist/shadow-pass.js.map +1 -1
  249. package/dist/shadow-types.d.ts +3 -0
  250. package/dist/shadow-types.d.ts.map +1 -1
  251. package/dist/shadow-types.js.map +1 -1
  252. package/dist/snap-detector.d.ts +5 -0
  253. package/dist/snap-detector.d.ts.map +1 -1
  254. package/dist/snap-detector.js.map +1 -1
  255. package/dist/source-curve-clipping.d.ts +7 -0
  256. package/dist/source-curve-clipping.d.ts.map +1 -0
  257. package/dist/source-curve-clipping.js +165 -0
  258. package/dist/source-curve-clipping.js.map +1 -0
  259. package/dist/source-curve-snap.d.ts +49 -0
  260. package/dist/source-curve-snap.d.ts.map +1 -0
  261. package/dist/source-curve-snap.js +197 -0
  262. package/dist/source-curve-snap.js.map +1 -0
  263. package/dist/symbolic-overlay-pipelines.d.ts +1 -1
  264. package/dist/symbolic-overlay-pipelines.d.ts.map +1 -1
  265. package/dist/symbolic-overlay-pipelines.js +13 -22
  266. package/dist/symbolic-overlay-pipelines.js.map +1 -1
  267. package/dist/symbolic-text-rte.d.ts +16 -0
  268. package/dist/symbolic-text-rte.d.ts.map +1 -0
  269. package/dist/symbolic-text-rte.js +37 -0
  270. package/dist/symbolic-text-rte.js.map +1 -0
  271. package/dist/textured-vertices.d.ts.map +1 -1
  272. package/dist/textured-vertices.js +2 -3
  273. package/dist/textured-vertices.js.map +1 -1
  274. package/dist/types.d.ts +10 -0
  275. package/dist/types.d.ts.map +1 -1
  276. package/dist/visual-enhancement.d.ts +0 -4
  277. package/dist/visual-enhancement.d.ts.map +1 -1
  278. package/dist/visual-enhancement.js +0 -5
  279. package/dist/visual-enhancement.js.map +1 -1
  280. package/dist/xray-alpha.d.ts +7 -3
  281. package/dist/xray-alpha.d.ts.map +1 -1
  282. package/dist/xray-alpha.js +11 -7
  283. package/dist/xray-alpha.js.map +1 -1
  284. package/package.json +4 -4
@@ -0,0 +1,170 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { mainShaderSource } from './shaders/main.wgsl.js';
5
+ import { SELECTION_MASK_DEPTH_GROUP, selectionMaskFragmentSource } from './shaders/selection-mask.wgsl.js';
6
+ import { createMaskPipelines, InstancedSelectionMask, isInstancedMaskEmpty, MASK_ALL_FORMAT, MASK_VISIBLE_FORMAT, } from './selection-mask-pipelines.js';
7
+ /** The regular (non-instanced) mesh vertex layout `vs_main` reads. */
8
+ const MESH_VERTEX_BUFFERS = [{
9
+ arrayStride: 28,
10
+ attributes: [
11
+ { shaderLocation: 0, offset: 0, format: 'float32x3' },
12
+ { shaderLocation: 1, offset: 12, format: 'float32x3' },
13
+ { shaderLocation: 2, offset: 24, format: 'uint32' },
14
+ ],
15
+ }];
16
+ export class SelectionMaskPass {
17
+ device;
18
+ meshBindGroupLayout;
19
+ depthLayout;
20
+ multisampled;
21
+ pipelines;
22
+ /** Built on the first frame with an instanced selection or hover. */
23
+ instanced = null;
24
+ targets = null;
25
+ cachedDepthView = null;
26
+ cachedDepthBindGroup = null;
27
+ /** One owned uniform buffer + bind group per hovered piece, grown on demand. */
28
+ hoverUniforms = [];
29
+ destroyed = false;
30
+ constructor(device, meshBindGroupLayout, sampleCount) {
31
+ this.device = device.getDevice();
32
+ this.meshBindGroupLayout = meshBindGroupLayout;
33
+ this.depthLayout = this.device.createBindGroupLayout({
34
+ label: 'selection-mask-depth-bgl',
35
+ entries: [{
36
+ binding: 0,
37
+ visibility: GPUShaderStage.FRAGMENT,
38
+ texture: { sampleType: 'depth', viewDimension: '2d', multisampled: sampleCount > 1 },
39
+ }],
40
+ });
41
+ const layout = this.device.createPipelineLayout({
42
+ bindGroupLayouts: [this.meshBindGroupLayout, this.depthLayout],
43
+ });
44
+ this.multisampled = sampleCount > 1;
45
+ const vertexModule = this.device.createShaderModule({ label: 'selection-mask-vs', code: mainShaderSource });
46
+ const fragmentModule = this.device.createShaderModule({
47
+ label: 'selection-mask-fs',
48
+ code: selectionMaskFragmentSource(this.multisampled),
49
+ });
50
+ const vertex = { module: vertexModule, entryPoint: 'vs_main', buffers: MESH_VERTEX_BUFFERS };
51
+ this.pipelines = createMaskPipelines(this.device, 'selection-mask', layout, vertex, fragmentModule);
52
+ }
53
+ /** Nothing to draw this frame: caller skips the pass and the outline composite entirely. */
54
+ static isEmpty(frame) {
55
+ return frame.selected.length === 0 && frame.hovered.length === 0 && isInstancedMaskEmpty(frame.instanced);
56
+ }
57
+ encode(frame) {
58
+ const targets = this.ensureTargets(frame.width, frame.height);
59
+ const depthGroup = this.ensureDepthBindGroup(frame.depthView);
60
+ const instancedFrame = frame.instanced && !isInstancedMaskEmpty(frame.instanced) ? frame.instanced : null;
61
+ const instanced = instancedFrame ? this.ensureInstanced() : null;
62
+ if (instanced && instancedFrame)
63
+ instanced.prepare(instancedFrame);
64
+ // The selected-visible and hover passes share `visibleView` (channels r
65
+ // and g): only the FIRST pass into a target may clear it, or the hover
66
+ // pass wipes the selection's visible mask (#5390, seen in a real frame).
67
+ const cleared = new Set();
68
+ const draw = (view, kind, meshes) => {
69
+ const loadOp = cleared.has(view) ? 'load' : 'clear';
70
+ cleared.add(view);
71
+ const pass = frame.encoder.beginRenderPass({
72
+ colorAttachments: [{ view, loadOp, storeOp: 'store', clearValue: { r: 0, g: 0, b: 0, a: 0 } }],
73
+ });
74
+ pass.setPipeline(this.pipelines[kind]);
75
+ pass.setBindGroup(SELECTION_MASK_DEPTH_GROUP, depthGroup);
76
+ for (const mesh of meshes) {
77
+ pass.setBindGroup(0, mesh.bindGroup);
78
+ pass.setVertexBuffer(0, mesh.vertexBuffer);
79
+ pass.setIndexBuffer(mesh.indexBuffer, 'uint32');
80
+ pass.drawIndexed(mesh.indexCount, 1, 0, 0, 0);
81
+ }
82
+ if (instanced && instancedFrame) {
83
+ instanced.draw(pass, kind, depthGroup, kind === 'hoverVisible' ? instancedFrame.hovered : instancedFrame.selected);
84
+ }
85
+ pass.end();
86
+ };
87
+ draw(targets.visibleView, 'selectedVisible', frame.selected);
88
+ if (frame.hovered.length > 0 || (instancedFrame?.hovered.length ?? 0) > 0) {
89
+ draw(targets.visibleView, 'hoverVisible', frame.hovered.map((h, i) => ({
90
+ vertexBuffer: h.vertexBuffer, indexBuffer: h.indexBuffer, indexCount: h.indexCount, bindGroup: this.hoverGroup(h, i),
91
+ })));
92
+ }
93
+ draw(targets.allView, 'selectedAll', frame.selected);
94
+ return targets.views;
95
+ }
96
+ ensureInstanced() {
97
+ this.instanced ??= new InstancedSelectionMask(this.device, this.meshBindGroupLayout, this.depthLayout, this.multisampled);
98
+ return this.instanced;
99
+ }
100
+ hoverGroup(hovered, slot) {
101
+ if (hovered.bindGroup)
102
+ return hovered.bindGroup;
103
+ const { uniforms } = hovered;
104
+ let entry = this.hoverUniforms[slot];
105
+ if (!entry || entry.buffer.size < uniforms.byteLength) {
106
+ entry?.buffer.destroy();
107
+ const buffer = this.device.createBuffer({
108
+ label: 'selection-mask-hover-uniforms',
109
+ size: uniforms.byteLength,
110
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
111
+ });
112
+ const bindGroup = this.device.createBindGroup({
113
+ layout: this.meshBindGroupLayout,
114
+ entries: [{ binding: 0, resource: { buffer } }],
115
+ });
116
+ entry = { buffer, bindGroup };
117
+ this.hoverUniforms[slot] = entry;
118
+ }
119
+ this.device.queue.writeBuffer(entry.buffer, 0, uniforms);
120
+ return entry.bindGroup;
121
+ }
122
+ ensureTargets(width, height) {
123
+ const current = this.targets;
124
+ if (current && current.width === width && current.height === height)
125
+ return current;
126
+ this.releaseTargets();
127
+ const make = (label, format) => this.device.createTexture({
128
+ label,
129
+ size: { width, height },
130
+ format,
131
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
132
+ });
133
+ const visible = make('selection-mask-visible', MASK_VISIBLE_FORMAT);
134
+ const all = make('selection-mask-all', MASK_ALL_FORMAT);
135
+ const visibleView = visible.createView();
136
+ const allView = all.createView();
137
+ this.targets = { width, height, visible, all, visibleView, allView, views: { visibleView, allView } };
138
+ return this.targets;
139
+ }
140
+ ensureDepthBindGroup(depthView) {
141
+ if (this.cachedDepthView === depthView && this.cachedDepthBindGroup)
142
+ return this.cachedDepthBindGroup;
143
+ this.cachedDepthBindGroup = this.device.createBindGroup({
144
+ layout: this.depthLayout,
145
+ entries: [{ binding: 0, resource: depthView }],
146
+ });
147
+ this.cachedDepthView = depthView;
148
+ return this.cachedDepthBindGroup;
149
+ }
150
+ releaseTargets() {
151
+ this.targets?.visible.destroy();
152
+ this.targets?.all.destroy();
153
+ this.targets = null;
154
+ }
155
+ /** Release every GPU resource. Idempotent; the pass is unusable afterwards. */
156
+ destroy() {
157
+ if (this.destroyed)
158
+ return;
159
+ this.destroyed = true;
160
+ this.releaseTargets();
161
+ this.cachedDepthBindGroup = null;
162
+ this.cachedDepthView = null;
163
+ for (const entry of this.hoverUniforms)
164
+ entry.buffer.destroy();
165
+ this.hoverUniforms = [];
166
+ this.instanced?.destroy();
167
+ this.instanced = null;
168
+ }
169
+ }
170
+ //# sourceMappingURL=selection-mask-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-mask-pass.js","sourceRoot":"","sources":["../src/selection-mask-pass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import type { WorldPoint } from './relative-to-eye.js';
2
+ import type { InstancedTemplateGPU } from './scene-instance-types.js';
3
+ export declare const MASK_VISIBLE_FORMAT: GPUTextureFormat;
4
+ export declare const MASK_ALL_FORMAT: GPUTextureFormat;
5
+ /** Which mask output a draw writes. */
6
+ export type MaskKind = 'selectedVisible' | 'hoverVisible' | 'selectedAll';
7
+ export type MaskPipelines = Record<MaskKind, GPURenderPipeline>;
8
+ /** The three mask pipelines over one vertex stage and one fragment module. */
9
+ export declare function createMaskPipelines(device: GPUDevice, labelPrefix: string, layout: GPUPipelineLayout, vertex: GPUVertexState, fragmentModule: GPUShaderModule): MaskPipelines;
10
+ /** What the instanced mask draws of a template: its geometry and its instance records. */
11
+ export type InstancedMaskTemplate = Pick<InstancedTemplateGPU, 'vertexBuffer' | 'indexBuffer' | 'indexCount' | 'instanceBuffer' | 'instanceCount' | 'canonicalAnchors' | 'rteDeltas'>;
12
+ export interface InstancedMaskFrame {
13
+ /**
14
+ * Packed mesh uniform for `vs_instanced` and the section/clip cut: the
15
+ * frame's RTE view-projection, section plane, clip box and flags, as the
16
+ * main instanced draw sees them (`selection-outline-frame.ts`).
17
+ */
18
+ uniforms: Float32Array;
19
+ /**
20
+ * The frame's RTE camera, the one the colour pass uploaded the delta streams
21
+ * for. The mask shares that submission, so it must not use another (see
22
+ * `instanced-rte.ts`); in practice every upload here is a cache hit, except
23
+ * for templates the colour pass culled.
24
+ */
25
+ rteCamera: WorldPoint;
26
+ /** Templates holding at least one selected occurrence. */
27
+ selected: readonly InstancedMaskTemplate[];
28
+ /** Templates holding an occurrence of `hoveredId`; empty when nothing is hovered. */
29
+ hovered: readonly InstancedMaskTemplate[];
30
+ hoveredId: number;
31
+ }
32
+ /** True when the instanced frame has nothing to draw. */
33
+ export declare function isInstancedMaskEmpty(frame: InstancedMaskFrame | null | undefined): boolean;
34
+ /**
35
+ * The instanced mask pipelines plus the two small uniforms they read: the
36
+ * mesh uniform (group 0, owned so no other draw's write can race it) and the
37
+ * hovered entity id (group `SELECTION_MASK_HOVER_GROUP`). Built on the first
38
+ * frame that has an instanced selection or hover.
39
+ */
40
+ export declare class InstancedSelectionMask {
41
+ private readonly device;
42
+ private readonly pipelines;
43
+ private readonly meshBindGroupLayout;
44
+ private meshUniform;
45
+ private readonly hoverBuffer;
46
+ private readonly hoverBindGroup;
47
+ private readonly hoverScratch;
48
+ /** This frame's drawable runs per template, from `prepare`. */
49
+ private runs;
50
+ constructor(device: GPUDevice, meshBindGroupLayout: GPUBindGroupLayout, depthLayout: GPUBindGroupLayout, multisampled: boolean);
51
+ /** Upload this frame's uniforms. Call once per frame, before `draw`. */
52
+ prepare(frame: InstancedMaskFrame): void;
53
+ /** Draw `templates` into the open mask pass, one instanced draw per in-envelope run. */
54
+ draw(pass: GPURenderPassEncoder, kind: MaskKind, depthGroup: GPUBindGroup, templates: readonly InstancedMaskTemplate[]): void;
55
+ destroy(): void;
56
+ }
57
+ //# sourceMappingURL=selection-mask-pipelines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-mask-pipelines.d.ts","sourceRoot":"","sources":["../src/selection-mask-pipelines.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAQtE,eAAO,MAAM,mBAAmB,EAAE,gBAA6B,CAAC;AAChE,eAAO,MAAM,eAAe,EAAE,gBAA4B,CAAC;AAQ3D,uCAAuC;AACvC,MAAM,MAAM,QAAQ,GAAG,iBAAiB,GAAG,cAAc,GAAG,aAAa,CAAC;AAE1E,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;AAQhE,8EAA8E;AAC9E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,cAAc,EACtB,cAAc,EAAE,eAAe,GAC9B,aAAa,CAYf;AAED,0FAA0F;AAC1F,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,oBAAoB,EACpB,cAAc,GAAG,aAAa,GAAG,YAAY,GAAG,gBAAgB,GAAG,eAAe,GAAG,kBAAkB,GAAG,WAAW,CACtH,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,QAAQ,EAAE,YAAY,CAAC;IACvB;;;;;OAKG;IACH,SAAS,EAAE,UAAU,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C,qFAAqF;IACrF,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,yDAAyD;AACzD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE1F;AAED;;;;;GAKG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,WAAW,CAA+D;IAClF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAe;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,+DAA+D;IAC/D,OAAO,CAAC,IAAI,CAA4D;gBAE5D,MAAM,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,WAAW,EAAE,kBAAkB,EAAE,YAAY,EAAE,OAAO;IAkC9H,wEAAwE;IACxE,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAyBxC,wFAAwF;IACxF,IAAI,CAAC,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,qBAAqB,EAAE,GAAG,IAAI;IAe7H,OAAO,IAAI,IAAI;CAMhB"}
@@ -0,0 +1,150 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * The selection/hover mask pipelines (#5390), and the instanced variant that
6
+ * outlines GPU-instanced occurrences (#5745): repeated windows, doors,
7
+ * furniture and fasteners, whose "selected" flag lives in the per-instance
8
+ * record rather than in a mesh uniform.
9
+ *
10
+ * Both variants write the same three outputs into the same targets, so
11
+ * `edge-pass.ts`'s `encodeOutline` sees one mask whatever drew it. The
12
+ * instanced one differs only in its vertex stage (`vs_instanced` over
13
+ * `INSTANCED_VERTEX_BUFFERS`, exactly as the main instanced draw, so the
14
+ * mask lands where the occurrence was drawn) and in a per-occurrence filter
15
+ * in the fragment stage (`selection-mask.wgsl.ts`). Each template draws the
16
+ * same in-envelope instance runs the colour pass draws, over the same
17
+ * camera-relative delta stream (#6393); the fragment keeps the selected
18
+ * occurrences, or the hovered id's.
19
+ */
20
+ import { INSTANCED_RTE_DELTA_SLOT, INSTANCED_VERTEX_BUFFERS } from './instanced-vertex-layout.js';
21
+ import { drawInstanceRuns, uploadInstancedRteDeltas } from './instanced-rte.js';
22
+ import { mainShaderSource } from './shaders/main.wgsl.js';
23
+ import { SELECTION_MASK_DEPTH_GROUP, SELECTION_MASK_HOVER_GROUP, selectionMaskFragmentSource, } from './shaders/selection-mask.wgsl.js';
24
+ export const MASK_VISIBLE_FORMAT = 'rg8unorm';
25
+ export const MASK_ALL_FORMAT = 'r8unorm';
26
+ /** Additive blend: two draws to the same target OR their channels together (binary flags, unorm-clamped). */
27
+ const ADDITIVE_BLEND = {
28
+ color: { srcFactor: 'one', dstFactor: 'one' },
29
+ alpha: { srcFactor: 'one', dstFactor: 'one' },
30
+ };
31
+ const MASK_OUTPUTS = {
32
+ selectedVisible: { label: 'selected-visible', entryPoint: 'fs_mask_selected_visible', format: MASK_VISIBLE_FORMAT },
33
+ hoverVisible: { label: 'hover-visible', entryPoint: 'fs_mask_hover_visible', format: MASK_VISIBLE_FORMAT },
34
+ selectedAll: { label: 'selected-all', entryPoint: 'fs_mask_selected_all', format: MASK_ALL_FORMAT },
35
+ };
36
+ /** The three mask pipelines over one vertex stage and one fragment module. */
37
+ export function createMaskPipelines(device, labelPrefix, layout, vertex, fragmentModule) {
38
+ const make = (kind) => {
39
+ const out = MASK_OUTPUTS[kind];
40
+ return device.createRenderPipeline({
41
+ label: `${labelPrefix}-${out.label}`,
42
+ layout,
43
+ vertex,
44
+ fragment: { module: fragmentModule, entryPoint: out.entryPoint, targets: [{ format: out.format, blend: ADDITIVE_BLEND }] },
45
+ primitive: { topology: 'triangle-list', cullMode: 'none' },
46
+ });
47
+ };
48
+ return { selectedVisible: make('selectedVisible'), hoverVisible: make('hoverVisible'), selectedAll: make('selectedAll') };
49
+ }
50
+ /** True when the instanced frame has nothing to draw. */
51
+ export function isInstancedMaskEmpty(frame) {
52
+ return !frame || (frame.selected.length === 0 && frame.hovered.length === 0);
53
+ }
54
+ /**
55
+ * The instanced mask pipelines plus the two small uniforms they read: the
56
+ * mesh uniform (group 0, owned so no other draw's write can race it) and the
57
+ * hovered entity id (group `SELECTION_MASK_HOVER_GROUP`). Built on the first
58
+ * frame that has an instanced selection or hover.
59
+ */
60
+ export class InstancedSelectionMask {
61
+ device;
62
+ pipelines;
63
+ meshBindGroupLayout;
64
+ meshUniform = null;
65
+ hoverBuffer;
66
+ hoverBindGroup;
67
+ hoverScratch = new Uint32Array(4);
68
+ /** This frame's drawable runs per template, from `prepare`. */
69
+ runs = new Map();
70
+ constructor(device, meshBindGroupLayout, depthLayout, multisampled) {
71
+ this.device = device;
72
+ this.meshBindGroupLayout = meshBindGroupLayout;
73
+ const hoverLayout = device.createBindGroupLayout({
74
+ label: 'selection-mask-instanced-hover-bgl',
75
+ entries: [{ binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } }],
76
+ });
77
+ const groups = [];
78
+ groups[0] = meshBindGroupLayout;
79
+ groups[SELECTION_MASK_DEPTH_GROUP] = depthLayout;
80
+ groups[SELECTION_MASK_HOVER_GROUP] = hoverLayout;
81
+ const layout = device.createPipelineLayout({ label: 'selection-mask-instanced-layout', bindGroupLayouts: groups });
82
+ const vertex = {
83
+ module: device.createShaderModule({ label: 'selection-mask-instanced-vs', code: mainShaderSource }),
84
+ entryPoint: 'vs_instanced',
85
+ buffers: INSTANCED_VERTEX_BUFFERS,
86
+ };
87
+ const fragmentModule = device.createShaderModule({
88
+ label: 'selection-mask-instanced-fs',
89
+ code: selectionMaskFragmentSource(multisampled, true),
90
+ });
91
+ this.pipelines = createMaskPipelines(device, 'selection-mask-instanced', layout, vertex, fragmentModule);
92
+ this.hoverBuffer = device.createBuffer({
93
+ label: 'selection-mask-instanced-hover',
94
+ size: this.hoverScratch.byteLength,
95
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
96
+ });
97
+ this.hoverBindGroup = device.createBindGroup({
98
+ layout: hoverLayout,
99
+ entries: [{ binding: 0, resource: { buffer: this.hoverBuffer } }],
100
+ });
101
+ }
102
+ /** Upload this frame's uniforms. Call once per frame, before `draw`. */
103
+ prepare(frame) {
104
+ const { uniforms } = frame;
105
+ if (!this.meshUniform || this.meshUniform.buffer.size < uniforms.byteLength) {
106
+ this.meshUniform?.buffer.destroy();
107
+ const buffer = this.device.createBuffer({
108
+ label: 'selection-mask-instanced-uniforms',
109
+ size: uniforms.byteLength,
110
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
111
+ });
112
+ const bindGroup = this.device.createBindGroup({
113
+ layout: this.meshBindGroupLayout,
114
+ entries: [{ binding: 0, resource: { buffer } }],
115
+ });
116
+ this.meshUniform = { buffer, bindGroup };
117
+ }
118
+ this.device.queue.writeBuffer(this.meshUniform.buffer, 0, uniforms);
119
+ this.hoverScratch[0] = frame.hoveredId >>> 0;
120
+ this.device.queue.writeBuffer(this.hoverBuffer, 0, this.hoverScratch);
121
+ // Without this a template the colour pass culled this frame would read a
122
+ // delta stream packed for an older camera (or never packed at all).
123
+ const templates = [...new Set([...frame.selected, ...frame.hovered])];
124
+ const runs = uploadInstancedRteDeltas(this.device, templates, frame.rteCamera);
125
+ this.runs = new Map(templates.map((t, i) => [t, runs[i]]));
126
+ }
127
+ /** Draw `templates` into the open mask pass, one instanced draw per in-envelope run. */
128
+ draw(pass, kind, depthGroup, templates) {
129
+ if (templates.length === 0 || !this.meshUniform)
130
+ return;
131
+ pass.setPipeline(this.pipelines[kind]);
132
+ pass.setBindGroup(0, this.meshUniform.bindGroup);
133
+ pass.setBindGroup(SELECTION_MASK_DEPTH_GROUP, depthGroup);
134
+ pass.setBindGroup(SELECTION_MASK_HOVER_GROUP, this.hoverBindGroup);
135
+ for (const t of templates) {
136
+ pass.setVertexBuffer(0, t.vertexBuffer);
137
+ pass.setVertexBuffer(1, t.instanceBuffer);
138
+ pass.setVertexBuffer(INSTANCED_RTE_DELTA_SLOT, t.rteDeltas.buffer);
139
+ pass.setIndexBuffer(t.indexBuffer, 'uint32');
140
+ drawInstanceRuns(pass, t.indexCount, this.runs.get(t) ?? []);
141
+ }
142
+ }
143
+ destroy() {
144
+ this.meshUniform?.buffer.destroy();
145
+ this.meshUniform = null;
146
+ this.runs.clear();
147
+ this.hoverBuffer.destroy();
148
+ }
149
+ }
150
+ //# sourceMappingURL=selection-mask-pipelines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-mask-pipelines.js","sourceRoot":"","sources":["../src/selection-mask-pipelines.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAoB,MAAM,oBAAoB,CAAC;AAGlG,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,kCAAkC,CAAC;AAE1C,MAAM,CAAC,MAAM,mBAAmB,GAAqB,UAAU,CAAC;AAChE,MAAM,CAAC,MAAM,eAAe,GAAqB,SAAS,CAAC;AAE3D,6GAA6G;AAC7G,MAAM,cAAc,GAAkB;IACpC,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE;IAC7C,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE;CAC9C,CAAC;AAOF,MAAM,YAAY,GAAsF;IACtG,eAAe,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,EAAE,mBAAmB,EAAE;IACnH,YAAY,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,EAAE,mBAAmB,EAAE;IAC1G,WAAW,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,EAAE,eAAe,EAAE;CACpG,CAAC;AAEF,8EAA8E;AAC9E,MAAM,UAAU,mBAAmB,CACjC,MAAiB,EACjB,WAAmB,EACnB,MAAyB,EACzB,MAAsB,EACtB,cAA+B;IAE/B,MAAM,IAAI,GAAG,CAAC,IAAc,EAAE,EAAE;QAC9B,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,MAAM,CAAC,oBAAoB,CAAC;YACjC,KAAK,EAAE,GAAG,WAAW,IAAI,GAAG,CAAC,KAAK,EAAE;YACpC,MAAM;YACN,MAAM;YACN,QAAQ,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE;YAC1H,SAAS,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE;SAC3D,CAAC,CAAC;IACL,CAAC,CAAC;IACF,OAAO,EAAE,eAAe,EAAE,IAAI,CAAC,iBAAiB,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;AAC5H,CAAC;AA6BD,yDAAyD;AACzD,MAAM,UAAU,oBAAoB,CAAC,KAA4C;IAC/E,OAAO,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,sBAAsB;IAChB,MAAM,CAAY;IAClB,SAAS,CAAgB;IACzB,mBAAmB,CAAqB;IACjD,WAAW,GAA0D,IAAI,CAAC;IACjE,WAAW,CAAY;IACvB,cAAc,CAAe;IAC7B,YAAY,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;IACnD,+DAA+D;IACvD,IAAI,GAAG,IAAI,GAAG,EAAiD,CAAC;IAExE,YAAY,MAAiB,EAAE,mBAAuC,EAAE,WAA+B,EAAE,YAAqB;QAC5H,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;QAC/C,MAAM,WAAW,GAAG,MAAM,CAAC,qBAAqB,CAAC;YAC/C,KAAK,EAAE,oCAAoC;YAC3C,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;SAC5F,CAAC,CAAC;QACH,MAAM,MAAM,GAAyB,EAAE,CAAC;QACxC,MAAM,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC;QAChC,MAAM,CAAC,0BAA0B,CAAC,GAAG,WAAW,CAAC;QACjD,MAAM,CAAC,0BAA0B,CAAC,GAAG,WAAW,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC;QACnH,MAAM,MAAM,GAAmB;YAC7B,MAAM,EAAE,MAAM,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;YACnG,UAAU,EAAE,cAAc;YAC1B,OAAO,EAAE,wBAAwB;SAClC,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,CAAC,kBAAkB,CAAC;YAC/C,KAAK,EAAE,6BAA6B;YACpC,IAAI,EAAE,2BAA2B,CAAC,YAAY,EAAE,IAAI,CAAC;SACtD,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,mBAAmB,CAAC,MAAM,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QAEzG,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;YACrC,KAAK,EAAE,gCAAgC;YACvC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,UAAU;YAClC,KAAK,EAAE,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,QAAQ;SACxD,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,eAAe,CAAC;YAC3C,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;SAClE,CAAC,CAAC;IACL,CAAC;IAED,wEAAwE;IACxE,OAAO,CAAC,KAAyB;QAC/B,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC;YAC5E,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;gBACtC,KAAK,EAAE,mCAAmC;gBAC1C,IAAI,EAAE,QAAQ,CAAC,UAAU;gBACzB,KAAK,EAAE,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,QAAQ;aACxD,CAAC,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;gBAC5C,MAAM,EAAE,IAAI,CAAC,mBAAmB;gBAChC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC;aAChD,CAAC,CAAC;YACH,IAAI,CAAC,WAAW,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QACpE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QACtE,yEAAyE;QACzE,oEAAoE;QACpE,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,IAAI,GAAG,wBAAwB,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAC/E,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,wFAAwF;IACxF,IAAI,CAAC,IAA0B,EAAE,IAAc,EAAE,UAAwB,EAAE,SAA2C;QACpH,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO;QACxD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,YAAY,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAC;QAC1D,IAAI,CAAC,YAAY,CAAC,0BAA0B,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACnE,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;YACxC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC;YAC1C,IAAI,CAAC,eAAe,CAAC,wBAAwB,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACnE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC7C,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,47 @@
1
+ import { packRteFragmentSpace } from './mesh-rte-uniforms.js';
2
+ import type { RelativeToEyeFrame } from './relative-to-eye.js';
3
+ import type { IndividualMeshGpu } from './individual-mesh-upload.js';
4
+ import type { HoveredMesh, SelectableMesh } from './selection-mask-pass.js';
5
+ import type { InstancedMaskFrame, InstancedMaskTemplate } from './selection-mask-pipelines.js';
6
+ import type { InstancedTemplateGPU } from './scene-instance-types.js';
7
+ import type { ClipBox, Mesh } from './types.js';
8
+ export interface SelectionOutlineSource {
9
+ uniformBufferSize: number;
10
+ viewProj: Float32Array | number[];
11
+ relativeToEyeFrame: RelativeToEyeFrame;
12
+ /** Meshes the highlight-draw loop already prepared this frame (may be empty). */
13
+ selectedMeshes: readonly Mesh[];
14
+ /** GPU copies of the hovered entity's pieces, used when it is not among `selectedMeshes`. */
15
+ hoverPieces: readonly IndividualMeshGpu[];
16
+ hoveredId: number | null | undefined;
17
+ selectedModelIndex: number | undefined;
18
+ /** This frame's resolved section plane (the one every mesh draw packs). */
19
+ section: Parameters<typeof packRteFragmentSpace>[1];
20
+ sectionFlipped: boolean | undefined;
21
+ clipBox: ClipBox | null | undefined;
22
+ /** This frame's live instanced templates; those with a selected occurrence are outlined (#5745). */
23
+ instancedTemplates?: readonly InstancedTemplateGPU[];
24
+ /** Instanced templates holding an occurrence of `hoveredId` (#5745). */
25
+ instancedHovered?: readonly InstancedMaskTemplate[];
26
+ }
27
+ /**
28
+ * Whether `mesh` is the one `hoveredId` names, honouring the same
29
+ * per-model disambiguation `selectedMeshes` filters by. Pure and exported
30
+ * for unit testing; the two GPU-facing lookups above call it with `.find`.
31
+ */
32
+ export declare function matchesHoveredMesh(mesh: Mesh, hoveredId: number, selectedModelIndex: number | undefined): boolean;
33
+ /**
34
+ * Packs the mask pipeline's mesh uniform for a mesh that may not have one
35
+ * yet: the frame fields plus the mesh's model matrix and RTE drawable origin.
36
+ * Exported for unit testing.
37
+ */
38
+ export declare function packHoverUniforms(source: SelectionOutlineSource, mesh: Pick<Mesh, 'transform' | 'rteOrigin'>): Float32Array;
39
+ export interface SelectionOutlineFrameResult {
40
+ selected: SelectableMesh[];
41
+ /** Every piece of the hovered entity (empty when nothing is hovered). */
42
+ hovered: HoveredMesh[];
43
+ /** Instanced occurrences to outline, or null when none are selected or hovered. */
44
+ instanced: InstancedMaskFrame | null;
45
+ }
46
+ export declare function buildSelectionOutlineFrame(source: SelectionOutlineSource): SelectionOutlineFrameResult;
47
+ //# sourceMappingURL=selection-outline-frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-outline-frame.d.ts","sourceRoot":"","sources":["../src/selection-outline-frame.ts"],"names":[],"mappings":"AAsCA,OAAO,EAAuE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnI,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC/F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACrC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,YAAY,GAAG,MAAM,EAAE,CAAC;IAClC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,iFAAiF;IACjF,cAAc,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,6FAA6F;IAC7F,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC1C,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,2EAA2E;IAC3E,OAAO,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,oGAAoG;IACpG,kBAAkB,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACrD,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACrD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEjH;AA6BD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,sBAAsB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAAC,GAAG,YAAY,CAM3H;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,yEAAyE;IACzE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,mFAAmF;IACnF,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACtC;AAeD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,sBAAsB,GAAG,2BAA2B,CAwBtG"}
@@ -0,0 +1,122 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * Builds the selection/hover outline pass's per-frame input (#5390) from
6
+ * the meshes the main render pass already drew this frame. Extracted from
7
+ * `index.ts`'s `renderFrame`, which sits close to its module-size budget.
8
+ *
9
+ * Selected meshes reuse their EXISTING uniform buffer/bind group verbatim:
10
+ * `renderFrame`'s highlight-draw loop already wrote the correct
11
+ * view-projection, transform and RTE drawable origin into it earlier in
12
+ * the same frame (before this runs), and GPU queue writes are visible to
13
+ * command buffers submitted in the same `queue.submit` call, in submission
14
+ * order — so no re-pack is needed here.
15
+ *
16
+ * A hovered entity that is not selected has no individual mesh on a batched
17
+ * model, so the caller supplies GPU copies of ALL its pieces
18
+ * (`hover-mesh-cache.ts`); a selected one reuses its selection meshes. Either
19
+ * way every piece is outlined, not just the first. For the copies this packs
20
+ * the fields the mask pipeline reads:
21
+ * view-projection, model transform and RTE drawable origin (vertex
22
+ * position), plus the section plane, clip box and their `flags.y` bits
23
+ * (the mask fragments clip exactly like `fs_main`). It returns the packed
24
+ * floats, not a GPU buffer: `SelectionMaskPass` writes them into the one
25
+ * hover uniform buffer it owns, so hovering allocates nothing per frame.
26
+ *
27
+ * GPU-instanced occurrences (#5745) are not copied at all: the mask draws the
28
+ * templates themselves with `vs_instanced`, and the fragment keeps the
29
+ * selected occurrences (their instance flag) or the hovered id's. This packs
30
+ * the one uniform those draws read: the same frame fields as a hover copy, with
31
+ * an identity model matrix and no drawable origin. `vs_instanced` reads neither; each
32
+ * occurrence's origin comes from its per-instance RTE delta, exactly as in the
33
+ * main instanced colour pass. Packing a stand-in origin of [0, 0, 0] threw once
34
+ * the camera was over 1,000 km from the world origin (#6400).
35
+ */
36
+ import { packClipBox } from './clip-box.js';
37
+ import { MESH_FLAG_RTE_DRAWABLE, MESH_FLAGS_BYTE_OFFSET, MESH_UNIFORM_OFFSET, packRteFragmentSpace } from './mesh-rte-uniforms.js';
38
+ /**
39
+ * Whether `mesh` is the one `hoveredId` names, honouring the same
40
+ * per-model disambiguation `selectedMeshes` filters by. Pure and exported
41
+ * for unit testing; the two GPU-facing lookups above call it with `.find`.
42
+ */
43
+ export function matchesHoveredMesh(mesh, hoveredId, selectedModelIndex) {
44
+ return mesh.expressId === hoveredId && (selectedModelIndex === undefined || mesh.modelIndex === selectedModelIndex);
45
+ }
46
+ function toSelectable(mesh) {
47
+ if (!mesh.bindGroup)
48
+ return null;
49
+ return { vertexBuffer: mesh.vertexBuffer, indexBuffer: mesh.indexBuffer, indexCount: mesh.indexCount, bindGroup: mesh.bindGroup };
50
+ }
51
+ const IDENTITY_TRANSFORM = { m: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) };
52
+ /**
53
+ * Packs the per-frame fields every mask draw reads: view-projection, RTE
54
+ * view-projection, section plane, clip box and flags, with an identity model
55
+ * matrix and no drawable origin. Section / clip data go through the same
56
+ * `packClipBox` + `packRteFragmentSpace` pair `index.ts`'s mesh loop uses.
57
+ */
58
+ function packMaskFrameUniforms(source) {
59
+ const scratch = new Float32Array(source.uniformBufferSize / 4);
60
+ scratch.set(source.viewProj, 0);
61
+ scratch.set(IDENTITY_TRANSFORM.m, MESH_UNIFORM_OFFSET.model);
62
+ source.relativeToEyeFrame.packUniforms(scratch, MESH_UNIFORM_OFFSET.rteViewProj);
63
+ const clipBit = packClipBox(source.clipBox, scratch, MESH_UNIFORM_OFFSET.clipBoxMin);
64
+ packRteFragmentSpace(source.relativeToEyeFrame, source.section, source.clipBox, scratch);
65
+ const flags = new Uint32Array(scratch.buffer, MESH_FLAGS_BYTE_OFFSET, 2);
66
+ flags[0] = MESH_FLAG_RTE_DRAWABLE;
67
+ // flags.y: bit 0 = section enabled, bit 1 = flipped, bit 2 = clip box (as index.ts packs it).
68
+ flags[1] = (source.section?.enabled ? 1 : 0) | (source.sectionFlipped ? 2 : 0) | clipBit;
69
+ return scratch;
70
+ }
71
+ /**
72
+ * Packs the mask pipeline's mesh uniform for a mesh that may not have one
73
+ * yet: the frame fields plus the mesh's model matrix and RTE drawable origin.
74
+ * Exported for unit testing.
75
+ */
76
+ export function packHoverUniforms(source, mesh) {
77
+ const scratch = packMaskFrameUniforms(source);
78
+ scratch.set(mesh.transform.m, MESH_UNIFORM_OFFSET.model);
79
+ const origin = mesh.rteOrigin ?? [mesh.transform.m[12], mesh.transform.m[13], mesh.transform.m[14]];
80
+ source.relativeToEyeFrame.packDrawableOrigin(origin, scratch, MESH_UNIFORM_OFFSET.drawableDelta);
81
+ return scratch;
82
+ }
83
+ function buildInstancedMaskFrame(source) {
84
+ const selected = (source.instancedTemplates ?? []).filter((t) => t.selectedCount > 0);
85
+ const hovered = source.hoveredId != null ? source.instancedHovered ?? [] : [];
86
+ if (selected.length === 0 && hovered.length === 0)
87
+ return null;
88
+ return {
89
+ uniforms: packMaskFrameUniforms(source),
90
+ rteCamera: source.relativeToEyeFrame.getCameraWorld(),
91
+ selected,
92
+ hovered,
93
+ hoveredId: source.hoveredId ?? 0,
94
+ };
95
+ }
96
+ export function buildSelectionOutlineFrame(source) {
97
+ const selected = [];
98
+ for (const mesh of source.selectedMeshes) {
99
+ const s = toSelectable(mesh);
100
+ if (s)
101
+ selected.push(s);
102
+ }
103
+ const hovered = [];
104
+ if (source.hoveredId != null) {
105
+ const hoveredId = source.hoveredId;
106
+ const already = source.selectedMeshes.filter((m) => matchesHoveredMesh(m, hoveredId, source.selectedModelIndex));
107
+ if (already.length > 0) {
108
+ for (const mesh of already) {
109
+ const s = toSelectable(mesh);
110
+ if (s)
111
+ hovered.push(s);
112
+ }
113
+ }
114
+ else {
115
+ for (const piece of source.hoverPieces) {
116
+ hovered.push({ vertexBuffer: piece.vertexBuffer, indexBuffer: piece.indexBuffer, indexCount: piece.indexCount, uniforms: packHoverUniforms(source, piece) });
117
+ }
118
+ }
119
+ }
120
+ return { selected, hovered, instanced: buildInstancedMaskFrame(source) };
121
+ }
122
+ //# sourceMappingURL=selection-outline-frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-outline-frame.js","sourceRoot":"","sources":["../src/selection-outline-frame.ts"],"names":[],"mappings":"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"}
@@ -7,10 +7,15 @@
7
7
  * camera projection (see `depthReconstructParams`).
8
8
  */
9
9
  /**
10
- * Declares `depthTex` at `@group(0) @binding(binding)` and `loadDepth(ip)`,
10
+ * Declares `depthTex` at `@group(group) @binding(binding)` and `loadDepth(ip)`,
11
11
  * which clamps the coordinate to the texture and reads sample 0 when the
12
12
  * attachment is multisampled.
13
+ *
14
+ * `group` must match the index of the bind-group layout that carries the
15
+ * depth texture in the caller's pipeline layout. The full-screen passes (AO,
16
+ * edges) own group 0; the selection mask draws mesh geometry, so group 0 is
17
+ * the mesh uniform and the depth texture sits in group 1 (#5390).
13
18
  */
14
- export declare function depthTextureWgsl(binding: number, multisampled: boolean): string;
19
+ export declare function depthTextureWgsl(binding: number, multisampled: boolean, group?: number): string;
15
20
  export declare const depthReconstructWgsl = "\n // Reverse-Z clears to 0, so anything at or below this is background.\n const BACKGROUND_DEPTH: f32 = 1e-7;\n\n fn viewZFromDepth(d: f32, dp: vec4<f32>) -> f32 {\n return (dp.z - d * dp.w) / (d * dp.y - dp.x);\n }\n\n fn clipWFromViewZ(z: f32, dp: vec4<f32>) -> f32 {\n return dp.y * z + dp.w;\n }\n\n // Pixel centre to NDC (y up), for a buffer whose texel size is invDims.\n fn ndcFromPixel(ip: vec2<i32>, invDims: vec2<f32>) -> vec2<f32> {\n let uv = (vec2<f32>(ip) + 0.5) * invDims;\n return vec2<f32>(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0);\n }\n\n fn viewPositionFromDepth(ndc: vec2<f32>, d: f32, dp: vec4<f32>, xy: vec4<f32>) -> vec3<f32> {\n let z = viewZFromDepth(d, dp);\n let w = clipWFromViewZ(z, dp);\n return vec3<f32>((ndc.x * w - xy.z) / xy.x, (ndc.y * w - xy.w) / xy.y, z);\n }\n\n // Normal facing the camera, from a position and its four pixel\n // neighbours. On each axis it takes the neighbour with the smaller\n // depth step, so a pixel on a silhouette or a crease uses the side\n // on its own surface instead of averaging across the edge.\n fn normalFromNeighbours(\n p: vec3<f32>, right: vec3<f32>, left: vec3<f32>, down: vec3<f32>, up: vec3<f32>,\n ) -> vec3<f32> {\n let dxR = right - p;\n let dxL = p - left;\n let dx = select(dxR, dxL, abs(dxL.z) < abs(dxR.z));\n let dyD = down - p;\n let dyU = p - up;\n let dy = select(dyD, dyU, abs(dyU.z) < abs(dyD.z));\n // Pixel +x is view +x and pixel +y is view -y, so dy x dx faces +z.\n return normalize(cross(dy, dx));\n }\n";
16
21
  //# sourceMappingURL=depth-reconstruct.wgsl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"depth-reconstruct.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/depth-reconstruct.wgsl.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,MAAM,CAU/E;AAED,eAAO,MAAM,oBAAoB,+uDAwChC,CAAC"}
1
+ {"version":3,"file":"depth-reconstruct.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/depth-reconstruct.wgsl.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,MAAM,CAU1F;AAED,eAAO,MAAM,oBAAoB,+uDAwChC,CAAC"}