@ifc-lite/renderer 4.2.0 → 6.0.0

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 (307) 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-params.d.ts +43 -0
  21. package/dist/edge-params.d.ts.map +1 -0
  22. package/dist/edge-params.js +63 -0
  23. package/dist/edge-params.js.map +1 -0
  24. package/dist/edge-pass.d.ts +54 -0
  25. package/dist/edge-pass.d.ts.map +1 -0
  26. package/dist/edge-pass.js +185 -0
  27. package/dist/edge-pass.js.map +1 -0
  28. package/dist/entity-color-table.d.ts +140 -0
  29. package/dist/entity-color-table.d.ts.map +1 -0
  30. package/dist/entity-color-table.js +238 -0
  31. package/dist/entity-color-table.js.map +1 -0
  32. package/dist/gpu-upload-guard.d.ts +1 -1
  33. package/dist/gpu-upload-guard.js +1 -1
  34. package/dist/hover-mesh-cache.d.ts +29 -0
  35. package/dist/hover-mesh-cache.d.ts.map +1 -0
  36. package/dist/hover-mesh-cache.js +31 -0
  37. package/dist/hover-mesh-cache.js.map +1 -0
  38. package/dist/index.d.ts +43 -14
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +196 -189
  41. package/dist/index.js.map +1 -1
  42. package/dist/individual-mesh-upload.d.ts +24 -0
  43. package/dist/individual-mesh-upload.d.ts.map +1 -0
  44. package/dist/individual-mesh-upload.js +85 -0
  45. package/dist/individual-mesh-upload.js.map +1 -0
  46. package/dist/instanced-render.d.ts +22 -12
  47. package/dist/instanced-render.d.ts.map +1 -1
  48. package/dist/instanced-render.js +39 -27
  49. package/dist/instanced-render.js.map +1 -1
  50. package/dist/instanced-rte.d.ts +68 -7
  51. package/dist/instanced-rte.d.ts.map +1 -1
  52. package/dist/instanced-rte.js +98 -17
  53. package/dist/instanced-rte.js.map +1 -1
  54. package/dist/instanced-vertex-layout.d.ts +26 -0
  55. package/dist/instanced-vertex-layout.d.ts.map +1 -0
  56. package/dist/instanced-vertex-layout.js +61 -0
  57. package/dist/instanced-vertex-layout.js.map +1 -0
  58. package/dist/mesh-material.d.ts +26 -0
  59. package/dist/mesh-material.d.ts.map +1 -0
  60. package/dist/mesh-material.js +52 -0
  61. package/dist/mesh-material.js.map +1 -0
  62. package/dist/mesh-rte-uniforms.d.ts +5 -2
  63. package/dist/mesh-rte-uniforms.d.ts.map +1 -1
  64. package/dist/mesh-rte-uniforms.js +5 -2
  65. package/dist/mesh-rte-uniforms.js.map +1 -1
  66. package/dist/model-translation.d.ts.map +1 -1
  67. package/dist/model-translation.js +0 -7
  68. package/dist/model-translation.js.map +1 -1
  69. package/dist/outline-params.d.ts +45 -0
  70. package/dist/outline-params.d.ts.map +1 -0
  71. package/dist/outline-params.js +54 -0
  72. package/dist/outline-params.js.map +1 -0
  73. package/dist/overlay-routing.d.ts +8 -8
  74. package/dist/overlay-routing.js +2 -2
  75. package/dist/overlay-routing.js.map +1 -1
  76. package/dist/overlay-theme-uniforms.d.ts +54 -0
  77. package/dist/overlay-theme-uniforms.d.ts.map +1 -0
  78. package/dist/overlay-theme-uniforms.js +89 -0
  79. package/dist/overlay-theme-uniforms.js.map +1 -0
  80. package/dist/overlay-theme.d.ts +79 -0
  81. package/dist/overlay-theme.d.ts.map +1 -0
  82. package/dist/overlay-theme.js +24 -0
  83. package/dist/overlay-theme.js.map +1 -0
  84. package/dist/partial-batch-requests.d.ts +2 -2
  85. package/dist/pick-mesh-budget.d.ts +28 -0
  86. package/dist/pick-mesh-budget.d.ts.map +1 -0
  87. package/dist/pick-mesh-budget.js +74 -0
  88. package/dist/pick-mesh-budget.js.map +1 -0
  89. package/dist/picker-rte-uniforms.d.ts +7 -1
  90. package/dist/picker-rte-uniforms.d.ts.map +1 -1
  91. package/dist/picker-rte-uniforms.js +9 -1
  92. package/dist/picker-rte-uniforms.js.map +1 -1
  93. package/dist/picker.d.ts.map +1 -1
  94. package/dist/picker.js +15 -28
  95. package/dist/picker.js.map +1 -1
  96. package/dist/picking-manager.d.ts.map +1 -1
  97. package/dist/picking-manager.js +4 -47
  98. package/dist/picking-manager.js.map +1 -1
  99. package/dist/pipeline.d.ts +9 -1
  100. package/dist/pipeline.d.ts.map +1 -1
  101. package/dist/pipeline.js +47 -70
  102. package/dist/pipeline.js.map +1 -1
  103. package/dist/point-picker.d.ts.map +1 -1
  104. package/dist/point-picker.js +7 -2
  105. package/dist/point-picker.js.map +1 -1
  106. package/dist/pointcloud/point-cloud-node.js +1 -1
  107. package/dist/pointcloud/point-cloud-node.js.map +1 -1
  108. package/dist/pointcloud/point-cloud-renderer.d.ts.map +1 -1
  109. package/dist/pointcloud/point-cloud-renderer.js +3 -1
  110. package/dist/pointcloud/point-cloud-renderer.js.map +1 -1
  111. package/dist/pointcloud/point-cloud-uniforms.d.ts +5 -1
  112. package/dist/pointcloud/point-cloud-uniforms.d.ts.map +1 -1
  113. package/dist/pointcloud/point-cloud-uniforms.js +7 -1
  114. package/dist/pointcloud/point-cloud-uniforms.js.map +1 -1
  115. package/dist/post-pass-chain.d.ts +15 -2
  116. package/dist/post-pass-chain.d.ts.map +1 -1
  117. package/dist/post-pass-chain.js +49 -14
  118. package/dist/post-pass-chain.js.map +1 -1
  119. package/dist/raycast-engine.d.ts +5 -1
  120. package/dist/raycast-engine.d.ts.map +1 -1
  121. package/dist/raycast-engine.js +20 -8
  122. package/dist/raycast-engine.js.map +1 -1
  123. package/dist/raycast-point-cloud-query.d.ts +2 -0
  124. package/dist/raycast-point-cloud-query.d.ts.map +1 -1
  125. package/dist/raycast-point-cloud-query.js +7 -0
  126. package/dist/raycast-point-cloud-query.js.map +1 -1
  127. package/dist/raycast-source-curve-query.d.ts +13 -0
  128. package/dist/raycast-source-curve-query.d.ts.map +1 -0
  129. package/dist/raycast-source-curve-query.js +17 -0
  130. package/dist/raycast-source-curve-query.js.map +1 -0
  131. package/dist/reference-image-pipeline.d.ts.map +1 -1
  132. package/dist/reference-image-pipeline.js +4 -2
  133. package/dist/reference-image-pipeline.js.map +1 -1
  134. package/dist/relative-to-eye-abi.d.ts +36 -0
  135. package/dist/relative-to-eye-abi.d.ts.map +1 -0
  136. package/dist/relative-to-eye-abi.js +72 -0
  137. package/dist/relative-to-eye-abi.js.map +1 -0
  138. package/dist/relative-to-eye.d.ts +15 -35
  139. package/dist/relative-to-eye.d.ts.map +1 -1
  140. package/dist/relative-to-eye.js +46 -74
  141. package/dist/relative-to-eye.js.map +1 -1
  142. package/dist/render-stats.d.ts +5 -1
  143. package/dist/render-stats.d.ts.map +1 -1
  144. package/dist/render-stats.js +1 -1
  145. package/dist/render-stats.js.map +1 -1
  146. package/dist/renderer-overlays.d.ts +8 -7
  147. package/dist/renderer-overlays.d.ts.map +1 -1
  148. package/dist/renderer-overlays.js +14 -16
  149. package/dist/renderer-overlays.js.map +1 -1
  150. package/dist/scene-batch-rebuild.d.ts +1 -2
  151. package/dist/scene-batch-rebuild.d.ts.map +1 -1
  152. package/dist/scene-batch-rebuild.js +4 -8
  153. package/dist/scene-batch-rebuild.js.map +1 -1
  154. package/dist/scene-batch-upload.d.ts.map +1 -1
  155. package/dist/scene-batch-upload.js +7 -3
  156. package/dist/scene-batch-upload.js.map +1 -1
  157. package/dist/scene-contents.d.ts +1 -1
  158. package/dist/scene-contents.d.ts.map +1 -1
  159. package/dist/scene-derived-batches.d.ts +19 -64
  160. package/dist/scene-derived-batches.d.ts.map +1 -1
  161. package/dist/scene-derived-batches.js +16 -51
  162. package/dist/scene-derived-batches.js.map +1 -1
  163. package/dist/scene-device-recovery.d.ts +3 -3
  164. package/dist/scene-device-recovery.d.ts.map +1 -1
  165. package/dist/scene-device-recovery.js +12 -9
  166. package/dist/scene-device-recovery.js.map +1 -1
  167. package/dist/scene-geometry.d.ts +6 -6
  168. package/dist/scene-geometry.d.ts.map +1 -1
  169. package/dist/scene-geometry.js +8 -9
  170. package/dist/scene-geometry.js.map +1 -1
  171. package/dist/scene-instance-bounds.d.ts +1 -1
  172. package/dist/scene-instance-bounds.d.ts.map +1 -1
  173. package/dist/scene-instance-bounds.js +4 -16
  174. package/dist/scene-instance-bounds.js.map +1 -1
  175. package/dist/scene-instance-materialization.d.ts.map +1 -1
  176. package/dist/scene-instance-materialization.js +4 -4
  177. package/dist/scene-instance-materialization.js.map +1 -1
  178. package/dist/scene-instance-translation.d.ts +6 -10
  179. package/dist/scene-instance-translation.d.ts.map +1 -1
  180. package/dist/scene-instance-translation.js +9 -31
  181. package/dist/scene-instance-translation.js.map +1 -1
  182. package/dist/scene-instance-types.d.ts +11 -2
  183. package/dist/scene-instance-types.d.ts.map +1 -1
  184. package/dist/scene-instance-types.js +7 -1
  185. package/dist/scene-instance-types.js.map +1 -1
  186. package/dist/scene-model-translation.d.ts +1 -2
  187. package/dist/scene-model-translation.d.ts.map +1 -1
  188. package/dist/scene-model-translation.js +4 -3
  189. package/dist/scene-model-translation.js.map +1 -1
  190. package/dist/scene.d.ts +44 -30
  191. package/dist/scene.d.ts.map +1 -1
  192. package/dist/scene.js +121 -129
  193. package/dist/scene.js.map +1 -1
  194. package/dist/section-2d-line-buffer.d.ts +2 -2
  195. package/dist/section-2d-line-buffer.d.ts.map +1 -1
  196. package/dist/section-2d-line-buffer.js +10 -11
  197. package/dist/section-2d-line-buffer.js.map +1 -1
  198. package/dist/section-2d-overlay.d.ts +6 -4
  199. package/dist/section-2d-overlay.d.ts.map +1 -1
  200. package/dist/section-2d-overlay.js +45 -21
  201. package/dist/section-2d-overlay.js.map +1 -1
  202. package/dist/section-2d-types.d.ts +1 -1
  203. package/dist/section-2d-types.d.ts.map +1 -1
  204. package/dist/section-2d-types.js +1 -1
  205. package/dist/section-2d-types.js.map +1 -1
  206. package/dist/section-plane.d.ts +3 -0
  207. package/dist/section-plane.d.ts.map +1 -1
  208. package/dist/section-plane.js +18 -25
  209. package/dist/section-plane.js.map +1 -1
  210. package/dist/selection-mask-pass.d.ts +85 -0
  211. package/dist/selection-mask-pass.d.ts.map +1 -0
  212. package/dist/selection-mask-pass.js +170 -0
  213. package/dist/selection-mask-pass.js.map +1 -0
  214. package/dist/selection-mask-pipelines.d.ts +57 -0
  215. package/dist/selection-mask-pipelines.d.ts.map +1 -0
  216. package/dist/selection-mask-pipelines.js +150 -0
  217. package/dist/selection-mask-pipelines.js.map +1 -0
  218. package/dist/selection-outline-frame.d.ts +47 -0
  219. package/dist/selection-outline-frame.d.ts.map +1 -0
  220. package/dist/selection-outline-frame.js +122 -0
  221. package/dist/selection-outline-frame.js.map +1 -0
  222. package/dist/shaders/color-transfer.wgsl.d.ts +5 -3
  223. package/dist/shaders/color-transfer.wgsl.d.ts.map +1 -1
  224. package/dist/shaders/color-transfer.wgsl.js +5 -3
  225. package/dist/shaders/color-transfer.wgsl.js.map +1 -1
  226. package/dist/shaders/depth-reconstruct.wgsl.d.ts +7 -2
  227. package/dist/shaders/depth-reconstruct.wgsl.d.ts.map +1 -1
  228. package/dist/shaders/depth-reconstruct.wgsl.js +8 -3
  229. package/dist/shaders/depth-reconstruct.wgsl.js.map +1 -1
  230. package/dist/shaders/edges.wgsl.d.ts +20 -0
  231. package/dist/shaders/edges.wgsl.d.ts.map +1 -0
  232. package/dist/shaders/edges.wgsl.js +257 -0
  233. package/dist/shaders/edges.wgsl.js.map +1 -0
  234. package/dist/shaders/entity-color-table.wgsl.d.ts +2 -0
  235. package/dist/shaders/entity-color-table.wgsl.d.ts.map +1 -0
  236. package/dist/shaders/entity-color-table.wgsl.js +85 -0
  237. package/dist/shaders/entity-color-table.wgsl.js.map +1 -0
  238. package/dist/shaders/main.wgsl.d.ts +1 -1
  239. package/dist/shaders/main.wgsl.d.ts.map +1 -1
  240. package/dist/shaders/main.wgsl.js +107 -171
  241. package/dist/shaders/main.wgsl.js.map +1 -1
  242. package/dist/shaders/mesh-uniforms.wgsl.d.ts +2 -0
  243. package/dist/shaders/mesh-uniforms.wgsl.d.ts.map +1 -0
  244. package/dist/shaders/mesh-uniforms.wgsl.js +53 -0
  245. package/dist/shaders/mesh-uniforms.wgsl.js.map +1 -0
  246. package/dist/shaders/section-2d-overlay.wgsl.d.ts +1 -0
  247. package/dist/shaders/section-2d-overlay.wgsl.d.ts.map +1 -1
  248. package/dist/shaders/section-2d-overlay.wgsl.js +3 -2
  249. package/dist/shaders/section-2d-overlay.wgsl.js.map +1 -1
  250. package/dist/shaders/selection-mask.wgsl.d.ts +16 -0
  251. package/dist/shaders/selection-mask.wgsl.d.ts.map +1 -0
  252. package/dist/shaders/selection-mask.wgsl.js +138 -0
  253. package/dist/shaders/selection-mask.wgsl.js.map +1 -0
  254. package/dist/shaders/shadow.wgsl.d.ts +1 -1
  255. package/dist/shaders/shadow.wgsl.d.ts.map +1 -1
  256. package/dist/shaders/shadow.wgsl.js +3 -3
  257. package/dist/shaders/specular.wgsl.d.ts +34 -0
  258. package/dist/shaders/specular.wgsl.d.ts.map +1 -0
  259. package/dist/shaders/specular.wgsl.js +134 -0
  260. package/dist/shaders/specular.wgsl.js.map +1 -0
  261. package/dist/shadow-occluders.d.ts.map +1 -1
  262. package/dist/shadow-occluders.js +1 -0
  263. package/dist/shadow-occluders.js.map +1 -1
  264. package/dist/shadow-pass.d.ts +0 -1
  265. package/dist/shadow-pass.d.ts.map +1 -1
  266. package/dist/shadow-pass.js +26 -32
  267. package/dist/shadow-pass.js.map +1 -1
  268. package/dist/shadow-types.d.ts +3 -0
  269. package/dist/shadow-types.d.ts.map +1 -1
  270. package/dist/shadow-types.js.map +1 -1
  271. package/dist/snap-detector.d.ts +5 -0
  272. package/dist/snap-detector.d.ts.map +1 -1
  273. package/dist/snap-detector.js.map +1 -1
  274. package/dist/source-curve-clipping.d.ts +7 -0
  275. package/dist/source-curve-clipping.d.ts.map +1 -0
  276. package/dist/source-curve-clipping.js +165 -0
  277. package/dist/source-curve-clipping.js.map +1 -0
  278. package/dist/source-curve-snap.d.ts +49 -0
  279. package/dist/source-curve-snap.d.ts.map +1 -0
  280. package/dist/source-curve-snap.js +197 -0
  281. package/dist/source-curve-snap.js.map +1 -0
  282. package/dist/symbolic-overlay-pipelines.d.ts +1 -1
  283. package/dist/symbolic-overlay-pipelines.d.ts.map +1 -1
  284. package/dist/symbolic-overlay-pipelines.js +13 -22
  285. package/dist/symbolic-overlay-pipelines.js.map +1 -1
  286. package/dist/symbolic-text-rte.d.ts +16 -0
  287. package/dist/symbolic-text-rte.d.ts.map +1 -0
  288. package/dist/symbolic-text-rte.js +37 -0
  289. package/dist/symbolic-text-rte.js.map +1 -0
  290. package/dist/textured-vertices.d.ts.map +1 -1
  291. package/dist/textured-vertices.js +2 -3
  292. package/dist/textured-vertices.js.map +1 -1
  293. package/dist/types.d.ts +10 -0
  294. package/dist/types.d.ts.map +1 -1
  295. package/dist/visual-enhancement.d.ts +10 -7
  296. package/dist/visual-enhancement.d.ts.map +1 -1
  297. package/dist/visual-enhancement.js +9 -8
  298. package/dist/visual-enhancement.js.map +1 -1
  299. package/dist/xray-alpha.d.ts +7 -3
  300. package/dist/xray-alpha.d.ts.map +1 -1
  301. package/dist/xray-alpha.js +11 -7
  302. package/dist/xray-alpha.js.map +1 -1
  303. package/package.json +4 -4
  304. package/dist/post-processor.d.ts +0 -46
  305. package/dist/post-processor.d.ts.map +0 -1
  306. package/dist/post-processor.js +0 -295
  307. package/dist/post-processor.js.map +0 -1
@@ -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"}
@@ -10,14 +10,19 @@
10
10
  * camera projection (see `depthReconstructParams`).
11
11
  */
12
12
  /**
13
- * Declares `depthTex` at `@group(0) @binding(binding)` and `loadDepth(ip)`,
13
+ * Declares `depthTex` at `@group(group) @binding(binding)` and `loadDepth(ip)`,
14
14
  * which clamps the coordinate to the texture and reads sample 0 when the
15
15
  * attachment is multisampled.
16
+ *
17
+ * `group` must match the index of the bind-group layout that carries the
18
+ * depth texture in the caller's pipeline layout. The full-screen passes (AO,
19
+ * edges) own group 0; the selection mask draws mesh geometry, so group 0 is
20
+ * the mesh uniform and the depth texture sits in group 1 (#5390).
16
21
  */
17
- export function depthTextureWgsl(binding, multisampled) {
22
+ export function depthTextureWgsl(binding, multisampled, group = 0) {
18
23
  const type = multisampled ? 'texture_depth_multisampled_2d' : 'texture_depth_2d';
19
24
  return `
20
- @group(0) @binding(${binding}) var depthTex: ${type};
25
+ @group(${group}) @binding(${binding}) var depthTex: ${type};
21
26
 
22
27
  fn loadDepth(ip: vec2<i32>) -> f32 {
23
28
  let dims = vec2<i32>(textureDimensions(depthTex));
@@ -1 +1 @@
1
- {"version":3,"file":"depth-reconstruct.wgsl.js","sourceRoot":"","sources":["../../src/shaders/depth-reconstruct.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,YAAqB;IACrE,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACjF,OAAO;6BACoB,OAAO,mBAAmB,IAAI;;;;;;CAM1D,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCnC,CAAC"}
1
+ {"version":3,"file":"depth-reconstruct.wgsl.js","sourceRoot":"","sources":["../../src/shaders/depth-reconstruct.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;GAOG;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,YAAqB,EAAE,KAAK,GAAG,CAAC;IAChF,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACjF,OAAO;iBACQ,KAAK,cAAc,OAAO,mBAAmB,IAAI;;;;;;CAMjE,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCnC,CAAC"}
@@ -0,0 +1,20 @@
1
+ export declare function edgeShaderSource(multisampled: boolean): string;
2
+ /**
3
+ * Selection/hover outline composite (#5390): outlines the mask the
4
+ * selection-mask pass wrote (`selection-mask-pass.ts`), sharing this
5
+ * module's fullscreen-triangle vertex stage with the geometry edge pass
6
+ * above (DRY, per the #5385/#5390 design note) even though the two run as
7
+ * separate draws with different blend states (this one is a normal
8
+ * alpha-over composite; the geometry pass above is darken-only).
9
+ *
10
+ * Coverage is a ring around the mask boundary: the distance to the nearest
11
+ * mask pixel that differs from this one, searched within
12
+ * `OUTLINE_SEARCH_RADIUS`, mapped through `outlineCoverage`
13
+ * (`outline-params.ts`): full within `OUTLINE_WIDTH_PX` of the boundary on
14
+ * either side, fading over the next pixel. (Averaging 4 neighbour taps
15
+ * instead gives a straight edge only 1/4 coverage, a 1 px line too faint to
16
+ * see.) No depth/normal reconstruction needed: a mask boundary is
17
+ * unambiguous on its own.
18
+ */
19
+ export declare function outlineFragmentSource(): string;
20
+ //# sourceMappingURL=edges.wgsl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edges.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/edges.wgsl.ts"],"names":[],"mappings":"AA2BA,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,CAqI9D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAgF9C"}
@@ -0,0 +1,257 @@
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
+ * Edge pass (#5385): a single fullscreen pass that darkens along entity-id
6
+ * changes, normal creases, and depth silhouettes, replacing the separation-
7
+ * line pass in `post-processor.ts`.
8
+ *
9
+ * View-space position and normal come from `depth-reconstruct.wgsl.ts`
10
+ * (shared with the ambient-occlusion pass, #5384: one reconstruction, not
11
+ * two). The entity-id attachment is decoded the same way the old
12
+ * separation-line pass did (`encodeId24`/`decodeId24` in `main.wgsl.ts`).
13
+ *
14
+ * Each of `directions` tap offsets (4 cardinal at `low`, +4 diagonal at
15
+ * `high`) votes 0/1 on three cues — id change, normal crease, depth
16
+ * silhouette — and the pass darkens by the AVERAGE vote across directions.
17
+ * That average is a coverage estimate, not a single hard sample, so a line
18
+ * that only grazes one direction fades instead of dashing on/off between
19
+ * frames of the same seam (the bug this pass replaces, `post-processor.ts`
20
+ * introduced its own version of this coverage trick for the id test alone;
21
+ * this generalises it to all three cues and both new tests).
22
+ */
23
+ import { EDGE_CREASE_COS, EDGE_MAX_DARKEN, EDGE_SILHOUETTE_REL_THRESHOLD } from '../edge-params.js';
24
+ import { OUTLINE_SEARCH_RADIUS, OUTLINE_WIDTH_PX, SELECTION_HIDDEN_ALPHA } from '../outline-params.js';
25
+ import { depthReconstructWgsl, depthTextureWgsl } from './depth-reconstruct.wgsl.js';
26
+ export function edgeShaderSource(multisampled) {
27
+ // Multisampled and non-multisampled `textureLoad` share this call shape:
28
+ // the third argument is the sample index (MS) or the mip level (non-MS),
29
+ // both 0, so one call site covers both declarations (`post-processor.ts`
30
+ // used the same trick).
31
+ const idTexDecl = multisampled
32
+ ? '@group(0) @binding(1) var idTex: texture_multisampled_2d<f32>;'
33
+ : '@group(0) @binding(1) var idTex: texture_2d<f32>;';
34
+ return `
35
+ struct EdgeParams {
36
+ depthParams: vec4<f32>, // m10, m11, m14, m15
37
+ xyParams: vec4<f32>, // m0, m5, m12, m13
38
+ viewport: vec4<f32>, // full-res width, height, 1/width, 1/height
39
+ edge: vec4<f32>, // tap radius px, intensity, highQuality (0/1), _pad
40
+ }
41
+
42
+ ${depthTextureWgsl(0, multisampled)}
43
+ ${idTexDecl}
44
+ @group(0) @binding(2) var<uniform> params: EdgeParams;
45
+
46
+ ${depthReconstructWgsl}
47
+
48
+ const EDGE_CREASE_COS: f32 = ${EDGE_CREASE_COS.toFixed(6)};
49
+ const EDGE_SILHOUETTE_REL: f32 = ${EDGE_SILHOUETTE_REL_THRESHOLD.toFixed(6)};
50
+ const EDGE_MAX_DARKEN: f32 = ${EDGE_MAX_DARKEN.toFixed(3)};
51
+
52
+ struct VsOut {
53
+ @builtin(position) pos: vec4<f32>,
54
+ }
55
+
56
+ @vertex
57
+ fn vs_fullscreen(@builtin(vertex_index) v: u32) -> VsOut {
58
+ var p = array<vec2<f32>, 3>(
59
+ vec2<f32>(-1.0, -3.0),
60
+ vec2<f32>(-1.0, 1.0),
61
+ vec2<f32>( 3.0, 1.0)
62
+ );
63
+ var o: VsOut;
64
+ o.pos = vec4<f32>(p[v], 0.0, 1.0);
65
+ return o;
66
+ }
67
+
68
+ fn decodeId24(encoded: vec4<f32>) -> u32 {
69
+ let r = u32(round(encoded.r * 255.0)) & 255u;
70
+ let g = u32(round(encoded.g * 255.0)) & 255u;
71
+ let b = u32(round(encoded.b * 255.0)) & 255u;
72
+ return (r << 16u) | (g << 8u) | b;
73
+ }
74
+
75
+ fn loadId(ip: vec2<i32>, dims: vec2<i32>) -> u32 {
76
+ let c = clamp(ip, vec2<i32>(0), dims - 1);
77
+ return decodeId24(textureLoad(idTex, c, 0));
78
+ }
79
+
80
+ fn viewPosAt(ip: vec2<i32>, d: f32) -> vec3<f32> {
81
+ return viewPositionFromDepth(ndcFromPixel(ip, params.viewport.zw), d, params.depthParams, params.xyParams);
82
+ }
83
+
84
+ // One tap direction's edge vote in [0, 1]: 1 if the id changes, the
85
+ // local normal creases past the angle threshold, or the view-space
86
+ // depth steps past the silhouette threshold.
87
+ fn tapVote(p: vec2<i32>, q: vec2<i32>, dims: vec2<i32>, centerId: u32, centerP: vec3<f32>, centerN: vec3<f32>) -> f32 {
88
+ let qc = clamp(q, vec2<i32>(0), dims - 1);
89
+ let dq = loadDepth(qc);
90
+ if (dq <= BACKGROUND_DEPTH) {
91
+ return 0.0;
92
+ }
93
+ let neighbourId = loadId(qc, dims);
94
+ let idVote = f32(neighbourId != centerId && neighbourId != 0u && centerId != 0u);
95
+
96
+ let Pq = viewPosAt(qc, dq);
97
+ let depthRef = max(-centerP.z, 1e-4);
98
+ let silhouetteVote = f32(abs(Pq.z - centerP.z) / depthRef > EDGE_SILHOUETTE_REL);
99
+
100
+ // Neighbour normal from ITS OWN neighbours (not just the two
101
+ // points), so a grazing coplanar surface (large positional slope,
102
+ // near-zero normal change) does not misread as a crease.
103
+ let dLeft = loadDepth(clamp(qc + vec2<i32>(-1, 0), vec2<i32>(0), dims - 1));
104
+ let dRight = loadDepth(clamp(qc + vec2<i32>(1, 0), vec2<i32>(0), dims - 1));
105
+ let dUp = loadDepth(clamp(qc + vec2<i32>(0, -1), vec2<i32>(0), dims - 1));
106
+ let dDown = loadDepth(clamp(qc + vec2<i32>(0, 1), vec2<i32>(0), dims - 1));
107
+ let Nq = normalFromNeighbours(
108
+ Pq,
109
+ select(centerP, viewPosAt(qc + vec2<i32>(1, 0), dRight), dRight > BACKGROUND_DEPTH),
110
+ select(centerP, viewPosAt(qc + vec2<i32>(-1, 0), dLeft), dLeft > BACKGROUND_DEPTH),
111
+ select(centerP, viewPosAt(qc + vec2<i32>(0, 1), dDown), dDown > BACKGROUND_DEPTH),
112
+ select(centerP, viewPosAt(qc + vec2<i32>(0, -1), dUp), dUp > BACKGROUND_DEPTH),
113
+ );
114
+ let creaseVote = f32(dot(centerN, Nq) < EDGE_CREASE_COS);
115
+
116
+ return max(idVote, max(creaseVote, silhouetteVote));
117
+ }
118
+
119
+ @fragment
120
+ fn fs_edges(@builtin(position) fragPos: vec4<f32>) -> @location(0) vec4<f32> {
121
+ let dims = vec2<i32>(params.viewport.xy);
122
+ let p = vec2<i32>(fragPos.xy);
123
+ let d = loadDepth(p);
124
+ if (d <= BACKGROUND_DEPTH) {
125
+ return vec4<f32>(0.0, 0.0, 0.0, 0.0);
126
+ }
127
+ let centerId = loadId(p, dims);
128
+ let centerP = viewPosAt(p, d);
129
+ let centerN = normalFromNeighbours(
130
+ centerP,
131
+ viewPosAt(clamp(p + vec2<i32>(1, 0), vec2<i32>(0), dims - 1), loadDepth(p + vec2<i32>(1, 0))),
132
+ viewPosAt(clamp(p - vec2<i32>(1, 0), vec2<i32>(0), dims - 1), loadDepth(p - vec2<i32>(1, 0))),
133
+ viewPosAt(clamp(p + vec2<i32>(0, 1), vec2<i32>(0), dims - 1), loadDepth(p + vec2<i32>(0, 1))),
134
+ viewPosAt(clamp(p - vec2<i32>(0, 1), vec2<i32>(0), dims - 1), loadDepth(p - vec2<i32>(0, 1))),
135
+ );
136
+
137
+ let r = i32(round(params.edge.x));
138
+ var votes = 0.0;
139
+ votes = votes + tapVote(p, p + vec2<i32>( r, 0), dims, centerId, centerP, centerN);
140
+ votes = votes + tapVote(p, p + vec2<i32>(-r, 0), dims, centerId, centerP, centerN);
141
+ votes = votes + tapVote(p, p + vec2<i32>( 0, r), dims, centerId, centerP, centerN);
142
+ votes = votes + tapVote(p, p + vec2<i32>( 0, -r), dims, centerId, centerP, centerN);
143
+ var directions = 4.0;
144
+
145
+ if (params.edge.z > 0.5) {
146
+ votes = votes + tapVote(p, p + vec2<i32>( r, r), dims, centerId, centerP, centerN);
147
+ votes = votes + tapVote(p, p + vec2<i32>(-r, r), dims, centerId, centerP, centerN);
148
+ votes = votes + tapVote(p, p + vec2<i32>( r, -r), dims, centerId, centerP, centerN);
149
+ votes = votes + tapVote(p, p + vec2<i32>(-r, -r), dims, centerId, centerP, centerN);
150
+ directions = 8.0;
151
+ }
152
+
153
+ let coverage = votes / directions;
154
+ let darken = clamp(coverage * params.edge.y, 0.0, EDGE_MAX_DARKEN);
155
+ return vec4<f32>(0.0, 0.0, 0.0, darken);
156
+ }
157
+ `;
158
+ }
159
+ /**
160
+ * Selection/hover outline composite (#5390): outlines the mask the
161
+ * selection-mask pass wrote (`selection-mask-pass.ts`), sharing this
162
+ * module's fullscreen-triangle vertex stage with the geometry edge pass
163
+ * above (DRY, per the #5385/#5390 design note) even though the two run as
164
+ * separate draws with different blend states (this one is a normal
165
+ * alpha-over composite; the geometry pass above is darken-only).
166
+ *
167
+ * Coverage is a ring around the mask boundary: the distance to the nearest
168
+ * mask pixel that differs from this one, searched within
169
+ * `OUTLINE_SEARCH_RADIUS`, mapped through `outlineCoverage`
170
+ * (`outline-params.ts`): full within `OUTLINE_WIDTH_PX` of the boundary on
171
+ * either side, fading over the next pixel. (Averaging 4 neighbour taps
172
+ * instead gives a straight edge only 1/4 coverage, a 1 px line too faint to
173
+ * see.) No depth/normal reconstruction needed: a mask boundary is
174
+ * unambiguous on its own.
175
+ */
176
+ export function outlineFragmentSource() {
177
+ return `
178
+ struct OutlineParams {
179
+ viewport: vec4<f32>, // width, height, unused, unused
180
+ selectionColor: vec4<f32>, // rgb, visible alpha
181
+ hoverColor: vec4<f32>, // rgb, visible alpha
182
+ }
183
+
184
+ @group(0) @binding(0) var maskVisible: texture_2d<f32>;
185
+ @group(0) @binding(1) var maskAll: texture_2d<f32>;
186
+ @group(0) @binding(2) var<uniform> params: OutlineParams;
187
+
188
+ const SELECTION_HIDDEN_ALPHA: f32 = ${SELECTION_HIDDEN_ALPHA.toFixed(3)};
189
+
190
+ struct VsOut {
191
+ @builtin(position) pos: vec4<f32>,
192
+ }
193
+
194
+ @vertex
195
+ fn vs_fullscreen(@builtin(vertex_index) v: u32) -> VsOut {
196
+ var p = array<vec2<f32>, 3>(
197
+ vec2<f32>(-1.0, -3.0),
198
+ vec2<f32>(-1.0, 1.0),
199
+ vec2<f32>( 3.0, 1.0)
200
+ );
201
+ var o: VsOut;
202
+ o.pos = vec4<f32>(p[v], 0.0, 1.0);
203
+ return o;
204
+ }
205
+
206
+ fn loadClamped(tex: texture_2d<f32>, ip: vec2<i32>, dims: vec2<i32>) -> vec4<f32> {
207
+ return textureLoad(tex, clamp(ip, vec2<i32>(0), dims - 1), 0);
208
+ }
209
+
210
+ const OUTLINE_SEARCH_RADIUS: i32 = ${OUTLINE_SEARCH_RADIUS};
211
+ const OUTLINE_WIDTH_PX: f32 = ${OUTLINE_WIDTH_PX.toFixed(3)};
212
+
213
+ // Ring coverage astride the mask boundary (outline-params.ts's
214
+ // outlineCoverage): distance to the nearest pixel whose channel
215
+ // differs from this one, full within OUTLINE_WIDTH_PX, 0 one pixel on.
216
+ fn boundaryCoverage(tex: texture_2d<f32>, channel: u32, p: vec2<i32>, dims: vec2<i32>) -> f32 {
217
+ let center = loadClamped(tex, p, dims)[channel] > 0.5;
218
+ var nearest = 1e4;
219
+ for (var dy = -OUTLINE_SEARCH_RADIUS; dy <= OUTLINE_SEARCH_RADIUS; dy = dy + 1) {
220
+ for (var dx = -OUTLINE_SEARCH_RADIUS; dx <= OUTLINE_SEARCH_RADIUS; dx = dx + 1) {
221
+ if ((loadClamped(tex, p + vec2<i32>(dx, dy), dims)[channel] > 0.5) != center) {
222
+ nearest = min(nearest, length(vec2<f32>(f32(dx), f32(dy))));
223
+ }
224
+ }
225
+ }
226
+ return clamp(OUTLINE_WIDTH_PX + 0.5 - nearest, 0.0, 1.0);
227
+ }
228
+
229
+ @fragment
230
+ fn fs_outline(@builtin(position) fragPos: vec4<f32>) -> @location(0) vec4<f32> {
231
+ let dims = vec2<i32>(params.viewport.xy);
232
+ let p = vec2<i32>(fragPos.xy);
233
+
234
+ let visibleCoverage = boundaryCoverage(maskVisible, 0u, p, dims);
235
+ let allCoverage = boundaryCoverage(maskAll, 0u, p, dims);
236
+ let hoverCoverage = boundaryCoverage(maskVisible, 1u, p, dims);
237
+
238
+ // The "hidden" ring is the silhouette of the unoccluded shape
239
+ // (maskAll) wherever this pixel is not itself part of the visible
240
+ // selection — so it does not double up with the solid ring.
241
+ let centerVisible = loadClamped(maskVisible, p, dims).r;
242
+ let hiddenCoverage = allCoverage * (1.0 - centerVisible);
243
+
244
+ let selectionAlpha = clamp(
245
+ max(visibleCoverage * params.selectionColor.a, hiddenCoverage * SELECTION_HIDDEN_ALPHA),
246
+ 0.0, 1.0,
247
+ );
248
+ if (selectionAlpha > 0.001) {
249
+ return vec4<f32>(params.selectionColor.rgb * selectionAlpha, selectionAlpha);
250
+ }
251
+
252
+ let hoverAlpha = clamp(hoverCoverage * params.hoverColor.a, 0.0, 1.0);
253
+ return vec4<f32>(params.hoverColor.rgb * hoverAlpha, hoverAlpha);
254
+ }
255
+ `;
256
+ }
257
+ //# sourceMappingURL=edges.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edges.wgsl.js","sourceRoot":"","sources":["../../src/shaders/edges.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AACpG,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACvG,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAErF,MAAM,UAAU,gBAAgB,CAAC,YAAqB;IACpD,yEAAyE;IACzE,yEAAyE;IACzE,yEAAyE;IACzE,wBAAwB;IACxB,MAAM,SAAS,GAAG,YAAY;QAC5B,CAAC,CAAC,gEAAgE;QAClE,CAAC,CAAC,mDAAmD,CAAC;IAExD,OAAO;;;;;;;;UAQC,gBAAgB,CAAC,CAAC,EAAE,YAAY,CAAC;UACjC,SAAS;;;UAGT,oBAAoB;;uCAES,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;2CACtB,6BAA6B,CAAC,OAAO,CAAC,CAAC,CAAC;uCAC5C,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2GhE,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;;;;;;;;;;;8CAWqC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;6CAsBlC,qBAAqB;wCAC1B,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4ClE,CAAC;AACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const entityColorTableWgsl = "\n @binding(5) @group(1) var<storage, read> entityColorTable: array<u32>;\n const ENTITY_COLOR_EMPTY: u32 = 4294967295u;\n const ENTITY_COLOR_HEADER: u32 = 4u;\n const OVERRIDE_PAINT: u32 = 1u;\n const OVERRIDE_EMPHASIZE: u32 = 2u;\n\n fn entityColorSlotHash(key: u32) -> u32 {\n var h = key;\n h = h ^ (h >> 16u);\n h = h * 0x85ebca6bu;\n h = h ^ (h >> 13u);\n h = h * 0xc2b2ae35u;\n h = h ^ (h >> 16u);\n return h;\n }\n\n // Full scene id behind a 24-bit lane, given the draw's smallest id.\n fn resolveLaneEntityId(anchor: u32, lane: u32) -> u32 {\n return anchor + ((lane - anchor) & 0x00FFFFFFu);\n }\n\n // The override colour for this fragment's entity; alpha < 0 = none.\n fn entityOverrideColor(lane: u32) -> vec4<f32> {\n let none = vec4<f32>(0.0, 0.0, 0.0, -1.0);\n if ((uniforms.overrideParams.y & OVERRIDE_PAINT) == 0u || entityColorTable[2] == 0u) {\n return none;\n }\n let capacity = entityColorTable[0];\n let maxProbe = entityColorTable[1];\n let colorBase = entityColorTable[3];\n let id = resolveLaneEntityId(uniforms.overrideParams.x, lane);\n let mask = capacity - 1u;\n var slot = entityColorSlotHash(id) & mask;\n for (var i = 0u; i <= maxProbe && i < capacity; i = i + 1u) {\n let key = entityColorTable[ENTITY_COLOR_HEADER + slot];\n if (key == id) {\n let c = colorBase + slot * 4u;\n return vec4<f32>(\n bitcast<f32>(entityColorTable[c]),\n bitcast<f32>(entityColorTable[c + 1u]),\n bitcast<f32>(entityColorTable[c + 2u]),\n bitcast<f32>(entityColorTable[c + 3u])\n );\n }\n if (key == ENTITY_COLOR_EMPTY) {\n break;\n }\n slot = (slot + 1u) & mask;\n }\n return none;\n }\n\n // Composite an override over the fragment's own encoded colour exactly\n // as the retired equal-depth overlay pass blended it (src-alpha over\n // the base draw): the override albedo lit by the same irradiance, no\n // specular, the same roll-off and edge darkening, mixed by its alpha.\n // Emphasized overrides are unlit, faintly faceted and opaque (#1277).\n fn paintEntityOverride(base: vec4<f32>, ov: vec4<f32>, irradiance: vec3<f32>, N: vec3<f32>) -> vec4<f32> {\n let albedo = srgbToLinear(ov.rgb);\n var lit = albedo * irradiance;\n var a = ov.a;\n if ((uniforms.overrideParams.y & OVERRIDE_EMPHASIZE) != 0u) {\n lit = albedo * (0.85 + 0.15 * abs(dot(N, normalize(vec3<f32>(0.3, 1.0, 0.2)))));\n a = 1.0;\n }\n let encoded = linearToSrgb(clamp(neutralCompress(lit), vec3<f32>(0.0), vec3<f32>(1.0)));\n return vec4<f32>(mix(base.rgb, encoded, a), a + (1.0 - a) * base.a);\n }\n";
2
+ //# sourceMappingURL=entity-color-table.wgsl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-color-table.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/entity-color-table.wgsl.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,oBAAoB,mhGAqEhC,CAAC"}
@@ -0,0 +1,85 @@
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
+ * WGSL half of the per-entity colour table (#6076; layout, anchor rule and
6
+ * memory bound in `entity-color-table.ts`, whose `lookupEntityColor` and
7
+ * `resolveLaneEntityId` are the CPU mirrors of the functions below).
8
+ *
9
+ * Inlined into main.wgsl.ts after the Uniforms struct and the colour-transfer
10
+ * helpers, so it reads `uniforms.overrideParams` and reuses `srgbToLinear`,
11
+ * `neutralCompress` and `linearToSrgb`. The table sits at group(1) binding 5,
12
+ * beside the lighting environment, because it is scene-global.
13
+ */
14
+ import { ENTITY_COLOR_EMPTY_KEY, ENTITY_COLOR_HEADER_WORDS, OVERRIDE_PARAM_EMPHASIZE, OVERRIDE_PARAM_PAINT } from '../entity-color-table.js';
15
+ export const entityColorTableWgsl = `
16
+ @binding(5) @group(1) var<storage, read> entityColorTable: array<u32>;
17
+ const ENTITY_COLOR_EMPTY: u32 = ${ENTITY_COLOR_EMPTY_KEY}u;
18
+ const ENTITY_COLOR_HEADER: u32 = ${ENTITY_COLOR_HEADER_WORDS}u;
19
+ const OVERRIDE_PAINT: u32 = ${OVERRIDE_PARAM_PAINT}u;
20
+ const OVERRIDE_EMPHASIZE: u32 = ${OVERRIDE_PARAM_EMPHASIZE}u;
21
+
22
+ fn entityColorSlotHash(key: u32) -> u32 {
23
+ var h = key;
24
+ h = h ^ (h >> 16u);
25
+ h = h * 0x85ebca6bu;
26
+ h = h ^ (h >> 13u);
27
+ h = h * 0xc2b2ae35u;
28
+ h = h ^ (h >> 16u);
29
+ return h;
30
+ }
31
+
32
+ // Full scene id behind a 24-bit lane, given the draw's smallest id.
33
+ fn resolveLaneEntityId(anchor: u32, lane: u32) -> u32 {
34
+ return anchor + ((lane - anchor) & 0x00FFFFFFu);
35
+ }
36
+
37
+ // The override colour for this fragment's entity; alpha < 0 = none.
38
+ fn entityOverrideColor(lane: u32) -> vec4<f32> {
39
+ let none = vec4<f32>(0.0, 0.0, 0.0, -1.0);
40
+ if ((uniforms.overrideParams.y & OVERRIDE_PAINT) == 0u || entityColorTable[2] == 0u) {
41
+ return none;
42
+ }
43
+ let capacity = entityColorTable[0];
44
+ let maxProbe = entityColorTable[1];
45
+ let colorBase = entityColorTable[3];
46
+ let id = resolveLaneEntityId(uniforms.overrideParams.x, lane);
47
+ let mask = capacity - 1u;
48
+ var slot = entityColorSlotHash(id) & mask;
49
+ for (var i = 0u; i <= maxProbe && i < capacity; i = i + 1u) {
50
+ let key = entityColorTable[ENTITY_COLOR_HEADER + slot];
51
+ if (key == id) {
52
+ let c = colorBase + slot * 4u;
53
+ return vec4<f32>(
54
+ bitcast<f32>(entityColorTable[c]),
55
+ bitcast<f32>(entityColorTable[c + 1u]),
56
+ bitcast<f32>(entityColorTable[c + 2u]),
57
+ bitcast<f32>(entityColorTable[c + 3u])
58
+ );
59
+ }
60
+ if (key == ENTITY_COLOR_EMPTY) {
61
+ break;
62
+ }
63
+ slot = (slot + 1u) & mask;
64
+ }
65
+ return none;
66
+ }
67
+
68
+ // Composite an override over the fragment's own encoded colour exactly
69
+ // as the retired equal-depth overlay pass blended it (src-alpha over
70
+ // the base draw): the override albedo lit by the same irradiance, no
71
+ // specular, the same roll-off and edge darkening, mixed by its alpha.
72
+ // Emphasized overrides are unlit, faintly faceted and opaque (#1277).
73
+ fn paintEntityOverride(base: vec4<f32>, ov: vec4<f32>, irradiance: vec3<f32>, N: vec3<f32>) -> vec4<f32> {
74
+ let albedo = srgbToLinear(ov.rgb);
75
+ var lit = albedo * irradiance;
76
+ var a = ov.a;
77
+ if ((uniforms.overrideParams.y & OVERRIDE_EMPHASIZE) != 0u) {
78
+ lit = albedo * (0.85 + 0.15 * abs(dot(N, normalize(vec3<f32>(0.3, 1.0, 0.2)))));
79
+ a = 1.0;
80
+ }
81
+ let encoded = linearToSrgb(clamp(neutralCompress(lit), vec3<f32>(0.0), vec3<f32>(1.0)));
82
+ return vec4<f32>(mix(base.rgb, encoded, a), a + (1.0 - a) * base.a);
83
+ }
84
+ `;
85
+ //# sourceMappingURL=entity-color-table.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-color-table.wgsl.js","sourceRoot":"","sources":["../../src/shaders/entity-color-table.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;GASG;AACH,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAE7I,MAAM,CAAC,MAAM,oBAAoB,GAAG;;0CAEM,sBAAsB;2CACrB,yBAAyB;sCAC9B,oBAAoB;0CAChB,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEjE,CAAC"}