@ifc-lite/renderer 6.0.1 → 6.3.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.
- package/README.md +21 -0
- package/dist/ao-pass.d.ts +0 -16
- package/dist/ao-pass.d.ts.map +1 -1
- package/dist/ao-pass.js +2 -0
- package/dist/ao-pass.js.map +1 -1
- package/dist/camera-animation.d.ts +1 -1
- package/dist/camera-animation.d.ts.map +1 -1
- package/dist/camera-animation.js +11 -11
- package/dist/camera-animation.js.map +1 -1
- package/dist/camera-inertia.d.ts +27 -0
- package/dist/camera-inertia.d.ts.map +1 -0
- package/dist/camera-inertia.js +33 -0
- package/dist/camera-inertia.js.map +1 -0
- package/dist/camera.d.ts.map +1 -1
- package/dist/camera.js +3 -0
- package/dist/camera.js.map +1 -1
- package/dist/deviation/deviation-computer.d.ts +5 -1
- package/dist/deviation/deviation-computer.d.ts.map +1 -1
- package/dist/deviation/deviation-computer.js +13 -6
- package/dist/deviation/deviation-computer.js.map +1 -1
- package/dist/deviation/deviation-readback.d.ts +16 -3
- package/dist/deviation/deviation-readback.d.ts.map +1 -1
- package/dist/deviation/deviation-readback.js +46 -36
- package/dist/deviation/deviation-readback.js.map +1 -1
- package/dist/deviation/deviation-statistics-kernel.d.ts +111 -0
- package/dist/deviation/deviation-statistics-kernel.d.ts.map +1 -0
- package/dist/deviation/deviation-statistics-kernel.js +303 -0
- package/dist/deviation/deviation-statistics-kernel.js.map +1 -0
- package/dist/deviation/deviation-statistics.d.ts +100 -0
- package/dist/deviation/deviation-statistics.d.ts.map +1 -0
- package/dist/deviation/deviation-statistics.js +100 -0
- package/dist/deviation/deviation-statistics.js.map +1 -0
- package/dist/device-recovery.d.ts.map +1 -1
- package/dist/device-recovery.js +5 -0
- package/dist/device-recovery.js.map +1 -1
- package/dist/device.d.ts +0 -3
- package/dist/device.d.ts.map +1 -1
- package/dist/device.js +5 -1
- package/dist/device.js.map +1 -1
- package/dist/edge-pass.d.ts +0 -12
- package/dist/edge-pass.d.ts.map +1 -1
- package/dist/edge-pass.js +3 -0
- package/dist/edge-pass.js.map +1 -1
- package/dist/edl-pass.d.ts +0 -21
- package/dist/edl-pass.d.ts.map +1 -1
- package/dist/edl-pass.js +23 -0
- package/dist/edl-pass.js.map +1 -1
- package/dist/frame-timing-gpu.d.ts +11 -15
- package/dist/frame-timing-gpu.d.ts.map +1 -1
- package/dist/frame-timing-gpu.js +57 -26
- package/dist/frame-timing-gpu.js.map +1 -1
- package/dist/gpu-counters.d.ts +30 -0
- package/dist/gpu-counters.d.ts.map +1 -0
- package/dist/gpu-counters.js +84 -0
- package/dist/gpu-counters.js.map +1 -0
- package/dist/gpu-static-upload.d.ts.map +1 -1
- package/dist/gpu-static-upload.js +2 -0
- package/dist/gpu-static-upload.js.map +1 -1
- package/dist/index.d.ts +33 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -59
- package/dist/index.js.map +1 -1
- package/dist/picker-depth-sample.d.ts +9 -0
- package/dist/picker-depth-sample.d.ts.map +1 -0
- package/dist/picker-depth-sample.js +63 -0
- package/dist/picker-depth-sample.js.map +1 -0
- package/dist/picker-readbacks.d.ts +8 -1
- package/dist/picker-readbacks.d.ts.map +1 -1
- package/dist/picker-readbacks.js +18 -1
- package/dist/picker-readbacks.js.map +1 -1
- package/dist/picker.d.ts +2 -0
- package/dist/picker.d.ts.map +1 -1
- package/dist/picker.js +70 -94
- package/dist/picker.js.map +1 -1
- package/dist/picking-manager.d.ts +5 -2
- package/dist/picking-manager.d.ts.map +1 -1
- package/dist/picking-manager.js +25 -8
- package/dist/picking-manager.js.map +1 -1
- package/dist/pipeline.d.ts +8 -0
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +22 -0
- package/dist/pipeline.js.map +1 -1
- package/dist/pointcloud/point-cloud-keyed-chunks.d.ts +23 -0
- package/dist/pointcloud/point-cloud-keyed-chunks.d.ts.map +1 -0
- package/dist/pointcloud/point-cloud-keyed-chunks.js +44 -0
- package/dist/pointcloud/point-cloud-keyed-chunks.js.map +1 -0
- package/dist/pointcloud/point-cloud-node.d.ts +5 -1
- package/dist/pointcloud/point-cloud-node.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-node.js +8 -4
- package/dist/pointcloud/point-cloud-node.js.map +1 -1
- package/dist/pointcloud/point-cloud-placement.d.ts +6 -0
- package/dist/pointcloud/point-cloud-placement.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-placement.js +8 -0
- package/dist/pointcloud/point-cloud-placement.js.map +1 -1
- package/dist/pointcloud/point-cloud-ray-transform.d.ts +17 -8
- package/dist/pointcloud/point-cloud-ray-transform.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-ray-transform.js +17 -13
- package/dist/pointcloud/point-cloud-ray-transform.js.map +1 -1
- package/dist/pointcloud/point-cloud-renderer.d.ts +10 -8
- package/dist/pointcloud/point-cloud-renderer.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-renderer.js +20 -31
- package/dist/pointcloud/point-cloud-renderer.js.map +1 -1
- package/dist/pointcloud/point-cloud-stream-lifecycle.d.ts +8 -1
- package/dist/pointcloud/point-cloud-stream-lifecycle.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-stream-lifecycle.js +17 -2
- package/dist/pointcloud/point-cloud-stream-lifecycle.js.map +1 -1
- package/dist/pointcloud/point-cloud-uniforms.d.ts +11 -0
- package/dist/pointcloud/point-cloud-uniforms.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-uniforms.js +8 -0
- package/dist/pointcloud/point-cloud-uniforms.js.map +1 -1
- package/dist/post-pass-chain.d.ts +2 -0
- package/dist/post-pass-chain.d.ts.map +1 -1
- package/dist/post-pass-chain.js +1 -1
- package/dist/post-pass-chain.js.map +1 -1
- package/dist/raycast-point-cloud-query.d.ts.map +1 -1
- package/dist/raycast-point-cloud-query.js +11 -1
- package/dist/raycast-point-cloud-query.js.map +1 -1
- package/dist/renderer-frame-timing.d.ts +21 -0
- package/dist/renderer-frame-timing.d.ts.map +1 -0
- package/dist/renderer-frame-timing.js +104 -0
- package/dist/renderer-frame-timing.js.map +1 -0
- package/dist/renderer-viewport.d.ts +13 -7
- package/dist/renderer-viewport.d.ts.map +1 -1
- package/dist/renderer-viewport.js +15 -7
- package/dist/renderer-viewport.js.map +1 -1
- package/dist/scene-batch-rebuild.d.ts +7 -0
- package/dist/scene-batch-rebuild.d.ts.map +1 -1
- package/dist/scene-batch-rebuild.js +12 -0
- package/dist/scene-batch-rebuild.js.map +1 -1
- package/dist/scene-contents.d.ts +3 -2
- package/dist/scene-contents.d.ts.map +1 -1
- package/dist/scene-flush.d.ts +43 -0
- package/dist/scene-flush.d.ts.map +1 -0
- package/dist/scene-flush.js +103 -0
- package/dist/scene-flush.js.map +1 -0
- package/dist/scene-geometry.d.ts.map +1 -1
- package/dist/scene-geometry.js +2 -0
- package/dist/scene-geometry.js.map +1 -1
- package/dist/scene.d.ts +10 -27
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +38 -107
- package/dist/scene.js.map +1 -1
- package/dist/selection-mask-pass.d.ts +2 -27
- package/dist/selection-mask-pass.d.ts.map +1 -1
- package/dist/selection-mask-pass.js +44 -39
- package/dist/selection-mask-pass.js.map +1 -1
- package/dist/selection-mask-pipelines.d.ts +3 -3
- package/dist/selection-mask-pipelines.d.ts.map +1 -1
- package/dist/selection-mask-pipelines.js +11 -8
- package/dist/selection-mask-pipelines.js.map +1 -1
- package/dist/shaders/depth-nudge.wgsl.d.ts +67 -0
- package/dist/shaders/depth-nudge.wgsl.d.ts.map +1 -0
- package/dist/shaders/depth-nudge.wgsl.js +130 -0
- package/dist/shaders/depth-nudge.wgsl.js.map +1 -0
- package/dist/shaders/ghost.wgsl.d.ts +2 -0
- package/dist/shaders/ghost.wgsl.d.ts.map +1 -0
- package/dist/shaders/ghost.wgsl.js +46 -0
- package/dist/shaders/ghost.wgsl.js.map +1 -0
- package/dist/shaders/main.wgsl.d.ts +1 -1
- package/dist/shaders/main.wgsl.d.ts.map +1 -1
- package/dist/shaders/main.wgsl.js +6 -4
- package/dist/shaders/main.wgsl.js.map +1 -1
- package/dist/shaders/section-2d-overlay.wgsl.d.ts +1 -16
- package/dist/shaders/section-2d-overlay.wgsl.d.ts.map +1 -1
- package/dist/shaders/section-2d-overlay.wgsl.js +6 -6
- package/dist/shaders/section-2d-overlay.wgsl.js.map +1 -1
- package/dist/shaders/selection-mask.wgsl.d.ts +2 -10
- package/dist/shaders/selection-mask.wgsl.d.ts.map +1 -1
- package/dist/shaders/selection-mask.wgsl.js +9 -42
- package/dist/shaders/selection-mask.wgsl.js.map +1 -1
- package/dist/shaders/symbolic-overlay.wgsl.d.ts +1 -1
- package/dist/shaders/symbolic-overlay.wgsl.d.ts.map +1 -1
- package/dist/shaders/symbolic-overlay.wgsl.js +5 -4
- package/dist/shaders/symbolic-overlay.wgsl.js.map +1 -1
- package/dist/shadow-pass.d.ts +0 -19
- package/dist/shadow-pass.d.ts.map +1 -1
- package/dist/shadow-pass.js +19 -0
- package/dist/shadow-pass.js.map +1 -1
- package/dist/test/frame-timing-device.d.ts +17 -0
- package/dist/test/frame-timing-device.d.ts.map +1 -0
- package/dist/test/frame-timing-device.js +70 -0
- package/dist/test/frame-timing-device.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/xray-alpha.d.ts +8 -0
- package/dist/xray-alpha.d.ts.map +1 -1
- package/dist/xray-alpha.js +23 -0
- package/dist/xray-alpha.js.map +1 -1
- package/package.json +4 -3
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Selection/hover mask pass (#5390): draws the selected and hovered
|
|
3
|
-
* meshes into two small single-sample targets the edge
|
|
4
|
-
* pass then outlines (`edge-pass.ts`'s `fs_outline`, DRY with the geometry
|
|
5
|
-
* edge detection, #5385):
|
|
6
|
-
*
|
|
7
|
-
* - `maskVisible` (rg8unorm): R = selected, G = hovered, both VISIBLE only
|
|
8
|
-
* (occluded fragments discarded — see `shaders/selection-mask.wgsl.ts`).
|
|
9
|
-
* - `maskAll` (r8unorm): R = selected, drawn regardless of occlusion, so
|
|
10
|
-
* the outline composite can tell "hidden behind something" (in `all`,
|
|
11
|
-
* not in `visible`) from "not selected at all".
|
|
12
|
-
*
|
|
13
|
-
* Reuses `mainShaderSource`'s `vs_main` as the vertex stage (same RTE /
|
|
14
|
-
* section-plane / transform math the real highlight draw uses, so the mask
|
|
15
|
-
* lands exactly where the highlighted mesh does) with a trivial constant
|
|
16
|
-
* fragment stage — see that module's header for why the two mix safely.
|
|
17
|
-
*
|
|
18
|
-
* GPU-instanced occurrences (#5745) are drawn by `selection-mask-pipelines.ts`'s
|
|
19
|
-
* instanced variant into the same targets, inside the same render passes,
|
|
20
|
-
* so the outline composite cannot tell which path wrote a pixel.
|
|
21
|
-
*/
|
|
22
1
|
import type { WebGPUDevice } from './device.js';
|
|
23
2
|
import { type InstancedMaskFrame } from './selection-mask-pipelines.js';
|
|
24
3
|
export interface SelectableMesh {
|
|
@@ -43,7 +22,7 @@ export interface SelectionMaskFrame {
|
|
|
43
22
|
encoder: GPUCommandEncoder;
|
|
44
23
|
width: number;
|
|
45
24
|
height: number;
|
|
46
|
-
/**
|
|
25
|
+
/** Full view of the scene depth/stencil attachment (may be multisampled). */
|
|
47
26
|
depthView: GPUTextureView;
|
|
48
27
|
/** Drawn into `maskAll` (selected-all) and `maskVisible.r` (selected-visible). */
|
|
49
28
|
selected: readonly SelectableMesh[];
|
|
@@ -59,14 +38,11 @@ export interface SelectionMaskViews {
|
|
|
59
38
|
export declare class SelectionMaskPass {
|
|
60
39
|
private readonly device;
|
|
61
40
|
private readonly meshBindGroupLayout;
|
|
62
|
-
private readonly
|
|
63
|
-
private readonly multisampled;
|
|
41
|
+
private readonly sampleCount;
|
|
64
42
|
private readonly pipelines;
|
|
65
43
|
/** Built on the first frame with an instanced selection or hover. */
|
|
66
44
|
private instanced;
|
|
67
45
|
private targets;
|
|
68
|
-
private cachedDepthView;
|
|
69
|
-
private cachedDepthBindGroup;
|
|
70
46
|
/** One owned uniform buffer + bind group per hovered piece, grown on demand. */
|
|
71
47
|
private hoverUniforms;
|
|
72
48
|
private destroyed;
|
|
@@ -77,7 +53,6 @@ export declare class SelectionMaskPass {
|
|
|
77
53
|
private ensureInstanced;
|
|
78
54
|
private hoverGroup;
|
|
79
55
|
private ensureTargets;
|
|
80
|
-
private ensureDepthBindGroup;
|
|
81
56
|
private releaseTargets;
|
|
82
57
|
/** Release every GPU resource. Idempotent; the pass is unusable afterwards. */
|
|
83
58
|
destroy(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-mask-pass.d.ts","sourceRoot":"","sources":["../src/selection-mask-pass.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"selection-mask-pass.d.ts","sourceRoot":"","sources":["../src/selection-mask-pass.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAML,KAAK,kBAAkB,EAGxB,MAAM,+BAA+B,CAAC;AAYvC,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,SAAS,CAAC;IACxB,WAAW,EAAE,SAAS,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,YAAY,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,GAAG,CAC1D;IAAE,SAAS,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,GACjD;IAAE,SAAS,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CACpD,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,SAAS,EAAE,cAAc,CAAC;IAC1B,kFAAkF;IAClF,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IACpC,6EAA6E;IAC7E,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IAChC,sGAAsG;IACtG,SAAS,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,cAAc,CAAC;CACzB;AAeD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,qEAAqE;IACrE,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,OAAO,CAA4B;IAC3C,gFAAgF;IAChF,OAAO,CAAC,aAAa,CAAwD;IAC7E,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM;IAgB9F,4FAA4F;IAC5F,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC,GAAG,OAAO;IAI9F,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,kBAAkB;IAgDrD,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,UAAU;IAsBlB,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,cAAc;IAOtB,+EAA+E;IAC/E,OAAO,IAAI,IAAI;CAShB"}
|
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* Selection/hover mask pass (#5390): draws the selected and hovered
|
|
6
|
+
* meshes into two resolved targets the edge
|
|
7
|
+
* pass then outlines (`edge-pass.ts`'s `fs_outline`, DRY with the geometry
|
|
8
|
+
* edge detection, #5385):
|
|
9
|
+
*
|
|
10
|
+
* - `maskVisible` (rg8unorm): R = selected, G = hovered, both VISIBLE only
|
|
11
|
+
* (occluded samples rejected by the shared scene depth attachment).
|
|
12
|
+
* - `maskAll` (r8unorm): R = selected, drawn regardless of occlusion, so
|
|
13
|
+
* the outline composite can tell "hidden behind something" (in `all`,
|
|
14
|
+
* not in `visible`) from "not selected at all".
|
|
15
|
+
*
|
|
16
|
+
* Reuses `mainShaderSource`'s `vs_main` as the vertex stage (same RTE /
|
|
17
|
+
* section-plane / transform math the real highlight draw uses, so the mask
|
|
18
|
+
* lands exactly where the highlighted mesh does) with a trivial constant
|
|
19
|
+
* fragment stage — see that module's header for why the two mix safely.
|
|
20
|
+
*
|
|
21
|
+
* GPU-instanced occurrences (#5745) are drawn by `selection-mask-pipelines.ts`'s
|
|
22
|
+
* instanced variant into the same targets, inside the same render passes,
|
|
23
|
+
* so the outline composite cannot tell which path wrote a pixel.
|
|
24
|
+
*/
|
|
25
|
+
import { renderPassTimestampWrites } from './renderer-frame-timing.js';
|
|
4
26
|
import { mainShaderSource } from './shaders/main.wgsl.js';
|
|
5
|
-
import {
|
|
27
|
+
import { selectionMaskFragmentSource } from './shaders/selection-mask.wgsl.js';
|
|
6
28
|
import { createMaskPipelines, InstancedSelectionMask, isInstancedMaskEmpty, MASK_ALL_FORMAT, MASK_VISIBLE_FORMAT, } from './selection-mask-pipelines.js';
|
|
7
29
|
/** The regular (non-instanced) mesh vertex layout `vs_main` reads. */
|
|
8
30
|
const MESH_VERTEX_BUFFERS = [{
|
|
@@ -16,39 +38,26 @@ const MESH_VERTEX_BUFFERS = [{
|
|
|
16
38
|
export class SelectionMaskPass {
|
|
17
39
|
device;
|
|
18
40
|
meshBindGroupLayout;
|
|
19
|
-
|
|
20
|
-
multisampled;
|
|
41
|
+
sampleCount;
|
|
21
42
|
pipelines;
|
|
22
43
|
/** Built on the first frame with an instanced selection or hover. */
|
|
23
44
|
instanced = null;
|
|
24
45
|
targets = null;
|
|
25
|
-
cachedDepthView = null;
|
|
26
|
-
cachedDepthBindGroup = null;
|
|
27
46
|
/** One owned uniform buffer + bind group per hovered piece, grown on demand. */
|
|
28
47
|
hoverUniforms = [];
|
|
29
48
|
destroyed = false;
|
|
30
49
|
constructor(device, meshBindGroupLayout, sampleCount) {
|
|
31
50
|
this.device = device.getDevice();
|
|
32
51
|
this.meshBindGroupLayout = meshBindGroupLayout;
|
|
33
|
-
this.
|
|
34
|
-
|
|
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;
|
|
52
|
+
this.sampleCount = sampleCount;
|
|
53
|
+
const layout = this.device.createPipelineLayout({ bindGroupLayouts: [this.meshBindGroupLayout] });
|
|
45
54
|
const vertexModule = this.device.createShaderModule({ label: 'selection-mask-vs', code: mainShaderSource });
|
|
46
55
|
const fragmentModule = this.device.createShaderModule({
|
|
47
56
|
label: 'selection-mask-fs',
|
|
48
|
-
code: selectionMaskFragmentSource(
|
|
57
|
+
code: selectionMaskFragmentSource(),
|
|
49
58
|
});
|
|
50
59
|
const vertex = { module: vertexModule, entryPoint: 'vs_main', buffers: MESH_VERTEX_BUFFERS };
|
|
51
|
-
this.pipelines = createMaskPipelines(this.device, 'selection-mask', layout, vertex, fragmentModule);
|
|
60
|
+
this.pipelines = createMaskPipelines(this.device, 'selection-mask', layout, vertex, fragmentModule, sampleCount);
|
|
52
61
|
}
|
|
53
62
|
/** Nothing to draw this frame: caller skips the pass and the outline composite entirely. */
|
|
54
63
|
static isEmpty(frame) {
|
|
@@ -56,7 +65,6 @@ export class SelectionMaskPass {
|
|
|
56
65
|
}
|
|
57
66
|
encode(frame) {
|
|
58
67
|
const targets = this.ensureTargets(frame.width, frame.height);
|
|
59
|
-
const depthGroup = this.ensureDepthBindGroup(frame.depthView);
|
|
60
68
|
const instancedFrame = frame.instanced && !isInstancedMaskEmpty(frame.instanced) ? frame.instanced : null;
|
|
61
69
|
const instanced = instancedFrame ? this.ensureInstanced() : null;
|
|
62
70
|
if (instanced && instancedFrame)
|
|
@@ -68,11 +76,17 @@ export class SelectionMaskPass {
|
|
|
68
76
|
const draw = (view, kind, meshes) => {
|
|
69
77
|
const loadOp = cleared.has(view) ? 'load' : 'clear';
|
|
70
78
|
cleared.add(view);
|
|
79
|
+
const visible = kind !== 'selectedAll';
|
|
71
80
|
const pass = frame.encoder.beginRenderPass({
|
|
72
|
-
|
|
81
|
+
timestampWrites: renderPassTimestampWrites(frame.encoder, `selection-${kind}`),
|
|
82
|
+
colorAttachments: [{
|
|
83
|
+
view: visible ? targets.multisampledVisibleView ?? view : view,
|
|
84
|
+
...(visible && targets.multisampledVisibleView ? { resolveTarget: view } : {}),
|
|
85
|
+
loadOp, storeOp: 'store', clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
86
|
+
}],
|
|
87
|
+
...(visible ? { depthStencilAttachment: { view: frame.depthView, depthReadOnly: true, stencilReadOnly: true } } : {}),
|
|
73
88
|
});
|
|
74
89
|
pass.setPipeline(this.pipelines[kind]);
|
|
75
|
-
pass.setBindGroup(SELECTION_MASK_DEPTH_GROUP, depthGroup);
|
|
76
90
|
for (const mesh of meshes) {
|
|
77
91
|
pass.setBindGroup(0, mesh.bindGroup);
|
|
78
92
|
pass.setVertexBuffer(0, mesh.vertexBuffer);
|
|
@@ -80,7 +94,7 @@ export class SelectionMaskPass {
|
|
|
80
94
|
pass.drawIndexed(mesh.indexCount, 1, 0, 0, 0);
|
|
81
95
|
}
|
|
82
96
|
if (instanced && instancedFrame) {
|
|
83
|
-
instanced.draw(pass, kind,
|
|
97
|
+
instanced.draw(pass, kind, kind === 'hoverVisible' ? instancedFrame.hovered : instancedFrame.selected);
|
|
84
98
|
}
|
|
85
99
|
pass.end();
|
|
86
100
|
};
|
|
@@ -94,7 +108,7 @@ export class SelectionMaskPass {
|
|
|
94
108
|
return targets.views;
|
|
95
109
|
}
|
|
96
110
|
ensureInstanced() {
|
|
97
|
-
this.instanced ??= new InstancedSelectionMask(this.device, this.meshBindGroupLayout, this.
|
|
111
|
+
this.instanced ??= new InstancedSelectionMask(this.device, this.meshBindGroupLayout, this.sampleCount);
|
|
98
112
|
return this.instanced;
|
|
99
113
|
}
|
|
100
114
|
hoverGroup(hovered, slot) {
|
|
@@ -124,32 +138,25 @@ export class SelectionMaskPass {
|
|
|
124
138
|
if (current && current.width === width && current.height === height)
|
|
125
139
|
return current;
|
|
126
140
|
this.releaseTargets();
|
|
127
|
-
const make = (label, format) => this.device.createTexture({
|
|
141
|
+
const make = (label, format, sampleCount = 1) => this.device.createTexture({
|
|
128
142
|
label,
|
|
129
143
|
size: { width, height },
|
|
130
|
-
format,
|
|
144
|
+
format, sampleCount,
|
|
131
145
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
132
146
|
});
|
|
133
147
|
const visible = make('selection-mask-visible', MASK_VISIBLE_FORMAT);
|
|
134
148
|
const all = make('selection-mask-all', MASK_ALL_FORMAT);
|
|
149
|
+
const multisampledVisible = this.sampleCount > 1 ? make('selection-mask-visible-msaa', MASK_VISIBLE_FORMAT, this.sampleCount) : null;
|
|
150
|
+
const multisampledVisibleView = multisampledVisible?.createView() ?? null;
|
|
135
151
|
const visibleView = visible.createView();
|
|
136
152
|
const allView = all.createView();
|
|
137
|
-
this.targets = { width, height, visible, all, visibleView, allView, views: { visibleView, allView } };
|
|
153
|
+
this.targets = { width, height, visible, all, visibleView, allView, multisampledVisible, multisampledVisibleView, views: { visibleView, allView } };
|
|
138
154
|
return this.targets;
|
|
139
155
|
}
|
|
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
156
|
releaseTargets() {
|
|
151
157
|
this.targets?.visible.destroy();
|
|
152
158
|
this.targets?.all.destroy();
|
|
159
|
+
this.targets?.multisampledVisible?.destroy();
|
|
153
160
|
this.targets = null;
|
|
154
161
|
}
|
|
155
162
|
/** Release every GPU resource. Idempotent; the pass is unusable afterwards. */
|
|
@@ -158,8 +165,6 @@ export class SelectionMaskPass {
|
|
|
158
165
|
return;
|
|
159
166
|
this.destroyed = true;
|
|
160
167
|
this.releaseTargets();
|
|
161
|
-
this.cachedDepthBindGroup = null;
|
|
162
|
-
this.cachedDepthView = null;
|
|
163
168
|
for (const entry of this.hoverUniforms)
|
|
164
169
|
entry.buffer.destroy();
|
|
165
170
|
this.hoverUniforms = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-mask-pass.js","sourceRoot":"","sources":["../src/selection-mask-pass.ts"],"names":[],"mappings":"AAAA;;+DAE+D;
|
|
1
|
+
{"version":3,"file":"selection-mask-pass.js","sourceRoot":"","sources":["../src/selection-mask-pass.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ export declare const MASK_ALL_FORMAT: GPUTextureFormat;
|
|
|
6
6
|
export type MaskKind = 'selectedVisible' | 'hoverVisible' | 'selectedAll';
|
|
7
7
|
export type MaskPipelines = Record<MaskKind, GPURenderPipeline>;
|
|
8
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;
|
|
9
|
+
export declare function createMaskPipelines(device: GPUDevice, labelPrefix: string, layout: GPUPipelineLayout, vertex: GPUVertexState, fragmentModule: GPUShaderModule, sampleCount: number): MaskPipelines;
|
|
10
10
|
/** What the instanced mask draws of a template: its geometry and its instance records. */
|
|
11
11
|
export type InstancedMaskTemplate = Pick<InstancedTemplateGPU, 'vertexBuffer' | 'indexBuffer' | 'indexCount' | 'instanceBuffer' | 'instanceCount' | 'canonicalAnchors' | 'rteDeltas'>;
|
|
12
12
|
export interface InstancedMaskFrame {
|
|
@@ -47,11 +47,11 @@ export declare class InstancedSelectionMask {
|
|
|
47
47
|
private readonly hoverScratch;
|
|
48
48
|
/** This frame's drawable runs per template, from `prepare`. */
|
|
49
49
|
private runs;
|
|
50
|
-
constructor(device: GPUDevice, meshBindGroupLayout: GPUBindGroupLayout,
|
|
50
|
+
constructor(device: GPUDevice, meshBindGroupLayout: GPUBindGroupLayout, sampleCount: number);
|
|
51
51
|
/** Upload this frame's uniforms. Call once per frame, before `draw`. */
|
|
52
52
|
prepare(frame: InstancedMaskFrame): void;
|
|
53
53
|
/** Draw `templates` into the open mask pass, one instanced draw per in-envelope run. */
|
|
54
|
-
draw(pass: GPURenderPassEncoder, kind: MaskKind,
|
|
54
|
+
draw(pass: GPURenderPassEncoder, kind: MaskKind, templates: readonly InstancedMaskTemplate[]): void;
|
|
55
55
|
destroy(): void;
|
|
56
56
|
}
|
|
57
57
|
//# sourceMappingURL=selection-mask-pipelines.d.ts.map
|
|
@@ -1 +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,
|
|
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,EAC/B,WAAW,EAAE,MAAM,GAClB,aAAa,CAgBf;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,MAAM;IAiC3F,wEAAwE;IACxE,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAyBxC,wFAAwF;IACxF,IAAI,CAAC,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,qBAAqB,EAAE,GAAG,IAAI;IAcnG,OAAO,IAAI,IAAI;CAMhB"}
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
import { INSTANCED_RTE_DELTA_SLOT, INSTANCED_VERTEX_BUFFERS } from './instanced-vertex-layout.js';
|
|
21
21
|
import { drawInstanceRuns, uploadInstancedRteDeltas } from './instanced-rte.js';
|
|
22
22
|
import { mainShaderSource } from './shaders/main.wgsl.js';
|
|
23
|
-
import {
|
|
23
|
+
import { PIPELINE_CONSTANTS } from './constants.js';
|
|
24
|
+
import { SELECTION_MASK_HOVER_GROUP, selectionMaskFragmentSource, } from './shaders/selection-mask.wgsl.js';
|
|
24
25
|
export const MASK_VISIBLE_FORMAT = 'rg8unorm';
|
|
25
26
|
export const MASK_ALL_FORMAT = 'r8unorm';
|
|
26
27
|
/** Additive blend: two draws to the same target OR their channels together (binary flags, unorm-clamped). */
|
|
@@ -34,7 +35,7 @@ const MASK_OUTPUTS = {
|
|
|
34
35
|
selectedAll: { label: 'selected-all', entryPoint: 'fs_mask_selected_all', format: MASK_ALL_FORMAT },
|
|
35
36
|
};
|
|
36
37
|
/** The three mask pipelines over one vertex stage and one fragment module. */
|
|
37
|
-
export function createMaskPipelines(device, labelPrefix, layout, vertex, fragmentModule) {
|
|
38
|
+
export function createMaskPipelines(device, labelPrefix, layout, vertex, fragmentModule, sampleCount) {
|
|
38
39
|
const make = (kind) => {
|
|
39
40
|
const out = MASK_OUTPUTS[kind];
|
|
40
41
|
return device.createRenderPipeline({
|
|
@@ -43,6 +44,10 @@ export function createMaskPipelines(device, labelPrefix, layout, vertex, fragmen
|
|
|
43
44
|
vertex,
|
|
44
45
|
fragment: { module: fragmentModule, entryPoint: out.entryPoint, targets: [{ format: out.format, blend: ADDITIVE_BLEND }] },
|
|
45
46
|
primitive: { topology: 'triangle-list', cullMode: 'none' },
|
|
47
|
+
...(kind === 'selectedAll' ? {} : {
|
|
48
|
+
depthStencil: { format: PIPELINE_CONSTANTS.DEPTH_FORMAT, depthWriteEnabled: false, depthCompare: 'greater-equal' },
|
|
49
|
+
multisample: { count: sampleCount },
|
|
50
|
+
}),
|
|
46
51
|
});
|
|
47
52
|
};
|
|
48
53
|
return { selectedVisible: make('selectedVisible'), hoverVisible: make('hoverVisible'), selectedAll: make('selectedAll') };
|
|
@@ -67,7 +72,7 @@ export class InstancedSelectionMask {
|
|
|
67
72
|
hoverScratch = new Uint32Array(4);
|
|
68
73
|
/** This frame's drawable runs per template, from `prepare`. */
|
|
69
74
|
runs = new Map();
|
|
70
|
-
constructor(device, meshBindGroupLayout,
|
|
75
|
+
constructor(device, meshBindGroupLayout, sampleCount) {
|
|
71
76
|
this.device = device;
|
|
72
77
|
this.meshBindGroupLayout = meshBindGroupLayout;
|
|
73
78
|
const hoverLayout = device.createBindGroupLayout({
|
|
@@ -76,7 +81,6 @@ export class InstancedSelectionMask {
|
|
|
76
81
|
});
|
|
77
82
|
const groups = [];
|
|
78
83
|
groups[0] = meshBindGroupLayout;
|
|
79
|
-
groups[SELECTION_MASK_DEPTH_GROUP] = depthLayout;
|
|
80
84
|
groups[SELECTION_MASK_HOVER_GROUP] = hoverLayout;
|
|
81
85
|
const layout = device.createPipelineLayout({ label: 'selection-mask-instanced-layout', bindGroupLayouts: groups });
|
|
82
86
|
const vertex = {
|
|
@@ -86,9 +90,9 @@ export class InstancedSelectionMask {
|
|
|
86
90
|
};
|
|
87
91
|
const fragmentModule = device.createShaderModule({
|
|
88
92
|
label: 'selection-mask-instanced-fs',
|
|
89
|
-
code: selectionMaskFragmentSource(
|
|
93
|
+
code: selectionMaskFragmentSource(true),
|
|
90
94
|
});
|
|
91
|
-
this.pipelines = createMaskPipelines(device, 'selection-mask-instanced', layout, vertex, fragmentModule);
|
|
95
|
+
this.pipelines = createMaskPipelines(device, 'selection-mask-instanced', layout, vertex, fragmentModule, sampleCount);
|
|
92
96
|
this.hoverBuffer = device.createBuffer({
|
|
93
97
|
label: 'selection-mask-instanced-hover',
|
|
94
98
|
size: this.hoverScratch.byteLength,
|
|
@@ -125,12 +129,11 @@ export class InstancedSelectionMask {
|
|
|
125
129
|
this.runs = new Map(templates.map((t, i) => [t, runs[i]]));
|
|
126
130
|
}
|
|
127
131
|
/** Draw `templates` into the open mask pass, one instanced draw per in-envelope run. */
|
|
128
|
-
draw(pass, kind,
|
|
132
|
+
draw(pass, kind, templates) {
|
|
129
133
|
if (templates.length === 0 || !this.meshUniform)
|
|
130
134
|
return;
|
|
131
135
|
pass.setPipeline(this.pipelines[kind]);
|
|
132
136
|
pass.setBindGroup(0, this.meshUniform.bindGroup);
|
|
133
|
-
pass.setBindGroup(SELECTION_MASK_DEPTH_GROUP, depthGroup);
|
|
134
137
|
pass.setBindGroup(SELECTION_MASK_HOVER_GROUP, this.hoverBindGroup);
|
|
135
138
|
for (const t of templates) {
|
|
136
139
|
pass.setVertexBuffer(0, t.vertexBuffer);
|
|
@@ -1 +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,
|
|
1
|
+
{"version":3,"file":"selection-mask-pipelines.js","sourceRoot":"","sources":["../src/selection-mask-pipelines.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two reverse-Z depth offsets that order coincident surfaces, and the one
|
|
3
|
+
* place that sizes them per projection.
|
|
4
|
+
*
|
|
5
|
+
* Mesh nudge (`depthNudgeWgsl`). Every vertex entry of the main shader
|
|
6
|
+
* (`vs_main`, `vs_main_quantized`, `vs_instanced`), and so every pass that
|
|
7
|
+
* reuses them (the selection highlight, the `'equal'` overlay, the selection
|
|
8
|
+
* mask), moves a fragment toward the camera by a deterministic per-entity hash
|
|
9
|
+
* (0-255, from the entity lane: see `main.wgsl.ts`), so coplanar faces of
|
|
10
|
+
* different entities resolve the same way every frame. A pass that drew the
|
|
11
|
+
* same mesh with a different nudge would no longer match the depth its batch
|
|
12
|
+
* wrote.
|
|
13
|
+
*
|
|
14
|
+
* Overlay lift (`overlayDepthLiftWgsl`). Annotation lines and text that lie
|
|
15
|
+
* on a model face (#812) are raised above it by a constant NDC offset. It has
|
|
16
|
+
* to beat the largest mesh nudge, or a label disappears under any surface
|
|
17
|
+
* whose hash happens to be high.
|
|
18
|
+
*
|
|
19
|
+
* The two projections map distance to depth differently:
|
|
20
|
+
*
|
|
21
|
+
* - Perspective (reverse-Z, infinite far): clip z is the constant `near` and
|
|
22
|
+
* NDC depth is `near / d`. Scaling clip z by `1 + k` divides the distance by
|
|
23
|
+
* `1 + k`, so the nudge is relative to the fragment's distance: under 3 mm
|
|
24
|
+
* at 10 m for the largest hash. Unchanged by #6729.
|
|
25
|
+
* - Orthographic: NDC depth is linear over the scene's bounding range
|
|
26
|
+
* (`computeOrthoNearFar`). Scaling clip z would shift a fragment by
|
|
27
|
+
* `k * z * range`: on a 1.5 km range about 20 cm mid-scene and nearly 40 cm
|
|
28
|
+
* near the camera, enough to draw a rod in front of the beam it runs through
|
|
29
|
+
* (#6729). So the orthographic nudge is a physical bound instead: no surface
|
|
30
|
+
* moves more than `ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES` toward the camera.
|
|
31
|
+
*
|
|
32
|
+
* The hash is ranked into levels one `ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL`
|
|
33
|
+
* apart. A level has to exceed the depth noise between two triangulations of
|
|
34
|
+
* one plane, or coplanar faces still z-fight, and that noise grows with how
|
|
35
|
+
* obliquely the face is seen. On the tested SwiftShader backend, steep views
|
|
36
|
+
* of overlapping coplanar plates z-fought at one to three 24-bit units per
|
|
37
|
+
* level; eight units, about what the old nudge gave mid-scene, keeps oblique
|
|
38
|
+
* and grazing views of ordinary sites as good as before. Within the metre
|
|
39
|
+
* bound that leaves `bound / (range * level)` levels: all 256 up to about a
|
|
40
|
+
* 205 m depth range, about 52 at 1 km. Past that, coplanar entities a level
|
|
41
|
+
* or two apart can swap at grazing angles, and two on one level are left to
|
|
42
|
+
* draw order. That is the price of keeping hidden surfaces hidden: the old
|
|
43
|
+
* nudge ranked them only because it moved every surface by decimetres.
|
|
44
|
+
*
|
|
45
|
+
* The range comes from the view-projection itself: its z row is the view's
|
|
46
|
+
* unit backward axis scaled by `1 / (far - near)`. Every draw of one frame
|
|
47
|
+
* sees the same matrix, so they all rank alike. The range is the bounding
|
|
48
|
+
* sphere's, so it does not change as the camera orbits.
|
|
49
|
+
*
|
|
50
|
+
* The nudge, and the orthographic overlay lift, only move a vertex that is
|
|
51
|
+
* strictly inside the depth range, and never past the near plane. A vertex beyond either plane, or exactly on the
|
|
52
|
+
* far plane (which the reverse-Z clear to 0 and `'greater'` never write), is
|
|
53
|
+
* left where it is, so nothing changes which side of a clip plane it is on.
|
|
54
|
+
*/
|
|
55
|
+
/** Perspective: relative distance shift per hash step. */
|
|
56
|
+
export declare const PERSPECTIVE_DEPTH_NUDGE_PER_STEP = 0.000001;
|
|
57
|
+
/** Orthographic: NDC depth between adjacent hash levels, eight units of a 24-bit depth buffer. */
|
|
58
|
+
export declare const ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL: number;
|
|
59
|
+
/** Orthographic: the furthest any surface moves toward the camera, in metres. */
|
|
60
|
+
export declare const ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES = 0.025;
|
|
61
|
+
/** Largest mesh hash (`zHash` is masked to 8 bits). */
|
|
62
|
+
export declare const MAX_DEPTH_NUDGE_HASH = 255;
|
|
63
|
+
/** Perspective: NDC lift for annotation lines and text; also the orthographic minimum. */
|
|
64
|
+
export declare const PERSPECTIVE_OVERLAY_DEPTH_LIFT = 0.00005;
|
|
65
|
+
export declare const depthNudgeWgsl = "\n \n const ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL: f32 = 4.76837158203125e-7;\n const ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES: f32 = 0.025;\n const MAX_DEPTH_NUDGE_HASH: f32 = 255.0;\n\n // An orthographic view-projection leaves w at 1: its bottom row is exactly\n // (0, 0, 0, 1), because the projection's and the view's bottom rows are\n // both (0, 0, 0, 1). A perspective one copies the forward axis into that\n // row, a unit vector, so it is never zero. Every caller passes the\n // camera's world view-projection, which each draw packs whether or not\n // it renders camera-relative.\n fn isOrthographicProjection(viewProj: mat4x4<f32>) -> bool {\n return viewProj[0][3] == 0.0 && viewProj[1][3] == 0.0 && viewProj[2][3] == 0.0 && viewProj[3][3] == 1.0;\n }\n\n // Orthographic only: how many hash levels fit the metre bound. The z row\n // of the view-projection has length 1 / (far - near).\n fn orthographicNudgeLevels(viewProj: mat4x4<f32>) -> u32 {\n let depthRange = 1.0 / length(vec3<f32>(viewProj[0][2], viewProj[1][2], viewProj[2][2]));\n let steps = ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES / (depthRange * ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL);\n return u32(clamp(floor(steps), 0.0, MAX_DEPTH_NUDGE_HASH)) + 1u;\n }\n\n // Orthographic only: clip z moved `ndcOffset` toward the camera without\n // changing which side of a clip plane the vertex is on. A vertex beyond\n // either plane, or exactly on the far plane, stays where it is.\n fn orthographicOffsetInsideDepthRange(clip: vec4<f32>, ndcOffset: f32) -> f32 {\n if (!(clip.z > 0.0 && clip.z < clip.w)) { return clip.z; }\n return min(clip.z + ndcOffset * clip.w, clip.w);\n }\n\n const PERSPECTIVE_DEPTH_NUDGE_PER_STEP: f32 = 0.000001;\n\n // Clip-space z with the entity's depth nudge applied (depth-nudge.wgsl.ts).\n fn nudgedClipZ(clip: vec4<f32>, zHash: u32, viewProj: mat4x4<f32>) -> f32 {\n if (isOrthographicProjection(viewProj)) {\n let level = (zHash * orthographicNudgeLevels(viewProj)) >> 8u;\n return orthographicOffsetInsideDepthRange(clip, f32(level) * ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL);\n }\n return clip.z * (1.0 + f32(zHash) * PERSPECTIVE_DEPTH_NUDGE_PER_STEP);\n }\n";
|
|
66
|
+
export declare const overlayDepthLiftWgsl = "\n \n const ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL: f32 = 4.76837158203125e-7;\n const ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES: f32 = 0.025;\n const MAX_DEPTH_NUDGE_HASH: f32 = 255.0;\n\n // An orthographic view-projection leaves w at 1: its bottom row is exactly\n // (0, 0, 0, 1), because the projection's and the view's bottom rows are\n // both (0, 0, 0, 1). A perspective one copies the forward axis into that\n // row, a unit vector, so it is never zero. Every caller passes the\n // camera's world view-projection, which each draw packs whether or not\n // it renders camera-relative.\n fn isOrthographicProjection(viewProj: mat4x4<f32>) -> bool {\n return viewProj[0][3] == 0.0 && viewProj[1][3] == 0.0 && viewProj[2][3] == 0.0 && viewProj[3][3] == 1.0;\n }\n\n // Orthographic only: how many hash levels fit the metre bound. The z row\n // of the view-projection has length 1 / (far - near).\n fn orthographicNudgeLevels(viewProj: mat4x4<f32>) -> u32 {\n let depthRange = 1.0 / length(vec3<f32>(viewProj[0][2], viewProj[1][2], viewProj[2][2]));\n let steps = ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES / (depthRange * ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL);\n return u32(clamp(floor(steps), 0.0, MAX_DEPTH_NUDGE_HASH)) + 1u;\n }\n\n // Orthographic only: clip z moved `ndcOffset` toward the camera without\n // changing which side of a clip plane the vertex is on. A vertex beyond\n // either plane, or exactly on the far plane, stays where it is.\n fn orthographicOffsetInsideDepthRange(clip: vec4<f32>, ndcOffset: f32) -> f32 {\n if (!(clip.z > 0.0 && clip.z < clip.w)) { return clip.z; }\n return min(clip.z + ndcOffset * clip.w, clip.w);\n }\n\n const PERSPECTIVE_OVERLAY_DEPTH_LIFT: f32 = 0.00005;\n\n // Clip-space z raised above any nudged mesh face (depth-nudge.wgsl.ts).\n // A multiple of clip.w is a constant NDC offset after the w-divide, which\n // under reverse-Z reads as \"slightly closer\". Orthographic keeps at least\n // the perspective lift, and two levels above the highest nudge level\n // when that is more (all 256 levels in use), so the text pipeline's\n // constant depthBias of -4 units is covered too.\n fn overlayLiftedClipZ(clip: vec4<f32>, viewProj: mat4x4<f32>) -> f32 {\n if (isOrthographicProjection(viewProj)) {\n let levelsLift = f32(orthographicNudgeLevels(viewProj) + 1u) * ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL;\n return orthographicOffsetInsideDepthRange(clip, max(PERSPECTIVE_OVERLAY_DEPTH_LIFT, levelsLift));\n }\n return clip.z + PERSPECTIVE_OVERLAY_DEPTH_LIFT * clip.w;\n }\n";
|
|
67
|
+
//# sourceMappingURL=depth-nudge.wgsl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"depth-nudge.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/depth-nudge.wgsl.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,0DAA0D;AAC1D,eAAO,MAAM,gCAAgC,WAAO,CAAC;AAErD,kGAAkG;AAClG,eAAO,MAAM,kCAAkC,QAAe,CAAC;AAE/D,iFAAiF;AACjF,eAAO,MAAM,mCAAmC,QAAQ,CAAC;AAEzD,uDAAuD;AACvD,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,0FAA0F;AAC1F,eAAO,MAAM,8BAA8B,UAAO,CAAC;AAkCnD,eAAO,MAAM,cAAc,83EAY1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,0wFAiBhC,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
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 two reverse-Z depth offsets that order coincident surfaces, and the one
|
|
6
|
+
* place that sizes them per projection.
|
|
7
|
+
*
|
|
8
|
+
* Mesh nudge (`depthNudgeWgsl`). Every vertex entry of the main shader
|
|
9
|
+
* (`vs_main`, `vs_main_quantized`, `vs_instanced`), and so every pass that
|
|
10
|
+
* reuses them (the selection highlight, the `'equal'` overlay, the selection
|
|
11
|
+
* mask), moves a fragment toward the camera by a deterministic per-entity hash
|
|
12
|
+
* (0-255, from the entity lane: see `main.wgsl.ts`), so coplanar faces of
|
|
13
|
+
* different entities resolve the same way every frame. A pass that drew the
|
|
14
|
+
* same mesh with a different nudge would no longer match the depth its batch
|
|
15
|
+
* wrote.
|
|
16
|
+
*
|
|
17
|
+
* Overlay lift (`overlayDepthLiftWgsl`). Annotation lines and text that lie
|
|
18
|
+
* on a model face (#812) are raised above it by a constant NDC offset. It has
|
|
19
|
+
* to beat the largest mesh nudge, or a label disappears under any surface
|
|
20
|
+
* whose hash happens to be high.
|
|
21
|
+
*
|
|
22
|
+
* The two projections map distance to depth differently:
|
|
23
|
+
*
|
|
24
|
+
* - Perspective (reverse-Z, infinite far): clip z is the constant `near` and
|
|
25
|
+
* NDC depth is `near / d`. Scaling clip z by `1 + k` divides the distance by
|
|
26
|
+
* `1 + k`, so the nudge is relative to the fragment's distance: under 3 mm
|
|
27
|
+
* at 10 m for the largest hash. Unchanged by #6729.
|
|
28
|
+
* - Orthographic: NDC depth is linear over the scene's bounding range
|
|
29
|
+
* (`computeOrthoNearFar`). Scaling clip z would shift a fragment by
|
|
30
|
+
* `k * z * range`: on a 1.5 km range about 20 cm mid-scene and nearly 40 cm
|
|
31
|
+
* near the camera, enough to draw a rod in front of the beam it runs through
|
|
32
|
+
* (#6729). So the orthographic nudge is a physical bound instead: no surface
|
|
33
|
+
* moves more than `ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES` toward the camera.
|
|
34
|
+
*
|
|
35
|
+
* The hash is ranked into levels one `ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL`
|
|
36
|
+
* apart. A level has to exceed the depth noise between two triangulations of
|
|
37
|
+
* one plane, or coplanar faces still z-fight, and that noise grows with how
|
|
38
|
+
* obliquely the face is seen. On the tested SwiftShader backend, steep views
|
|
39
|
+
* of overlapping coplanar plates z-fought at one to three 24-bit units per
|
|
40
|
+
* level; eight units, about what the old nudge gave mid-scene, keeps oblique
|
|
41
|
+
* and grazing views of ordinary sites as good as before. Within the metre
|
|
42
|
+
* bound that leaves `bound / (range * level)` levels: all 256 up to about a
|
|
43
|
+
* 205 m depth range, about 52 at 1 km. Past that, coplanar entities a level
|
|
44
|
+
* or two apart can swap at grazing angles, and two on one level are left to
|
|
45
|
+
* draw order. That is the price of keeping hidden surfaces hidden: the old
|
|
46
|
+
* nudge ranked them only because it moved every surface by decimetres.
|
|
47
|
+
*
|
|
48
|
+
* The range comes from the view-projection itself: its z row is the view's
|
|
49
|
+
* unit backward axis scaled by `1 / (far - near)`. Every draw of one frame
|
|
50
|
+
* sees the same matrix, so they all rank alike. The range is the bounding
|
|
51
|
+
* sphere's, so it does not change as the camera orbits.
|
|
52
|
+
*
|
|
53
|
+
* The nudge, and the orthographic overlay lift, only move a vertex that is
|
|
54
|
+
* strictly inside the depth range, and never past the near plane. A vertex beyond either plane, or exactly on the
|
|
55
|
+
* far plane (which the reverse-Z clear to 0 and `'greater'` never write), is
|
|
56
|
+
* left where it is, so nothing changes which side of a clip plane it is on.
|
|
57
|
+
*/
|
|
58
|
+
/** Perspective: relative distance shift per hash step. */
|
|
59
|
+
export const PERSPECTIVE_DEPTH_NUDGE_PER_STEP = 1e-6;
|
|
60
|
+
/** Orthographic: NDC depth between adjacent hash levels, eight units of a 24-bit depth buffer. */
|
|
61
|
+
export const ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL = 8 * 2 ** -24;
|
|
62
|
+
/** Orthographic: the furthest any surface moves toward the camera, in metres. */
|
|
63
|
+
export const ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES = 0.025;
|
|
64
|
+
/** Largest mesh hash (`zHash` is masked to 8 bits). */
|
|
65
|
+
export const MAX_DEPTH_NUDGE_HASH = 255;
|
|
66
|
+
/** Perspective: NDC lift for annotation lines and text; also the orthographic minimum. */
|
|
67
|
+
export const PERSPECTIVE_OVERLAY_DEPTH_LIFT = 5e-5;
|
|
68
|
+
const projectionWgsl = `
|
|
69
|
+
const ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL: f32 = ${ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL};
|
|
70
|
+
const ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES: f32 = ${ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES};
|
|
71
|
+
const MAX_DEPTH_NUDGE_HASH: f32 = ${MAX_DEPTH_NUDGE_HASH}.0;
|
|
72
|
+
|
|
73
|
+
// An orthographic view-projection leaves w at 1: its bottom row is exactly
|
|
74
|
+
// (0, 0, 0, 1), because the projection's and the view's bottom rows are
|
|
75
|
+
// both (0, 0, 0, 1). A perspective one copies the forward axis into that
|
|
76
|
+
// row, a unit vector, so it is never zero. Every caller passes the
|
|
77
|
+
// camera's world view-projection, which each draw packs whether or not
|
|
78
|
+
// it renders camera-relative.
|
|
79
|
+
fn isOrthographicProjection(viewProj: mat4x4<f32>) -> bool {
|
|
80
|
+
return viewProj[0][3] == 0.0 && viewProj[1][3] == 0.0 && viewProj[2][3] == 0.0 && viewProj[3][3] == 1.0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Orthographic only: how many hash levels fit the metre bound. The z row
|
|
84
|
+
// of the view-projection has length 1 / (far - near).
|
|
85
|
+
fn orthographicNudgeLevels(viewProj: mat4x4<f32>) -> u32 {
|
|
86
|
+
let depthRange = 1.0 / length(vec3<f32>(viewProj[0][2], viewProj[1][2], viewProj[2][2]));
|
|
87
|
+
let steps = ORTHOGRAPHIC_MAX_DEPTH_NUDGE_METRES / (depthRange * ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL);
|
|
88
|
+
return u32(clamp(floor(steps), 0.0, MAX_DEPTH_NUDGE_HASH)) + 1u;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Orthographic only: clip z moved \`ndcOffset\` toward the camera without
|
|
92
|
+
// changing which side of a clip plane the vertex is on. A vertex beyond
|
|
93
|
+
// either plane, or exactly on the far plane, stays where it is.
|
|
94
|
+
fn orthographicOffsetInsideDepthRange(clip: vec4<f32>, ndcOffset: f32) -> f32 {
|
|
95
|
+
if (!(clip.z > 0.0 && clip.z < clip.w)) { return clip.z; }
|
|
96
|
+
return min(clip.z + ndcOffset * clip.w, clip.w);
|
|
97
|
+
}
|
|
98
|
+
`;
|
|
99
|
+
export const depthNudgeWgsl = `
|
|
100
|
+
${projectionWgsl}
|
|
101
|
+
const PERSPECTIVE_DEPTH_NUDGE_PER_STEP: f32 = ${PERSPECTIVE_DEPTH_NUDGE_PER_STEP};
|
|
102
|
+
|
|
103
|
+
// Clip-space z with the entity's depth nudge applied (depth-nudge.wgsl.ts).
|
|
104
|
+
fn nudgedClipZ(clip: vec4<f32>, zHash: u32, viewProj: mat4x4<f32>) -> f32 {
|
|
105
|
+
if (isOrthographicProjection(viewProj)) {
|
|
106
|
+
let level = (zHash * orthographicNudgeLevels(viewProj)) >> 8u;
|
|
107
|
+
return orthographicOffsetInsideDepthRange(clip, f32(level) * ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL);
|
|
108
|
+
}
|
|
109
|
+
return clip.z * (1.0 + f32(zHash) * PERSPECTIVE_DEPTH_NUDGE_PER_STEP);
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
export const overlayDepthLiftWgsl = `
|
|
113
|
+
${projectionWgsl}
|
|
114
|
+
const PERSPECTIVE_OVERLAY_DEPTH_LIFT: f32 = ${PERSPECTIVE_OVERLAY_DEPTH_LIFT};
|
|
115
|
+
|
|
116
|
+
// Clip-space z raised above any nudged mesh face (depth-nudge.wgsl.ts).
|
|
117
|
+
// A multiple of clip.w is a constant NDC offset after the w-divide, which
|
|
118
|
+
// under reverse-Z reads as "slightly closer". Orthographic keeps at least
|
|
119
|
+
// the perspective lift, and two levels above the highest nudge level
|
|
120
|
+
// when that is more (all 256 levels in use), so the text pipeline's
|
|
121
|
+
// constant depthBias of -4 units is covered too.
|
|
122
|
+
fn overlayLiftedClipZ(clip: vec4<f32>, viewProj: mat4x4<f32>) -> f32 {
|
|
123
|
+
if (isOrthographicProjection(viewProj)) {
|
|
124
|
+
let levelsLift = f32(orthographicNudgeLevels(viewProj) + 1u) * ORTHOGRAPHIC_DEPTH_NUDGE_PER_LEVEL;
|
|
125
|
+
return orthographicOffsetInsideDepthRange(clip, max(PERSPECTIVE_OVERLAY_DEPTH_LIFT, levelsLift));
|
|
126
|
+
}
|
|
127
|
+
return clip.z + PERSPECTIVE_OVERLAY_DEPTH_LIFT * clip.w;
|
|
128
|
+
}
|
|
129
|
+
`;
|
|
130
|
+
//# sourceMappingURL=depth-nudge.wgsl.js.map
|