@ifc-lite/renderer 5.0.0 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/camera-projection.d.ts +2 -0
- package/dist/camera-projection.d.ts.map +1 -1
- package/dist/camera-projection.js +46 -0
- package/dist/camera-projection.js.map +1 -1
- package/dist/chunk-grid.d.ts +21 -0
- package/dist/chunk-grid.d.ts.map +1 -1
- package/dist/chunk-grid.js +25 -7
- package/dist/chunk-grid.js.map +1 -1
- package/dist/clash-solid-pipeline.d.ts.map +1 -1
- package/dist/clash-solid-pipeline.js +4 -2
- package/dist/clash-solid-pipeline.js.map +1 -1
- package/dist/deviation/deviation-computer.d.ts +4 -0
- package/dist/deviation/deviation-computer.d.ts.map +1 -1
- package/dist/deviation/deviation-computer.js +20 -0
- package/dist/deviation/deviation-computer.js.map +1 -1
- package/dist/deviation/deviation-readback.d.ts +18 -0
- package/dist/deviation/deviation-readback.d.ts.map +1 -0
- package/dist/deviation/deviation-readback.js +67 -0
- package/dist/deviation/deviation-readback.js.map +1 -0
- package/dist/edge-pass.d.ts +16 -0
- package/dist/edge-pass.d.ts.map +1 -1
- package/dist/edge-pass.js +75 -1
- package/dist/edge-pass.js.map +1 -1
- package/dist/entity-color-table.d.ts +140 -0
- package/dist/entity-color-table.d.ts.map +1 -0
- package/dist/entity-color-table.js +238 -0
- package/dist/entity-color-table.js.map +1 -0
- package/dist/gpu-upload-guard.d.ts +1 -1
- package/dist/gpu-upload-guard.js +1 -1
- package/dist/hover-mesh-cache.d.ts +29 -0
- package/dist/hover-mesh-cache.d.ts.map +1 -0
- package/dist/hover-mesh-cache.js +31 -0
- package/dist/hover-mesh-cache.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -161
- package/dist/index.js.map +1 -1
- package/dist/individual-mesh-upload.d.ts +24 -0
- package/dist/individual-mesh-upload.d.ts.map +1 -0
- package/dist/individual-mesh-upload.js +85 -0
- package/dist/individual-mesh-upload.js.map +1 -0
- package/dist/instanced-render.d.ts +19 -9
- package/dist/instanced-render.d.ts.map +1 -1
- package/dist/instanced-render.js +36 -24
- package/dist/instanced-render.js.map +1 -1
- package/dist/instanced-rte.d.ts +68 -7
- package/dist/instanced-rte.d.ts.map +1 -1
- package/dist/instanced-rte.js +98 -17
- package/dist/instanced-rte.js.map +1 -1
- package/dist/instanced-vertex-layout.d.ts +26 -0
- package/dist/instanced-vertex-layout.d.ts.map +1 -0
- package/dist/instanced-vertex-layout.js +61 -0
- package/dist/instanced-vertex-layout.js.map +1 -0
- package/dist/mesh-rte-uniforms.d.ts +4 -2
- package/dist/mesh-rte-uniforms.d.ts.map +1 -1
- package/dist/mesh-rte-uniforms.js +4 -2
- package/dist/mesh-rte-uniforms.js.map +1 -1
- package/dist/model-translation.d.ts.map +1 -1
- package/dist/model-translation.js +0 -7
- package/dist/model-translation.js.map +1 -1
- package/dist/outline-params.d.ts +45 -0
- package/dist/outline-params.d.ts.map +1 -0
- package/dist/outline-params.js +54 -0
- package/dist/outline-params.js.map +1 -0
- package/dist/overlay-routing.d.ts +8 -8
- package/dist/overlay-routing.js +2 -2
- package/dist/overlay-routing.js.map +1 -1
- package/dist/overlay-theme.d.ts +9 -3
- package/dist/overlay-theme.d.ts.map +1 -1
- package/dist/overlay-theme.js.map +1 -1
- package/dist/partial-batch-requests.d.ts +2 -2
- package/dist/pick-mesh-budget.d.ts +28 -0
- package/dist/pick-mesh-budget.d.ts.map +1 -0
- package/dist/pick-mesh-budget.js +74 -0
- package/dist/pick-mesh-budget.js.map +1 -0
- package/dist/picker-rte-uniforms.d.ts +7 -1
- package/dist/picker-rte-uniforms.d.ts.map +1 -1
- package/dist/picker-rte-uniforms.js +9 -1
- package/dist/picker-rte-uniforms.js.map +1 -1
- package/dist/picker.d.ts.map +1 -1
- package/dist/picker.js +15 -28
- package/dist/picker.js.map +1 -1
- package/dist/picking-manager.d.ts.map +1 -1
- package/dist/picking-manager.js +4 -47
- package/dist/picking-manager.js.map +1 -1
- package/dist/pipeline.d.ts +7 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +37 -59
- package/dist/pipeline.js.map +1 -1
- package/dist/point-picker.d.ts.map +1 -1
- package/dist/point-picker.js +7 -2
- package/dist/point-picker.js.map +1 -1
- package/dist/pointcloud/point-cloud-node.js +1 -1
- package/dist/pointcloud/point-cloud-node.js.map +1 -1
- package/dist/pointcloud/point-cloud-renderer.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-renderer.js +3 -1
- package/dist/pointcloud/point-cloud-renderer.js.map +1 -1
- package/dist/pointcloud/point-cloud-uniforms.d.ts +5 -1
- package/dist/pointcloud/point-cloud-uniforms.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-uniforms.js +7 -1
- package/dist/pointcloud/point-cloud-uniforms.js.map +1 -1
- package/dist/post-pass-chain.d.ts +14 -1
- package/dist/post-pass-chain.d.ts.map +1 -1
- package/dist/post-pass-chain.js +31 -2
- package/dist/post-pass-chain.js.map +1 -1
- package/dist/raycast-engine.d.ts +5 -1
- package/dist/raycast-engine.d.ts.map +1 -1
- package/dist/raycast-engine.js +20 -8
- package/dist/raycast-engine.js.map +1 -1
- package/dist/raycast-point-cloud-query.d.ts +2 -0
- package/dist/raycast-point-cloud-query.d.ts.map +1 -1
- package/dist/raycast-point-cloud-query.js +7 -0
- package/dist/raycast-point-cloud-query.js.map +1 -1
- package/dist/raycast-source-curve-query.d.ts +13 -0
- package/dist/raycast-source-curve-query.d.ts.map +1 -0
- package/dist/raycast-source-curve-query.js +17 -0
- package/dist/raycast-source-curve-query.js.map +1 -0
- package/dist/reference-image-pipeline.d.ts.map +1 -1
- package/dist/reference-image-pipeline.js +4 -2
- package/dist/reference-image-pipeline.js.map +1 -1
- package/dist/relative-to-eye-abi.d.ts +36 -0
- package/dist/relative-to-eye-abi.d.ts.map +1 -0
- package/dist/relative-to-eye-abi.js +72 -0
- package/dist/relative-to-eye-abi.js.map +1 -0
- package/dist/relative-to-eye.d.ts +15 -35
- package/dist/relative-to-eye.d.ts.map +1 -1
- package/dist/relative-to-eye.js +46 -74
- package/dist/relative-to-eye.js.map +1 -1
- package/dist/render-stats.d.ts +5 -1
- package/dist/render-stats.d.ts.map +1 -1
- package/dist/render-stats.js +1 -1
- package/dist/render-stats.js.map +1 -1
- package/dist/renderer-overlays.d.ts.map +1 -1
- package/dist/renderer-overlays.js +3 -2
- package/dist/renderer-overlays.js.map +1 -1
- package/dist/scene-batch-rebuild.d.ts +1 -2
- package/dist/scene-batch-rebuild.d.ts.map +1 -1
- package/dist/scene-batch-rebuild.js +4 -8
- package/dist/scene-batch-rebuild.js.map +1 -1
- package/dist/scene-batch-upload.d.ts.map +1 -1
- package/dist/scene-batch-upload.js +7 -3
- package/dist/scene-batch-upload.js.map +1 -1
- package/dist/scene-contents.d.ts +1 -1
- package/dist/scene-contents.d.ts.map +1 -1
- package/dist/scene-derived-batches.d.ts +19 -64
- package/dist/scene-derived-batches.d.ts.map +1 -1
- package/dist/scene-derived-batches.js +16 -51
- package/dist/scene-derived-batches.js.map +1 -1
- package/dist/scene-device-recovery.d.ts +3 -3
- package/dist/scene-device-recovery.d.ts.map +1 -1
- package/dist/scene-device-recovery.js +12 -9
- package/dist/scene-device-recovery.js.map +1 -1
- package/dist/scene-geometry.d.ts +6 -6
- package/dist/scene-geometry.d.ts.map +1 -1
- package/dist/scene-geometry.js +8 -9
- package/dist/scene-geometry.js.map +1 -1
- package/dist/scene-instance-bounds.d.ts +1 -1
- package/dist/scene-instance-bounds.d.ts.map +1 -1
- package/dist/scene-instance-bounds.js +4 -16
- package/dist/scene-instance-bounds.js.map +1 -1
- package/dist/scene-instance-materialization.d.ts.map +1 -1
- package/dist/scene-instance-materialization.js +4 -4
- package/dist/scene-instance-materialization.js.map +1 -1
- package/dist/scene-instance-translation.d.ts +6 -10
- package/dist/scene-instance-translation.d.ts.map +1 -1
- package/dist/scene-instance-translation.js +9 -31
- package/dist/scene-instance-translation.js.map +1 -1
- package/dist/scene-instance-types.d.ts +11 -2
- package/dist/scene-instance-types.d.ts.map +1 -1
- package/dist/scene-instance-types.js +7 -1
- package/dist/scene-instance-types.js.map +1 -1
- package/dist/scene-model-translation.d.ts +1 -2
- package/dist/scene-model-translation.d.ts.map +1 -1
- package/dist/scene-model-translation.js +4 -3
- package/dist/scene-model-translation.js.map +1 -1
- package/dist/scene-precision.d.ts +1 -1
- package/dist/scene-precision.d.ts.map +1 -1
- package/dist/scene-precision.js +11 -2
- package/dist/scene-precision.js.map +1 -1
- package/dist/scene.d.ts +43 -38
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +121 -129
- package/dist/scene.js.map +1 -1
- package/dist/section-2d-line-buffer.d.ts +2 -2
- package/dist/section-2d-line-buffer.d.ts.map +1 -1
- package/dist/section-2d-line-buffer.js +10 -11
- package/dist/section-2d-line-buffer.js.map +1 -1
- package/dist/section-2d-overlay.d.ts +6 -4
- package/dist/section-2d-overlay.d.ts.map +1 -1
- package/dist/section-2d-overlay.js +45 -21
- package/dist/section-2d-overlay.js.map +1 -1
- package/dist/section-2d-types.d.ts +1 -1
- package/dist/section-2d-types.d.ts.map +1 -1
- package/dist/section-2d-types.js +1 -1
- package/dist/section-2d-types.js.map +1 -1
- package/dist/section-plane.d.ts.map +1 -1
- package/dist/section-plane.js +3 -1
- package/dist/section-plane.js.map +1 -1
- package/dist/selection-mask-pass.d.ts +85 -0
- package/dist/selection-mask-pass.d.ts.map +1 -0
- package/dist/selection-mask-pass.js +170 -0
- package/dist/selection-mask-pass.js.map +1 -0
- package/dist/selection-mask-pipelines.d.ts +57 -0
- package/dist/selection-mask-pipelines.d.ts.map +1 -0
- package/dist/selection-mask-pipelines.js +150 -0
- package/dist/selection-mask-pipelines.js.map +1 -0
- package/dist/selection-outline-frame.d.ts +47 -0
- package/dist/selection-outline-frame.d.ts.map +1 -0
- package/dist/selection-outline-frame.js +122 -0
- package/dist/selection-outline-frame.js.map +1 -0
- package/dist/shaders/depth-reconstruct.wgsl.d.ts +7 -2
- package/dist/shaders/depth-reconstruct.wgsl.d.ts.map +1 -1
- package/dist/shaders/depth-reconstruct.wgsl.js +8 -3
- package/dist/shaders/depth-reconstruct.wgsl.js.map +1 -1
- package/dist/shaders/edges.wgsl.d.ts +18 -0
- package/dist/shaders/edges.wgsl.d.ts.map +1 -1
- package/dist/shaders/edges.wgsl.js +99 -0
- package/dist/shaders/edges.wgsl.js.map +1 -1
- package/dist/shaders/entity-color-table.wgsl.d.ts +2 -0
- package/dist/shaders/entity-color-table.wgsl.d.ts.map +1 -0
- package/dist/shaders/entity-color-table.wgsl.js +85 -0
- package/dist/shaders/entity-color-table.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 +45 -113
- package/dist/shaders/main.wgsl.js.map +1 -1
- package/dist/shaders/mesh-uniforms.wgsl.d.ts +2 -0
- package/dist/shaders/mesh-uniforms.wgsl.d.ts.map +1 -0
- package/dist/shaders/mesh-uniforms.wgsl.js +53 -0
- package/dist/shaders/mesh-uniforms.wgsl.js.map +1 -0
- package/dist/shaders/section-2d-overlay.wgsl.d.ts +1 -0
- package/dist/shaders/section-2d-overlay.wgsl.d.ts.map +1 -1
- package/dist/shaders/section-2d-overlay.wgsl.js +3 -2
- package/dist/shaders/section-2d-overlay.wgsl.js.map +1 -1
- package/dist/shaders/selection-mask.wgsl.d.ts +16 -0
- package/dist/shaders/selection-mask.wgsl.d.ts.map +1 -0
- package/dist/shaders/selection-mask.wgsl.js +138 -0
- package/dist/shaders/selection-mask.wgsl.js.map +1 -0
- package/dist/shaders/shadow.wgsl.d.ts +1 -1
- package/dist/shaders/shadow.wgsl.d.ts.map +1 -1
- package/dist/shaders/shadow.wgsl.js +3 -3
- package/dist/shadow-occluders.d.ts.map +1 -1
- package/dist/shadow-occluders.js +1 -0
- package/dist/shadow-occluders.js.map +1 -1
- package/dist/shadow-pass.d.ts +0 -1
- package/dist/shadow-pass.d.ts.map +1 -1
- package/dist/shadow-pass.js +26 -32
- package/dist/shadow-pass.js.map +1 -1
- package/dist/shadow-types.d.ts +3 -0
- package/dist/shadow-types.d.ts.map +1 -1
- package/dist/shadow-types.js.map +1 -1
- package/dist/snap-detector.d.ts +5 -0
- package/dist/snap-detector.d.ts.map +1 -1
- package/dist/snap-detector.js.map +1 -1
- package/dist/source-curve-clipping.d.ts +7 -0
- package/dist/source-curve-clipping.d.ts.map +1 -0
- package/dist/source-curve-clipping.js +165 -0
- package/dist/source-curve-clipping.js.map +1 -0
- package/dist/source-curve-snap.d.ts +49 -0
- package/dist/source-curve-snap.d.ts.map +1 -0
- package/dist/source-curve-snap.js +197 -0
- package/dist/source-curve-snap.js.map +1 -0
- package/dist/symbolic-overlay-pipelines.d.ts +1 -1
- package/dist/symbolic-overlay-pipelines.d.ts.map +1 -1
- package/dist/symbolic-overlay-pipelines.js +13 -22
- package/dist/symbolic-overlay-pipelines.js.map +1 -1
- package/dist/symbolic-text-rte.d.ts +16 -0
- package/dist/symbolic-text-rte.d.ts.map +1 -0
- package/dist/symbolic-text-rte.js +37 -0
- package/dist/symbolic-text-rte.js.map +1 -0
- package/dist/textured-vertices.d.ts.map +1 -1
- package/dist/textured-vertices.js +2 -3
- package/dist/textured-vertices.js.map +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/visual-enhancement.d.ts +0 -4
- package/dist/visual-enhancement.d.ts.map +1 -1
- package/dist/visual-enhancement.js +0 -5
- package/dist/visual-enhancement.js.map +1 -1
- package/dist/xray-alpha.d.ts +7 -3
- package/dist/xray-alpha.d.ts.map +1 -1
- package/dist/xray-alpha.js +11 -7
- package/dist/xray-alpha.js.map +1 -1
- package/package.json +4 -4
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
* Main rendering shader for IFC geometry.
|
|
6
6
|
* Features: linear-space lighting of sRGB-authored colours with a GGX
|
|
7
7
|
* specular term (specular.wgsl.ts), section plane clipping, selection
|
|
8
|
-
* highlight, glass, hue-preserving highlight roll-off
|
|
9
|
-
*
|
|
8
|
+
* highlight, glass, hue-preserving highlight roll-off. Edges come from the
|
|
9
|
+
* screen-space edge pass (edge-pass.ts), not from this shader (#5746).
|
|
10
10
|
*/
|
|
11
|
-
import { MESH_FLAG_RTE_DRAWABLE } from '../mesh-rte-uniforms.js';
|
|
12
11
|
import { colorTransferWgsl } from './color-transfer.wgsl.js';
|
|
13
12
|
import { mainRteWgsl, mainShadowWgsl } from './main-rte-shadow.wgsl.js';
|
|
13
|
+
import { meshUniformsWgsl } from './mesh-uniforms.wgsl.js';
|
|
14
14
|
import { relativeToEyeWgsl } from './relative-to-eye.wgsl.js';
|
|
15
15
|
import { specularWgsl } from './specular.wgsl.js';
|
|
16
|
+
import { entityColorTableWgsl } from './entity-color-table.wgsl.js';
|
|
16
17
|
/**
|
|
17
18
|
* Translucent surfaces draw at this fraction of their alpha, so interiors
|
|
18
19
|
* read through windows and X-Ray ghosts stay faint. A viewer choice that
|
|
@@ -37,25 +38,7 @@ const TRANSLUCENT_OPACITY_SCALE = 0.7;
|
|
|
37
38
|
*/
|
|
38
39
|
const IRRADIANCE_CALIBRATION = 1.82;
|
|
39
40
|
export const mainShaderSource = `
|
|
40
|
-
|
|
41
|
-
viewProj: mat4x4<f32>,
|
|
42
|
-
model: mat4x4<f32>,
|
|
43
|
-
baseColor: vec4<f32>,
|
|
44
|
-
metallicRoughness: vec2<f32>, // x = metallic, y = roughness (mesh-material.ts)
|
|
45
|
-
transmission: vec2<f32>, // x = 1: authored translucent, drawn as glass; y = pad
|
|
46
|
-
sectionPlane: vec4<f32>, // xyz = plane normal, w = plane distance
|
|
47
|
-
flags: vec4<u32>, // x = isSelected, y = section/clip bits, z = edgeEnabled, w = edgeIntensityMilli
|
|
48
|
-
clipBoxMin: vec4<f32>, // xyz = clip-box min corner (world), w = pad
|
|
49
|
-
clipBoxMax: vec4<f32>, // xyz = clip-box max corner (world), w = pad
|
|
50
|
-
quantParams: vec4<f32>, // local min xyz, lattice step w
|
|
51
|
-
rteViewProj: mat4x4<f32>, // appended frame; bit 16 selects it
|
|
52
|
-
drawableDeltaHigh: vec4<f32>,
|
|
53
|
-
drawableDeltaLow: vec4<f32>,
|
|
54
|
-
rteCameraHigh: vec4<f32>,
|
|
55
|
-
rteCameraLow: vec4<f32>,
|
|
56
|
-
}
|
|
57
|
-
@binding(0) @group(0) var<uniform> uniforms: Uniforms;
|
|
58
|
-
const RTE_DRAWABLE_FLAG: u32 = ${MESH_FLAG_RTE_DRAWABLE}u;
|
|
41
|
+
${meshUniformsWgsl}
|
|
59
42
|
${relativeToEyeWgsl}
|
|
60
43
|
${mainRteWgsl}
|
|
61
44
|
// Shared group(1) lighting; packing matches packEnvironmentUniforms().
|
|
@@ -83,6 +66,7 @@ export const mainShaderSource = `
|
|
|
83
66
|
const TRANSLUCENT_OPACITY_SCALE: f32 = ${TRANSLUCENT_OPACITY_SCALE};
|
|
84
67
|
${colorTransferWgsl}
|
|
85
68
|
${specularWgsl}
|
|
69
|
+
${entityColorTableWgsl}
|
|
86
70
|
|
|
87
71
|
${mainShadowWgsl}
|
|
88
72
|
|
|
@@ -97,10 +81,9 @@ export const mainShaderSource = `
|
|
|
97
81
|
@location(0) worldPos: vec3<f32>,
|
|
98
82
|
@location(1) normal: vec3<f32>,
|
|
99
83
|
@location(2) @interpolate(flat) entityId: u32,
|
|
100
|
-
@location(3) viewPos: vec3<f32>, // For edge detection
|
|
101
84
|
// Per-draw albedo carried from the vertex stage so the fragment shader
|
|
102
85
|
// is shared by the flat path (vs_main writes uniforms.baseColor — the
|
|
103
|
-
// per-batch
|
|
86
|
+
// per-batch colour) AND the instanced path
|
|
104
87
|
// (vs_instanced writes the per-occurrence colour from the instance
|
|
105
88
|
// buffer). For the flat path this is identical to reading
|
|
106
89
|
// uniforms.baseColor directly (the value is constant across the draw).
|
|
@@ -182,7 +165,6 @@ export const mainShaderSource = `
|
|
|
182
165
|
output.color = uniforms.baseColor;
|
|
183
166
|
output.instSelected = 0u;
|
|
184
167
|
output.eyePos = eyePos;
|
|
185
|
-
output.viewPos = select((uniforms.viewProj * worldPos).xyz, (uniforms.rteViewProj * vec4<f32>(eyePos, 1.0)).xyz, rte);
|
|
186
168
|
return output;
|
|
187
169
|
}
|
|
188
170
|
|
|
@@ -210,12 +192,10 @@ export const mainShaderSource = `
|
|
|
210
192
|
// an 8-bit MATERIAL-COLOUR salt that mergeGeometry/interleaveTextured
|
|
211
193
|
// baked into the HIGH 8 bits of the entityId lane (low 24 = picking id,
|
|
212
194
|
// masked off by encodeId24). Crucially the salt comes from the mesh's
|
|
213
|
-
// OWN colour, NOT the per-draw baseColor uniform — so
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
// the
|
|
217
|
-
// rejecting every fragment. At 1e-6 per step the max world-space offset
|
|
218
|
-
// is <3mm at 10m — invisible.
|
|
195
|
+
// OWN colour, NOT the per-draw baseColor uniform — so every redraw of
|
|
196
|
+
// the same geometry with a different draw colour (the selection
|
|
197
|
+
// highlight's greater-equal pass) computes the SAME nudge as its
|
|
198
|
+
// batch. At 1e-6 per step the max world-space offset is <3mm at 10m.
|
|
219
199
|
let colorSalt = (input.entityId >> 24u) * 2654435761u;
|
|
220
200
|
let zHash = (((input.entityId & 0x00FFFFFFu) ^ colorSalt) * 2654435761u) & 255u;
|
|
221
201
|
output.position.z *= 1.0 + f32(zHash) * 1e-6;
|
|
@@ -225,8 +205,6 @@ export const mainShaderSource = `
|
|
|
225
205
|
output.color = uniforms.baseColor;
|
|
226
206
|
output.instSelected = 0u; // flat path selects via uniforms.flags.x
|
|
227
207
|
output.eyePos = eyePos;
|
|
228
|
-
// Store view-space position for edge detection
|
|
229
|
-
output.viewPos = select((uniforms.viewProj * worldPos).xyz, (uniforms.rteViewProj * vec4<f32>(eyePos, 1.0)).xyz, rte);
|
|
230
208
|
return output;
|
|
231
209
|
}
|
|
232
210
|
|
|
@@ -245,8 +223,8 @@ export const mainShaderSource = `
|
|
|
245
223
|
let eyePos = rteInstancePosition(linearLocal, inst.anchorHigh.xyz, inst.anchorLow.xyz).xyz;
|
|
246
224
|
output.position = uniforms.rteViewProj * vec4<f32>(eyePos, 1.0);
|
|
247
225
|
// Same per-entity depth nudge as vs_main. No colour salt here: the
|
|
248
|
-
// instanced path
|
|
249
|
-
// raw picking id is enough to separate coplanar entities.
|
|
226
|
+
// instanced path never redraws an occurrence with a second draw
|
|
227
|
+
// colour, so the raw picking id is enough to separate coplanar entities.
|
|
250
228
|
let zHash = ((inst.instEntityId & 0x00FFFFFFu) * 2654435761u) & 255u;
|
|
251
229
|
output.position.z *= 1.0 + f32(zHash) * 1e-6;
|
|
252
230
|
output.worldPos = worldPos.xyz;
|
|
@@ -255,7 +233,6 @@ export const mainShaderSource = `
|
|
|
255
233
|
output.color = inst.instColor;
|
|
256
234
|
output.instSelected = inst.instSelected;
|
|
257
235
|
output.eyePos = eyePos;
|
|
258
|
-
output.viewPos = (uniforms.rteViewProj * vec4<f32>(eyePos, 1.0)).xyz;
|
|
259
236
|
return output;
|
|
260
237
|
}
|
|
261
238
|
|
|
@@ -278,7 +255,7 @@ export const mainShaderSource = `
|
|
|
278
255
|
// that frame; otherwise the RTE vertex precision is thrown away at
|
|
279
256
|
// section/crop/derivative ingress. Instanced geometry is not yet
|
|
280
257
|
// anchored, so its worldPos remains the authoritative input.
|
|
281
|
-
let fragmentPos =
|
|
258
|
+
let fragmentPos = clipSpacePos(input.worldPos, input.eyePos);
|
|
282
259
|
// Per-instance hide/isolate: bit 1 of the instance flags lane marks a hidden
|
|
283
260
|
// occurrence. Discard it so it neither draws nor writes depth (and the pick
|
|
284
261
|
// pass applies the same discard, so it isn't pickable). vs_main writes
|
|
@@ -300,27 +277,9 @@ export const mainShaderSource = `
|
|
|
300
277
|
if (!occOpaque) { discard; }
|
|
301
278
|
}
|
|
302
279
|
}
|
|
303
|
-
// Section plane
|
|
304
|
-
//
|
|
305
|
-
|
|
306
|
-
if (sectionEnabled) {
|
|
307
|
-
let planeNormal = uniforms.sectionPlane.xyz;
|
|
308
|
-
let planeDistance = uniforms.sectionPlane.w;
|
|
309
|
-
let flipped = (uniforms.flags.y & 2u) == 2u;
|
|
310
|
-
let side = select(1.0, -1.0, flipped);
|
|
311
|
-
let distToPlane = (dot(fragmentPos, planeNormal) - planeDistance) * side;
|
|
312
|
-
if (distToPlane > 0.0) {
|
|
313
|
-
discard;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
// Clip box (section / crop box): discard fragments OUTSIDE the AABB.
|
|
317
|
-
// flags.y bit 2 = clip-box enabled.
|
|
318
|
-
if ((uniforms.flags.y & 4u) != 0u) {
|
|
319
|
-
let p = fragmentPos;
|
|
320
|
-
if (any(p < uniforms.clipBoxMin.xyz) || any(p > uniforms.clipBoxMax.xyz)) {
|
|
321
|
-
discard;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
280
|
+
// Section plane / clip box (mesh-uniforms.wgsl.ts, shared with the
|
|
281
|
+
// selection mask so an outline is cut where its surface is).
|
|
282
|
+
if (sectionClipped(fragmentPos)) { discard; }
|
|
324
283
|
|
|
325
284
|
// Compute normal via derivative-based flat shading.
|
|
326
285
|
//
|
|
@@ -432,15 +391,9 @@ export const mainShaderSource = `
|
|
|
432
391
|
let irradiance = lightTerm * (env.exposure * IRRADIANCE_CALIBRATION);
|
|
433
392
|
var color = baseColor * irradiance;
|
|
434
393
|
|
|
435
|
-
// flags.x
|
|
436
|
-
//
|
|
437
|
-
//
|
|
438
|
-
// baseColor.a (overlay pipeline has
|
|
439
|
-
// src-alpha blending) AND skip the
|
|
440
|
-
// specular term, so an override
|
|
441
|
-
// paints its colour, lit, and a
|
|
442
|
-
// low-alpha ghost tint does not
|
|
443
|
-
// pick up glass reflections.
|
|
394
|
+
// flags.x bit 0 (value 1) = isSelected → selection highlight, forced opaque.
|
|
395
|
+
// bit 1 (value 2) = isOverlay → legacy overlay pipeline callers;
|
|
396
|
+
// preserve alpha and skip specular for their blended draw.
|
|
444
397
|
// Selected via the per-draw flag (flat path) OR the per-occurrence flag
|
|
445
398
|
// (instanced path — vs_instanced reads it from the instance buffer).
|
|
446
399
|
let isSelected = ((uniforms.flags.x & 1u) == 1u) || ((input.instSelected & 1u) == 1u);
|
|
@@ -480,28 +433,22 @@ export const mainShaderSource = `
|
|
|
480
433
|
color = selectionColor.rgb * shade;
|
|
481
434
|
}
|
|
482
435
|
|
|
483
|
-
//
|
|
484
|
-
//
|
|
485
|
-
// wash-to-white) so the focused clash pair reads as a solid, vivid,
|
|
486
|
-
// distinct colour that pops against the lit model — like a clash tool.
|
|
487
|
-
// A faint normal-based shade keeps the silhouette from going flat. (#1277)
|
|
436
|
+
// Public getOverlayPipeline() callers can still use the emphasized
|
|
437
|
+
// overlay bit even though internal colour overrides now use a table.
|
|
488
438
|
let emphasizedOverlay = isOverlay && (uniforms.flags.x & 32u) != 0u;
|
|
489
439
|
if (emphasizedOverlay) {
|
|
490
440
|
let facet = 0.85 + 0.15 * abs(dot(N, normalize(vec3<f32>(0.3, 1.0, 0.2))));
|
|
491
441
|
color = baseColor * facet;
|
|
492
442
|
}
|
|
493
443
|
|
|
494
|
-
//
|
|
495
|
-
// opaque (the selection pipeline has no alpha blending). Emphasized
|
|
496
|
-
// clash overlay paints a SOLID vivid fill (force opaque) so it isn't
|
|
497
|
-
// blended down to a pale tint against the geometry beneath.
|
|
444
|
+
// Selected objects and emphasized overlays draw fully opaque.
|
|
498
445
|
var finalAlpha = select(input.color.a, 1.0, isSelected || emphasizedOverlay);
|
|
499
446
|
|
|
500
447
|
// Specular (#5386; specular.wgsl.ts), after the diffuse above. Not
|
|
501
|
-
// on the selection highlight (it would wash
|
|
502
|
-
//
|
|
503
|
-
//
|
|
504
|
-
// highlights and
|
|
448
|
+
// on the selection highlight or legacy overlay (it would wash out
|
|
449
|
+
// their colours); a table override is composited without it below. The
|
|
450
|
+
// sun lobe is scaled exactly like the diffuse sun term, and both
|
|
451
|
+
// terms like irradiance, so a preset's highlights and diffuse move together.
|
|
505
452
|
if (!isSelected && !isOverlay) {
|
|
506
453
|
// Glass is an authored translucent material (mesh-material.ts
|
|
507
454
|
// also gives it its smooth roughness). An X-Ray or compare fade
|
|
@@ -511,13 +458,23 @@ export const mainShaderSource = `
|
|
|
511
458
|
let instancedPass = (uniforms.flags.x & 4u) != 0u;
|
|
512
459
|
let translucent = finalAlpha < 0.99;
|
|
513
460
|
let glass = translucent && uniforms.transmission.x > 0.5 && !instancedPass;
|
|
514
|
-
|
|
461
|
+
// #5984: an instanced occurrence's own authored finish rides its
|
|
462
|
+
// flags lane (instanced-render.ts packInstanceFinish); the pass's
|
|
463
|
+
// uniform row is the shared default.
|
|
464
|
+
var metallicRoughness = vec2<f32>(uniforms.metallicRoughness.x, uniforms.metallicRoughness.y);
|
|
465
|
+
if (instancedPass && (input.instSelected & 4u) != 0u) {
|
|
466
|
+
metallicRoughness.x = f32((input.instSelected >> 16u) & 255u) / 255.0;
|
|
467
|
+
}
|
|
468
|
+
if (instancedPass && (input.instSelected & 8u) != 0u) {
|
|
469
|
+
metallicRoughness.y = f32((input.instSelected >> 24u) & 255u) / 255.0;
|
|
470
|
+
}
|
|
471
|
+
let metallic = clamp(metallicRoughness.x, 0.0, 1.0);
|
|
515
472
|
let spec = surfaceSpecular(
|
|
516
473
|
N,
|
|
517
474
|
normalize(-input.eyePos),
|
|
518
475
|
baseColor,
|
|
519
476
|
metallic,
|
|
520
|
-
|
|
477
|
+
metallicRoughness.y,
|
|
521
478
|
env.sunColor * (env.sunIntensity * sunShadow),
|
|
522
479
|
);
|
|
523
480
|
// What the lobe reflects is not there to diffuse; a metal has no
|
|
@@ -552,41 +509,16 @@ export const mainShaderSource = `
|
|
|
552
509
|
// the roll-off threshold.
|
|
553
510
|
color = neutralCompress(color);
|
|
554
511
|
|
|
555
|
-
// Subtle edge enhancement using screen-space derivatives.
|
|
556
|
-
//
|
|
557
|
-
// Use the SHADED normal (face normal from dpdx/dpdy above)
|
|
558
|
-
// for the normal-gradient term, not the interpolated vertex
|
|
559
|
-
// normal — otherwise we get spurious dark stripes on flat
|
|
560
|
-
// surfaces whose vertex normals carry numerical noise from
|
|
561
|
-
// CSG output (the visible scar-line symptom would just
|
|
562
|
-
// resurface here even after the lit-normal fix). With the
|
|
563
|
-
// face normal, coplanar adjacent triangles agree exactly →
|
|
564
|
-
// zero normal gradient → no false edge; only the genuine
|
|
565
|
-
// creases between perpendicular faces produce a real
|
|
566
|
-
// gradient and get the intended outline.
|
|
567
|
-
let depthGradient = length(vec2<f32>(
|
|
568
|
-
dpdx(input.viewPos.z),
|
|
569
|
-
dpdy(input.viewPos.z)
|
|
570
|
-
));
|
|
571
|
-
let normalGradient = length(vec2<f32>(
|
|
572
|
-
length(dpdx(N)),
|
|
573
|
-
length(dpdy(N))
|
|
574
|
-
));
|
|
575
|
-
|
|
576
|
-
if (uniforms.flags.z == 1u) {
|
|
577
|
-
// Threshold filters subtle normal discontinuities at internal
|
|
578
|
-
// triangle edges between coplanar entities in the same batch.
|
|
579
|
-
let edgeFactor = smoothstep(0.02, 0.12, depthGradient * 10.0 + normalGradient * 5.0);
|
|
580
|
-
let edgeIntensity = f32(uniforms.flags.w) / 1000.0;
|
|
581
|
-
let edgeDarkenStrength = clamp(0.25 * edgeIntensity, 0.0, 0.85);
|
|
582
|
-
let edgeDarken = mix(1.0, 1.0 - edgeDarkenStrength, edgeFactor);
|
|
583
|
-
color *= edgeDarken;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
512
|
color = linearToSrgb(clamp(color, vec3<f32>(0.0), vec3<f32>(1.0)));
|
|
587
513
|
|
|
588
514
|
var out: FragmentOutput;
|
|
589
515
|
out.color = vec4<f32>(color, finalAlpha);
|
|
516
|
+
// Colour override from the per-entity table (#6076): only draws the
|
|
517
|
+
// renderer marks (overrideParams.y), i.e. depth-writing opaque ones.
|
|
518
|
+
let entityOverride = entityOverrideColor(input.entityId);
|
|
519
|
+
if (entityOverride.a >= 0.0 && !isSelected) {
|
|
520
|
+
out.color = paintEntityOverride(out.color, entityOverride, irradiance, N);
|
|
521
|
+
}
|
|
590
522
|
out.objectIdEncoded = encodeId24(input.entityId);
|
|
591
523
|
return out;
|
|
592
524
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.wgsl.js","sourceRoot":"","sources":["../../src/shaders/main.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;GAMG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"main.wgsl.js","sourceRoot":"","sources":["../../src/shaders/main.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;GAMG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;;;GAIG;AACH,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAEtC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAEpC,MAAM,CAAC,MAAM,gBAAgB,GAAG;UACtB,gBAAgB;UAChB,iBAAiB;UACjB,WAAW;;;;;;;;;;;;;;;;;;;;;;8CAsByB,sBAAsB;iDACnB,yBAAyB;UAChE,iBAAiB;UACjB,YAAY;UACZ,oBAAoB;;UAEpB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAscjB,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const meshUniformsWgsl = "\n struct Uniforms {\n viewProj: mat4x4<f32>,\n model: mat4x4<f32>,\n baseColor: vec4<f32>,\n metallicRoughness: vec2<f32>, // x = metallic, y = roughness (mesh-material.ts)\n transmission: vec2<f32>, // x = 1: authored translucent, drawn as glass; y = pad\n sectionPlane: vec4<f32>, // xyz = plane normal, w = plane distance\n flags: vec4<u32>, // x = isSelected, y = section/clip bits; z, w unused (0) since #5746 dropped the derivative edges\n clipBoxMin: vec4<f32>, // xyz = clip-box min corner (world), w = pad\n clipBoxMax: vec4<f32>, // xyz = clip-box max corner (world), w = pad\n quantParams: vec4<f32>, // local min xyz, lattice step w\n rteViewProj: mat4x4<f32>, // appended frame; bit 16 selects it\n drawableDeltaHigh: vec4<f32>,\n drawableDeltaLow: vec4<f32>,\n rteCameraHigh: vec4<f32>,\n rteCameraLow: vec4<f32>,\n overrideParams: vec4<u32>, // x = draw's id anchor, y = OVERRIDE_* bits (entity-color-table.ts, #6076)\n }\n @binding(0) @group(0) var<uniform> uniforms: Uniforms;\n const RTE_DRAWABLE_FLAG: u32 = 65536u;\n\n // The fragment position the section/crop tests run in: camera-relative\n // for RTE drawables (the packer writes plane and box in that frame),\n // world space otherwise.\n fn clipSpacePos(worldPos: vec3<f32>, eyePos: vec3<f32>) -> vec3<f32> {\n return select(worldPos, eyePos, (uniforms.flags.x & RTE_DRAWABLE_FLAG) != 0u);\n }\n\n // True when p is cut away: ABOVE the section plane (flags.y bit 0 =\n // enabled, bit 1 = flipped) or OUTSIDE the clip box (bit 2).\n fn sectionClipped(p: vec3<f32>) -> bool {\n if ((uniforms.flags.y & 1u) == 1u) {\n let side = select(1.0, -1.0, (uniforms.flags.y & 2u) == 2u);\n if ((dot(p, uniforms.sectionPlane.xyz) - uniforms.sectionPlane.w) * side > 0.0) { return true; }\n }\n if ((uniforms.flags.y & 4u) != 0u) {\n if (any(p < uniforms.clipBoxMin.xyz) || any(p > uniforms.clipBoxMax.xyz)) { return true; }\n }\n return false;\n }\n";
|
|
2
|
+
//# sourceMappingURL=mesh-uniforms.wgsl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesh-uniforms.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/mesh-uniforms.wgsl.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,gBAAgB,ouEAyC5B,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
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 per-mesh uniform block (`@group(0) @binding(0)`) and the section /
|
|
6
|
+
* clip-box test that reads it, shared by `main.wgsl.ts` and the selection
|
|
7
|
+
* mask fragment stage (#5390) so an outline is cut exactly where the
|
|
8
|
+
* surface it traces is. Packing: `mesh-rte-uniforms.ts` / `index.ts`.
|
|
9
|
+
*/
|
|
10
|
+
import { MESH_FLAG_RTE_DRAWABLE } from '../mesh-rte-uniforms.js';
|
|
11
|
+
export const meshUniformsWgsl = `
|
|
12
|
+
struct Uniforms {
|
|
13
|
+
viewProj: mat4x4<f32>,
|
|
14
|
+
model: mat4x4<f32>,
|
|
15
|
+
baseColor: vec4<f32>,
|
|
16
|
+
metallicRoughness: vec2<f32>, // x = metallic, y = roughness (mesh-material.ts)
|
|
17
|
+
transmission: vec2<f32>, // x = 1: authored translucent, drawn as glass; y = pad
|
|
18
|
+
sectionPlane: vec4<f32>, // xyz = plane normal, w = plane distance
|
|
19
|
+
flags: vec4<u32>, // x = isSelected, y = section/clip bits; z, w unused (0) since #5746 dropped the derivative edges
|
|
20
|
+
clipBoxMin: vec4<f32>, // xyz = clip-box min corner (world), w = pad
|
|
21
|
+
clipBoxMax: vec4<f32>, // xyz = clip-box max corner (world), w = pad
|
|
22
|
+
quantParams: vec4<f32>, // local min xyz, lattice step w
|
|
23
|
+
rteViewProj: mat4x4<f32>, // appended frame; bit 16 selects it
|
|
24
|
+
drawableDeltaHigh: vec4<f32>,
|
|
25
|
+
drawableDeltaLow: vec4<f32>,
|
|
26
|
+
rteCameraHigh: vec4<f32>,
|
|
27
|
+
rteCameraLow: vec4<f32>,
|
|
28
|
+
overrideParams: vec4<u32>, // x = draw's id anchor, y = OVERRIDE_* bits (entity-color-table.ts, #6076)
|
|
29
|
+
}
|
|
30
|
+
@binding(0) @group(0) var<uniform> uniforms: Uniforms;
|
|
31
|
+
const RTE_DRAWABLE_FLAG: u32 = ${MESH_FLAG_RTE_DRAWABLE}u;
|
|
32
|
+
|
|
33
|
+
// The fragment position the section/crop tests run in: camera-relative
|
|
34
|
+
// for RTE drawables (the packer writes plane and box in that frame),
|
|
35
|
+
// world space otherwise.
|
|
36
|
+
fn clipSpacePos(worldPos: vec3<f32>, eyePos: vec3<f32>) -> vec3<f32> {
|
|
37
|
+
return select(worldPos, eyePos, (uniforms.flags.x & RTE_DRAWABLE_FLAG) != 0u);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// True when p is cut away: ABOVE the section plane (flags.y bit 0 =
|
|
41
|
+
// enabled, bit 1 = flipped) or OUTSIDE the clip box (bit 2).
|
|
42
|
+
fn sectionClipped(p: vec3<f32>) -> bool {
|
|
43
|
+
if ((uniforms.flags.y & 1u) == 1u) {
|
|
44
|
+
let side = select(1.0, -1.0, (uniforms.flags.y & 2u) == 2u);
|
|
45
|
+
if ((dot(p, uniforms.sectionPlane.xyz) - uniforms.sectionPlane.w) * side > 0.0) { return true; }
|
|
46
|
+
}
|
|
47
|
+
if ((uniforms.flags.y & 4u) != 0u) {
|
|
48
|
+
if (any(p < uniforms.clipBoxMin.xyz) || any(p > uniforms.clipBoxMax.xyz)) { return true; }
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
//# sourceMappingURL=mesh-uniforms.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesh-uniforms.wgsl.js","sourceRoot":"","sources":["../../src/shaders/mesh-uniforms.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;GAKG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;yCAoBS,sBAAsB;;;;;;;;;;;;;;;;;;;;;CAqB9D,CAAC"}
|
|
@@ -85,6 +85,7 @@ export declare const SECTION_2D_UNIFORM_SLOT_INDEX: {
|
|
|
85
85
|
readonly grid: number;
|
|
86
86
|
readonly dxf: number;
|
|
87
87
|
readonly terrain: number;
|
|
88
|
+
readonly centreline: number;
|
|
88
89
|
readonly clashBox: number;
|
|
89
90
|
};
|
|
90
91
|
/** One cap record plus a partition range for every line family. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section-2d-overlay.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/section-2d-overlay.wgsl.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB;IACnC,+CAA+C;;IAE/C,+CAA+C;;IAE/C,+CAA+C;;IAE/C,gDAAgD;;IAEhD,gFAAgF;;IAEhF,oEAAoE;;IAEpE,mFAAmF;;IAEnF,oEAAoE;;IAEpE,8DAA8D;;;CAGtD,CAAC;AAEX,uEAAuE;AACvE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,6CAA6C;AAC7C,eAAO,MAAM,wBAAwB,QAAgC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD,eAAO,MAAM,6BAA6B;IACxC,6EAA6E
|
|
1
|
+
{"version":3,"file":"section-2d-overlay.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/section-2d-overlay.wgsl.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB;IACnC,+CAA+C;;IAE/C,+CAA+C;;IAE/C,+CAA+C;;IAE/C,gDAAgD;;IAEhD,gFAAgF;;IAEhF,oEAAoE;;IAEpE,mFAAmF;;IAEnF,oEAAoE;;IAEpE,8DAA8D;;;CAGtD,CAAC;AAEX,uEAAuE;AACvE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,6CAA6C;AAC7C,eAAO,MAAM,wBAAwB,QAAgC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD,eAAO,MAAM,6BAA6B;IACxC,6EAA6E;;;;;;;;;CASrE,CAAC;AAEX,mEAAmE;AACnE,eAAO,MAAM,6BAA6B,QAAyC,CAAC;AAEpF;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAIlE;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,k7LA8H9B,CAAC;AAER;;;GAGG;AACH,eAAO,MAAM,4BAA4B,46EAyDlC,CAAC"}
|
|
@@ -88,10 +88,11 @@ export const SECTION_2D_UNIFORM_SLOT_INDEX = {
|
|
|
88
88
|
grid: 1 + SECTION_2D_MAX_LINE_PARTITIONS * 2,
|
|
89
89
|
dxf: 1 + SECTION_2D_MAX_LINE_PARTITIONS * 3,
|
|
90
90
|
terrain: 1 + SECTION_2D_MAX_LINE_PARTITIONS * 4,
|
|
91
|
-
|
|
91
|
+
centreline: 1 + SECTION_2D_MAX_LINE_PARTITIONS * 5,
|
|
92
|
+
clashBox: 1 + SECTION_2D_MAX_LINE_PARTITIONS * 6,
|
|
92
93
|
};
|
|
93
94
|
/** One cap record plus a partition range for every line family. */
|
|
94
|
-
export const SECTION_2D_UNIFORM_SLOT_COUNT = 1 + SECTION_2D_MAX_LINE_PARTITIONS *
|
|
95
|
+
export const SECTION_2D_UNIFORM_SLOT_COUNT = 1 + SECTION_2D_MAX_LINE_PARTITIONS * 7;
|
|
95
96
|
/**
|
|
96
97
|
* Byte stride between uniform slots for `device`.
|
|
97
98
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section-2d-overlay.wgsl.js","sourceRoot":"","sources":["../../src/shaders/section-2d-overlay.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,+CAA+C;IAC/C,QAAQ,EAAE,CAAC;IACX,+CAA+C;IAC/C,WAAW,EAAE,EAAE;IACf,+CAA+C;IAC/C,YAAY,EAAE,EAAE;IAChB,gDAAgD;IAChD,cAAc,EAAE,EAAE;IAClB,gFAAgF;IAChF,MAAM,EAAE,EAAE;IACV,oEAAoE;IACpE,OAAO,EAAE,EAAE;IACX,mFAAmF;IACnF,SAAS,EAAE,EAAE;IACb,oEAAoE;IACpE,WAAW,EAAE,EAAE;IACf,8DAA8D;IAC9D,eAAe,EAAE,EAAE;IACnB,cAAc,EAAE,EAAE;CACV,CAAC;AAEX,uEAAuE;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAE5C,6CAA6C;AAC7C,MAAM,CAAC,MAAM,wBAAwB,GAAG,yBAAyB,GAAG,CAAC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAG,CAAC;AAElD,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,6EAA6E;IAC7E,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,CAAC,GAAG,8BAA8B;IAC7C,IAAI,EAAE,CAAC,GAAG,8BAA8B,GAAG,CAAC;IAC5C,GAAG,EAAE,CAAC,GAAG,8BAA8B,GAAG,CAAC;IAC3C,OAAO,EAAE,CAAC,GAAG,8BAA8B,GAAG,CAAC;IAC/C,QAAQ,EAAE,CAAC,GAAG,8BAA8B,GAAG,CAAC;CACxC,CAAC;AAEX,mEAAmE;AACnE,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,GAAG,8BAA8B,GAAG,CAAC,CAAC;AAEpF;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,+BAA+B,IAAI,GAAG,CAAC;IACxE,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3E,OAAO,IAAI,CAAC,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8H5C,CAAC;AAER;;;GAGG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyDhD,CAAC"}
|
|
1
|
+
{"version":3,"file":"section-2d-overlay.wgsl.js","sourceRoot":"","sources":["../../src/shaders/section-2d-overlay.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,+CAA+C;IAC/C,QAAQ,EAAE,CAAC;IACX,+CAA+C;IAC/C,WAAW,EAAE,EAAE;IACf,+CAA+C;IAC/C,YAAY,EAAE,EAAE;IAChB,gDAAgD;IAChD,cAAc,EAAE,EAAE;IAClB,gFAAgF;IAChF,MAAM,EAAE,EAAE;IACV,oEAAoE;IACpE,OAAO,EAAE,EAAE;IACX,mFAAmF;IACnF,SAAS,EAAE,EAAE;IACb,oEAAoE;IACpE,WAAW,EAAE,EAAE;IACf,8DAA8D;IAC9D,eAAe,EAAE,EAAE;IACnB,cAAc,EAAE,EAAE;CACV,CAAC;AAEX,uEAAuE;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAE5C,6CAA6C;AAC7C,MAAM,CAAC,MAAM,wBAAwB,GAAG,yBAAyB,GAAG,CAAC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAG,CAAC;AAElD,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,6EAA6E;IAC7E,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,CAAC,GAAG,8BAA8B;IAC7C,IAAI,EAAE,CAAC,GAAG,8BAA8B,GAAG,CAAC;IAC5C,GAAG,EAAE,CAAC,GAAG,8BAA8B,GAAG,CAAC;IAC3C,OAAO,EAAE,CAAC,GAAG,8BAA8B,GAAG,CAAC;IAC/C,UAAU,EAAE,CAAC,GAAG,8BAA8B,GAAG,CAAC;IAClD,QAAQ,EAAE,CAAC,GAAG,8BAA8B,GAAG,CAAC;CACxC,CAAC;AAEX,mEAAmE;AACnE,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,GAAG,8BAA8B,GAAG,CAAC,CAAC;AAEpF;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,+BAA+B,IAAI,GAAG,CAAC;IACxE,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3E,OAAO,IAAI,CAAC,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8H5C,CAAC;AAER;;;GAGG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyDhD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bind-group index of the scene depth texture in the mask pipeline layout:
|
|
3
|
+
* group 0 is the mesh uniform that `vs_main` reads, so depth is group 1.
|
|
4
|
+
* `selection-mask-pass.ts` builds its layout from this same constant.
|
|
5
|
+
*/
|
|
6
|
+
export declare const SELECTION_MASK_DEPTH_GROUP = 1;
|
|
7
|
+
/**
|
|
8
|
+
* Bind-group index of the hovered-entity uniform (`vec4<u32>`, x = id) in the
|
|
9
|
+
* INSTANCED mask pipeline layout only (#5745). The non-instanced variant
|
|
10
|
+
* selects its meshes on the CPU and declares no such binding.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SELECTION_MASK_HOVER_GROUP = 2;
|
|
13
|
+
/** Relative depth slack for "the same surface" (reverse-Z: ~0.2 % of the distance). */
|
|
14
|
+
export declare const MASK_DEPTH_REL_TOLERANCE = 0.002;
|
|
15
|
+
export declare function selectionMaskFragmentSource(multisampled: boolean, instanced?: boolean): string;
|
|
16
|
+
//# sourceMappingURL=selection-mask.wgsl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-mask.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/selection-mask.wgsl.ts"],"names":[],"mappings":"AAqDA;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,QAAO,CAAC;AAuB7C,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,OAAO,EAAE,SAAS,UAAQ,GAAG,MAAM,CAmD5F"}
|
|
@@ -0,0 +1,138 @@
|
|
|
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
|
+
* Fragment stage for the selection/hover mask pass (#5390). The vertex
|
|
6
|
+
* stage is `mainShaderSource`'s `vs_main` (recompiled as its own
|
|
7
|
+
* `GPUShaderModule`, reusing the exact same RTE/section-plane/transform
|
|
8
|
+
* math the selection highlight draw already uses) — this module supplies
|
|
9
|
+
* only the fragment side, so the two can be mixed in one pipeline: a
|
|
10
|
+
* fragment entry point with no declared inputs is interface-compatible
|
|
11
|
+
* with any vertex stage, since `@builtin(position)` is always available.
|
|
12
|
+
*
|
|
13
|
+
* Manual depth test instead of a real depth-stencil attachment: comparing
|
|
14
|
+
* `@builtin(position).z` (this fragment's own device depth) against the
|
|
15
|
+
* scene depth texture (`depth-reconstruct.wgsl.ts`'s `loadDepth`, same
|
|
16
|
+
* sample-0 convention as the AO/edge passes) means the mask targets stay
|
|
17
|
+
* single-sample regardless of the scene's MSAA sample count, with no
|
|
18
|
+
* resolve step of their own.
|
|
19
|
+
*
|
|
20
|
+
* Every output first drops fragments the section plane or clip box cuts
|
|
21
|
+
* away (`sectionClipped`, shared with `fs_main`), so an outline never traces
|
|
22
|
+
* geometry the section tool removed. That reads the mesh uniform at group 0
|
|
23
|
+
* and the `worldPos` / `eyePos` varyings `vs_main` already emits.
|
|
24
|
+
*
|
|
25
|
+
* Three outputs, at most one per pipeline:
|
|
26
|
+
* - `fs_mask_selected_visible` / `fs_mask_hover_visible`: pass only where
|
|
27
|
+
* this fragment is at least as close as the stored scene depth
|
|
28
|
+
* (reverse-Z: `>=`), i.e. not occluded. `discard` otherwise, so the
|
|
29
|
+
* additive blend leaves the target at 0 there. The comparison is NOT
|
|
30
|
+
* exact: the stored depth is sample 0 of an MSAA attachment (not the
|
|
31
|
+
* pixel centre) and was usually written by the batch draw, whose
|
|
32
|
+
* positions may be quantized, so the same surface lands a slope-sized
|
|
33
|
+
* step away. `isVisible` therefore allows this fragment's own depth
|
|
34
|
+
* slope (`fwidth`, taken before any branch so it stays in uniform
|
|
35
|
+
* control flow) plus `MASK_DEPTH_REL_TOLERANCE` of its depth; reverse-Z
|
|
36
|
+
* depth is proportional to 1/distance, so that is a relative distance
|
|
37
|
+
* tolerance. A fixed 1e-7 epsilon failed on every pixel of a real
|
|
38
|
+
* WebGPU frame, leaving the visible mask empty.
|
|
39
|
+
* - `fs_mask_selected_all`: always passes (drawn "through occluders").
|
|
40
|
+
*
|
|
41
|
+
* Instanced variant (#5745, `instanced = true`): the vertex stage is
|
|
42
|
+
* `vs_instanced` instead, so one draw covers every occurrence of a template.
|
|
43
|
+
* The same entry points then also keep only the occurrences they are for:
|
|
44
|
+
* selected ones (instance flag bit 0) for the selected outputs, and the one
|
|
45
|
+
* whose entity id is the hovered id (a small uniform at
|
|
46
|
+
* `SELECTION_MASK_HOVER_GROUP`) for the hover output. Hidden occurrences
|
|
47
|
+
* (flag bit 1) are dropped, as `fs_main` drops them. The section/clip cut and
|
|
48
|
+
* the depth test are the same code as the non-instanced variant.
|
|
49
|
+
*/
|
|
50
|
+
import { depthTextureWgsl } from './depth-reconstruct.wgsl.js';
|
|
51
|
+
import { meshUniformsWgsl } from './mesh-uniforms.wgsl.js';
|
|
52
|
+
/**
|
|
53
|
+
* Bind-group index of the scene depth texture in the mask pipeline layout:
|
|
54
|
+
* group 0 is the mesh uniform that `vs_main` reads, so depth is group 1.
|
|
55
|
+
* `selection-mask-pass.ts` builds its layout from this same constant.
|
|
56
|
+
*/
|
|
57
|
+
export const SELECTION_MASK_DEPTH_GROUP = 1;
|
|
58
|
+
/**
|
|
59
|
+
* Bind-group index of the hovered-entity uniform (`vec4<u32>`, x = id) in the
|
|
60
|
+
* INSTANCED mask pipeline layout only (#5745). The non-instanced variant
|
|
61
|
+
* selects its meshes on the CPU and declares no such binding.
|
|
62
|
+
*/
|
|
63
|
+
export const SELECTION_MASK_HOVER_GROUP = 2;
|
|
64
|
+
/** Relative depth slack for "the same surface" (reverse-Z: ~0.2 % of the distance). */
|
|
65
|
+
export const MASK_DEPTH_REL_TOLERANCE = 2e-3;
|
|
66
|
+
/**
|
|
67
|
+
* Which occurrences each output keeps. The non-instanced pass is handed only
|
|
68
|
+
* the meshes it should draw, so every fragment qualifies; the instanced pass
|
|
69
|
+
* draws whole templates and filters per occurrence off the flat varyings
|
|
70
|
+
* `vs_instanced` emits (`VertexOutput.entityId` / `.instSelected`).
|
|
71
|
+
*/
|
|
72
|
+
function occurrenceFilterWgsl(instanced) {
|
|
73
|
+
if (!instanced) {
|
|
74
|
+
return `
|
|
75
|
+
fn isSelectedOccurrence(input: MaskInput) -> bool { return true; }
|
|
76
|
+
fn isHoveredOccurrence(input: MaskInput) -> bool { return true; }`;
|
|
77
|
+
}
|
|
78
|
+
return `
|
|
79
|
+
@group(${SELECTION_MASK_HOVER_GROUP}) @binding(0) var<uniform> maskHover: vec4<u32>;
|
|
80
|
+
// bit 0 = selected, bit 1 = hidden (instanced-vertex-layout.ts).
|
|
81
|
+
fn isSelectedOccurrence(input: MaskInput) -> bool { return (input.instSelected & 3u) == 1u; }
|
|
82
|
+
fn isHoveredOccurrence(input: MaskInput) -> bool {
|
|
83
|
+
return (input.instSelected & 2u) == 0u && input.entityId == maskHover.x;
|
|
84
|
+
}`;
|
|
85
|
+
}
|
|
86
|
+
export function selectionMaskFragmentSource(multisampled, instanced = false) {
|
|
87
|
+
const instanceVaryings = instanced
|
|
88
|
+
? `
|
|
89
|
+
@location(2) @interpolate(flat) entityId: u32,
|
|
90
|
+
@location(5) @interpolate(flat) instSelected: u32,`
|
|
91
|
+
: '';
|
|
92
|
+
return `
|
|
93
|
+
${meshUniformsWgsl}
|
|
94
|
+
${depthTextureWgsl(0, multisampled, SELECTION_MASK_DEPTH_GROUP)}
|
|
95
|
+
|
|
96
|
+
// The subset of the vertex stage's VertexOutput the mask reads (locations match).
|
|
97
|
+
struct MaskInput {
|
|
98
|
+
@builtin(position) fragPos: vec4<f32>,
|
|
99
|
+
@location(0) worldPos: vec3<f32>,
|
|
100
|
+
@location(6) eyePos: vec3<f32>,${instanceVaryings}
|
|
101
|
+
}
|
|
102
|
+
${occurrenceFilterWgsl(instanced)}
|
|
103
|
+
|
|
104
|
+
fn isCut(input: MaskInput) -> bool {
|
|
105
|
+
return sectionClipped(clipSpacePos(input.worldPos, input.eyePos));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const MASK_DEPTH_REL_TOLERANCE: f32 = ${MASK_DEPTH_REL_TOLERANCE};
|
|
109
|
+
|
|
110
|
+
// depthSlope = fwidth(fragPos.z), taken by the caller in uniform control flow.
|
|
111
|
+
fn isVisible(fragPos: vec4<f32>, depthSlope: f32) -> bool {
|
|
112
|
+
let ip = vec2<i32>(fragPos.xy);
|
|
113
|
+
let slack = depthSlope + fragPos.z * MASK_DEPTH_REL_TOLERANCE;
|
|
114
|
+
return fragPos.z >= loadDepth(ip) - slack;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@fragment
|
|
118
|
+
fn fs_mask_selected_visible(input: MaskInput) -> @location(0) vec4<f32> {
|
|
119
|
+
let depthSlope = fwidth(input.fragPos.z);
|
|
120
|
+
if (!isSelectedOccurrence(input) || isCut(input) || !isVisible(input.fragPos, depthSlope)) { discard; }
|
|
121
|
+
return vec4<f32>(1.0, 0.0, 0.0, 0.0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@fragment
|
|
125
|
+
fn fs_mask_hover_visible(input: MaskInput) -> @location(0) vec4<f32> {
|
|
126
|
+
let depthSlope = fwidth(input.fragPos.z);
|
|
127
|
+
if (!isHoveredOccurrence(input) || isCut(input) || !isVisible(input.fragPos, depthSlope)) { discard; }
|
|
128
|
+
return vec4<f32>(0.0, 1.0, 0.0, 0.0);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@fragment
|
|
132
|
+
fn fs_mask_selected_all(input: MaskInput) -> @location(0) vec4<f32> {
|
|
133
|
+
if (!isSelectedOccurrence(input) || isCut(input)) { discard; }
|
|
134
|
+
return vec4<f32>(1.0, 0.0, 0.0, 0.0);
|
|
135
|
+
}
|
|
136
|
+
`;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=selection-mask.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-mask.wgsl.js","sourceRoot":"","sources":["../../src/shaders/selection-mask.wgsl.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C,uFAAuF;AACvF,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,SAAkB;IAC9C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO;;0EAE+D,CAAC;IACzE,CAAC;IACD,OAAO;iBACQ,0BAA0B;;;;;UAKjC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,YAAqB,EAAE,SAAS,GAAG,KAAK;IAClF,MAAM,gBAAgB,GAAG,SAAS;QAChC,CAAC,CAAC;;6DAEuD;QACzD,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;UACC,gBAAgB;UAChB,gBAAgB,CAAC,CAAC,EAAE,YAAY,EAAE,0BAA0B,CAAC;;;;;;2CAM5B,gBAAgB;;UAEjD,oBAAoB,CAAC,SAAS,CAAC;;;;;;gDAMO,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BvE,CAAC;AACF,CAAC"}
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
* the unused `worldPos` output on those pipelines costs an interpolator, not a
|
|
28
28
|
* shader stage.
|
|
29
29
|
*/
|
|
30
|
-
export declare const shadowShaderSource = "\n \nstruct RteFrameUniform {\n // Camera translation is intentionally absent. This projects positions\n // returned by rteWorldPosition, which are already relative to the eye.\n viewProj: mat4x4<f32>,\n}\n\nstruct RteDrawableUniform {\n // CPU computes (drawable origin - camera origin) in f64 and splits it.\n // This data must be refreshed whenever the RTE camera frame changes.\n drawableDeltaHigh: vec4<f32>,\n drawableDeltaLow: vec4<f32>,\n}\n\nfn rteWorldPosition(\n local: vec3<f32>,\n drawable: RteDrawableUniform,\n) -> vec4<f32> {\n // Do not subtract a camera origin here: this delta was formed in CPU f64.\n let highDelta = drawable.drawableDeltaHigh.xyz;\n let lowDelta = drawable.drawableDeltaLow.xyz;\n // A drawable template can span kilometres. Keep local with high first;\n // The local-plus-(high-plus-low) association is not equivalent in f32.\n return vec4<f32>((local + highDelta) + lowDelta, 1.0);\n}\n\n struct Light {\n lightViewProj: mat4x4<f32>,\n cameraHigh: vec4<f32>,\n cameraLow: vec4<f32>,\n }\n @binding(0) @group(0) var<uniform> light: Light;\n\n struct Draw {\n model: mat4x4<f32>,\n // xyz = lattice-aligned quantMin (batch-origin-relative), w = step.\n // Read only by vs_shadow_quantized; zero for the other paths.\n quantParams: vec4<f32>,\n originHigh: vec4<f32>,\n originLow: vec4<f32>,\n }\n @binding(1) @group(0) var<uniform> draw: Draw;\n\n struct Clip {\n // xyz = plane normal, w = plane distance (world space).\n sectionPlane: vec4<f32>,\n clipBoxMin: vec4<f32>,\n clipBoxMax: vec4<f32>,\n // x packs: bit 0 = section enabled, bit 1 = section flipped,\n // bit 2 = clip box enabled. Mirrors main.wgsl's flags.y.\n flags: vec4<u32>,\n }\n @binding(2) @group(0) var<uniform> clip: Clip;\n\n struct FlatIn {\n @location(0) position: vec3<f32>,\n }\n\n struct QuantIn {\n @location(0) q: vec4<u32>, // uint16x4: lattice x, y, z, packedOct\n }\n\n struct InstanceIn {\n @location(3) m0: vec4<f32>,\n @location(4) m1: vec4<f32>,\n @location(5) m2: vec4<f32>,\n @location(6) m3: vec4<f32>,\n // Per-occurrence flags lane (bit 1 = hidden), same instance buffer the\n // colour pass reads. Locations 7 (entityId) and 8 (rgba) are
|
|
30
|
+
export declare const shadowShaderSource = "\n \nstruct RteFrameUniform {\n // Camera translation is intentionally absent. This projects positions\n // returned by rteWorldPosition, which are already relative to the eye.\n viewProj: mat4x4<f32>,\n}\n\nstruct RteDrawableUniform {\n // CPU computes (drawable origin - camera origin) in f64 and splits it.\n // This data must be refreshed whenever the RTE camera frame changes.\n drawableDeltaHigh: vec4<f32>,\n drawableDeltaLow: vec4<f32>,\n}\n\nfn rteWorldPosition(\n local: vec3<f32>,\n drawable: RteDrawableUniform,\n) -> vec4<f32> {\n // Do not subtract a camera origin here: this delta was formed in CPU f64.\n let highDelta = drawable.drawableDeltaHigh.xyz;\n let lowDelta = drawable.drawableDeltaLow.xyz;\n // A drawable template can span kilometres. Keep local with high first;\n // The local-plus-(high-plus-low) association is not equivalent in f32.\n return vec4<f32>((local + highDelta) + lowDelta, 1.0);\n}\n\n struct Light {\n lightViewProj: mat4x4<f32>,\n cameraHigh: vec4<f32>,\n cameraLow: vec4<f32>,\n }\n @binding(0) @group(0) var<uniform> light: Light;\n\n struct Draw {\n model: mat4x4<f32>,\n // xyz = lattice-aligned quantMin (batch-origin-relative), w = step.\n // Read only by vs_shadow_quantized; zero for the other paths.\n quantParams: vec4<f32>,\n originHigh: vec4<f32>,\n originLow: vec4<f32>,\n }\n @binding(1) @group(0) var<uniform> draw: Draw;\n\n struct Clip {\n // xyz = plane normal, w = plane distance (world space).\n sectionPlane: vec4<f32>,\n clipBoxMin: vec4<f32>,\n clipBoxMax: vec4<f32>,\n // x packs: bit 0 = section enabled, bit 1 = section flipped,\n // bit 2 = clip box enabled. Mirrors main.wgsl's flags.y.\n flags: vec4<u32>,\n }\n @binding(2) @group(0) var<uniform> clip: Clip;\n\n struct FlatIn {\n @location(0) position: vec3<f32>,\n }\n\n struct QuantIn {\n @location(0) q: vec4<u32>, // uint16x4: lattice x, y, z, packedOct\n }\n\n struct InstanceIn {\n @location(3) m0: vec4<f32>,\n @location(4) m1: vec4<f32>,\n @location(5) m2: vec4<f32>,\n @location(6) m3: vec4<f32>,\n // Per-occurrence flags lane (bit 1 = hidden), same instance buffer the\n // colour pass reads. Locations 7 (entityId) and 8 (rgba) are in the\n // shared layout but unused by the depth pass.\n @location(9) flags: u32,\n // Split drawable-minus-camera delta from the slot-2 delta stream.\n @location(10) anchorHigh: vec4<f32>,\n @location(11) anchorLow: vec4<f32>,\n }\n\n struct ShadowOut {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPos: vec3<f32>,\n }\n\n fn emit(eyePos: vec4<f32>) -> ShadowOut {\n var out: ShadowOut;\n out.position = light.lightViewProj * eyePos;\n out.worldPos = eyePos.xyz;\n return out;\n }\n\n @vertex\n fn vs_shadow_flat(input: FlatIn) -> ShadowOut {\n let linear = (draw.model * vec4<f32>(input.position, 0.0)).xyz;\n return emit(rteWorldPosition(linear, RteDrawableUniform(draw.originHigh, draw.originLow)));\n }\n\n @vertex\n fn vs_shadow_quantized(input: QuantIn) -> ShadowOut {\n let p = draw.quantParams.xyz\n + vec3<f32>(f32(input.q.x), f32(input.q.y), f32(input.q.z)) * draw.quantParams.w;\n let linear = (draw.model * vec4<f32>(p, 0.0)).xyz;\n return emit(rteWorldPosition(linear, RteDrawableUniform(draw.originHigh, draw.originLow)));\n }\n\n @vertex\n fn vs_shadow_instanced(input: FlatIn, inst: InstanceIn) -> ShadowOut {\n // A hidden / isolation-excluded occurrence (flags bit 1) must not cast:\n // the colour pass discards it in fs_main, so collapse it to a zero-area\n // triangle here (every vertex to one clip point) \u2014 the rasterizer drops\n // it and it writes no depth. Mirrors main.wgsl's instSelected & 2u check.\n if ((inst.flags & 2u) != 0u) {\n var out: ShadowOut;\n out.position = vec4<f32>(0.0, 0.0, 0.0, 1.0);\n out.worldPos = vec3<f32>(0.0, 0.0, 0.0);\n return out;\n }\n let instMat = mat4x4<f32>(inst.m0, inst.m1, inst.m2, inst.m3);\n // Keep the local placement from the V1 matrix and add the shared\n // CPU-packed drawable-minus-camera delta. The light projection uses\n // the same RTE frame as the colour and picker submissions.\n let linear = (instMat * vec4<f32>(input.position, 0.0)).xyz;\n return emit(rteWorldPosition(linear, RteDrawableUniform(\n inst.anchorHigh, inst.anchorLow,\n )));\n }\n\n @vertex\n fn vs_shadow_textured(input: FlatIn) -> ShadowOut {\n let linear = (draw.model * vec4<f32>(input.position, 0.0)).xyz;\n return emit(rteWorldPosition(linear, RteDrawableUniform(draw.originHigh, draw.originLow)));\n }\n\n // Clipped variant: discard before the depth write, so a clipped-away\n // occluder leaves the shadow map untouched. Kept byte-for-byte in step\n // with the fs_main section/clip-box branches.\n @fragment\n fn fs_shadow_clip(@location(0) worldPos: vec3<f32>) {\n if ((clip.flags.x & 1u) == 1u) {\n let side = select(1.0, -1.0, (clip.flags.x & 2u) == 2u);\n let distToPlane = (dot(worldPos, clip.sectionPlane.xyz) - clip.sectionPlane.w) * side;\n if (distToPlane > 0.0) {\n discard;\n }\n }\n if ((clip.flags.x & 4u) != 0u) {\n if (any(worldPos < clip.clipBoxMin.xyz) || any(worldPos > clip.clipBoxMax.xyz)) {\n discard;\n }\n }\n }\n";
|
|
31
31
|
//# sourceMappingURL=shadow.wgsl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/shadow.wgsl.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"shadow.wgsl.d.ts","sourceRoot":"","sources":["../../src/shaders/shadow.wgsl.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,kBAAkB,w7LA4H9B,CAAC"}
|
|
@@ -75,10 +75,10 @@ export const shadowShaderSource = `
|
|
|
75
75
|
@location(5) m2: vec4<f32>,
|
|
76
76
|
@location(6) m3: vec4<f32>,
|
|
77
77
|
// Per-occurrence flags lane (bit 1 = hidden), same instance buffer the
|
|
78
|
-
// colour pass reads. Locations 7 (entityId) and 8 (rgba) are
|
|
79
|
-
// the depth pass
|
|
78
|
+
// colour pass reads. Locations 7 (entityId) and 8 (rgba) are in the
|
|
79
|
+
// shared layout but unused by the depth pass.
|
|
80
80
|
@location(9) flags: u32,
|
|
81
|
-
//
|
|
81
|
+
// Split drawable-minus-camera delta from the slot-2 delta stream.
|
|
82
82
|
@location(10) anchorHigh: vec4<f32>,
|
|
83
83
|
@location(11) anchorLow: vec4<f32>,
|
|
84
84
|
}
|