@ifc-lite/renderer 6.0.1 → 6.3.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/README.md +23 -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-controls.d.ts +0 -21
- package/dist/camera-controls.d.ts.map +1 -1
- package/dist/camera-controls.js +8 -90
- package/dist/camera-controls.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-surface-zoom.d.ts +1 -1
- package/dist/camera-zoom.d.ts +55 -0
- package/dist/camera-zoom.d.ts.map +1 -0
- package/dist/camera-zoom.js +138 -0
- package/dist/camera-zoom.js.map +1 -0
- package/dist/camera.d.ts.map +1 -1
- package/dist/camera.js +8 -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 +71 -60
- package/dist/index.js.map +1 -1
- package/dist/pick-rte-snapshot.d.ts +4 -0
- package/dist/pick-rte-snapshot.d.ts.map +1 -1
- package/dist/pick-rte-snapshot.js +10 -0
- package/dist/pick-rte-snapshot.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 +10 -1
- package/dist/picker-readbacks.d.ts.map +1 -1
- package/dist/picker-readbacks.js +30 -1
- package/dist/picker-readbacks.js.map +1 -1
- package/dist/picker.d.ts +4 -4
- package/dist/picker.d.ts.map +1 -1
- package/dist/picker.js +77 -102
- 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 +32 -11
- 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/relative-to-eye.d.ts +3 -0
- package/dist/relative-to-eye.d.ts.map +1 -1
- package/dist/relative-to-eye.js +4 -1
- package/dist/relative-to-eye.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 +26 -27
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +66 -109
- 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 +3 -2
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export { appearanceSourceTriangle, expandAppearanceCorners, equivalentAppearance
|
|
|
11
11
|
export { sameCompanionParts } from './appearance-companions.js';
|
|
12
12
|
export { invertAppearancePartition, validateAppearancePartition } from './appearance-preview.js';
|
|
13
13
|
import { createReferenceImageManager } from './reference-image-host.js';
|
|
14
|
-
import { measureDrawingBuffer, resizeRendererViewport } from './renderer-viewport.js';
|
|
14
|
+
import { MAX_DRAWING_BUFFER_PIXEL_RATIO, measureDrawingBuffer, resizeRendererViewport } from './renderer-viewport.js';
|
|
15
15
|
export { pickFitPolicy } from './camera-fit-policy.js';
|
|
16
16
|
// `Scene` is NOT exported: an exported class republishes every method `SceneContents` above just froze.
|
|
17
17
|
export { Picker } from './picker.js';
|
|
@@ -59,11 +59,6 @@ export { isEntityVisible } from './entity-visibility.js';
|
|
|
59
59
|
// through its own glTF pipeline rather than this one (#2591).
|
|
60
60
|
export { DEFAULT_GHOST_ALPHA, OPAQUE_ALPHA_CUTOFF } from './overlay-routing.js';
|
|
61
61
|
export { VisibilityEpochTracker } from './visibility-epoch.js';
|
|
62
|
-
// Frame/pass GPU timing (issue #2670 perf-verdict gate). Opt-in and NOT wired
|
|
63
|
-
// into `Renderer` by default — a caller constructs `GpuFrameTimingRecorder`
|
|
64
|
-
// itself and attaches its `timestampWrites` to the passes it wants measured;
|
|
65
|
-
// see `frame-timing-gpu.ts`'s module doc for the usage pattern, and
|
|
66
|
-
// `decideTimingMode` for choosing GPU queries vs. the CPU fallback vs. off.
|
|
67
62
|
export { decideTimingMode, passDurationsMs, frameTotalMs, aggregateFrameTimings } from './frame-timing.js';
|
|
68
63
|
export { computeDurationStats, nsToMs, isNegativeDelta } from './frame-timing-stats.js';
|
|
69
64
|
export { GpuFrameTimingRecorder, hasTimestampQueryFeature } from './frame-timing-gpu.js';
|
|
@@ -74,6 +69,7 @@ export { PointPicker, decodePickSample } from './point-picker.js';
|
|
|
74
69
|
export { PointCloudRenderer } from './pointcloud/point-cloud-renderer.js';
|
|
75
70
|
export { PointRenderPipeline } from './pointcloud/point-pipeline.js';
|
|
76
71
|
import { modelPlacementBounds, sceneMeshBounds } from './model-placement-bounds.js';
|
|
72
|
+
import { configureRendererGpuTiming, readRendererGpuTiming, releaseRendererGpuTiming, beginRendererGpuTiming, renderPassTimestampWrites, submitRendererGpuTiming } from './renderer-frame-timing.js';
|
|
77
73
|
import { WebGPUDevice } from './device.js';
|
|
78
74
|
import { RenderPipeline } from './pipeline.js';
|
|
79
75
|
import { Camera } from './camera.js';
|
|
@@ -117,8 +113,9 @@ import { XRayAlpha, XRayEpochTracker } from './xray-alpha.js';
|
|
|
117
113
|
import { PartialBatchRequests } from './partial-batch-requests.js';
|
|
118
114
|
import { uploadIndividualMesh } from './individual-mesh-upload.js';
|
|
119
115
|
import { PointCloudRenderer } from './pointcloud/point-cloud-renderer.js';
|
|
120
|
-
import { appendPointCloudChunk as appendPointCloudChunkImpl, beginPointCloudStream as beginPointCloudStreamImpl, endPointCloudStream as endPointCloudStreamImpl, removePointCloudAsset as removePointCloudAssetImpl, } from './pointcloud/point-cloud-stream-lifecycle.js';
|
|
116
|
+
import { appendPointCloudChunk as appendPointCloudChunkImpl, beginPointCloudStream as beginPointCloudStreamImpl, endPointCloudStream as endPointCloudStreamImpl, removePointCloudAsset as removePointCloudAssetImpl, removePointCloudChunk as removePointCloudChunkImpl, } from './pointcloud/point-cloud-stream-lifecycle.js';
|
|
121
117
|
import { DeviationComputer } from './deviation/deviation-computer.js';
|
|
118
|
+
export { computeDeviationStatistics, computeDeviationStatisticsAsync, countWithinToleranceAsync, deviationHistogramAsync, summarizeDeviationAssetsAsync } from './deviation/deviation-statistics.js';
|
|
122
119
|
import { runGuardedGpuUpload, isDeviceLossThrow } from './gpu-upload-guard.js';
|
|
123
120
|
import { recoverRendererDevice, rendererDeviceLostError } from './device-recovery.js';
|
|
124
121
|
/**
|
|
@@ -172,6 +169,7 @@ export class Renderer {
|
|
|
172
169
|
hoverMeshes = new HoverMeshCache();
|
|
173
170
|
/** Device px per CSS px in the drawing buffer; CSS-px sizes scale by it (#5383). */
|
|
174
171
|
pixelRatio = 1;
|
|
172
|
+
maxPixelRatio = MAX_DRAWING_BUFFER_PIXEL_RATIO;
|
|
175
173
|
interactionEffects = new InteractionEffectsGovernor();
|
|
176
174
|
// Procedural sky background — created lazily on the first frame that
|
|
177
175
|
// enables it (most sessions never do).
|
|
@@ -510,7 +508,7 @@ export class Renderer {
|
|
|
510
508
|
// are clamped to the GPU's max 2D texture dimension so the initial
|
|
511
509
|
// pipeline allocations can't overflow on tall/wide layouts.
|
|
512
510
|
const maxDim = this.device.getMaxTextureDimension();
|
|
513
|
-
const measured = measureDrawingBuffer(this.canvas, maxDim);
|
|
511
|
+
const measured = measureDrawingBuffer(this.canvas, maxDim, this.maxPixelRatio);
|
|
514
512
|
this.pixelRatio = measured?.pixelRatio ?? 1;
|
|
515
513
|
const width = Math.max(1, Math.min(measured?.width ?? this.canvas.width, maxDim));
|
|
516
514
|
const height = Math.max(1, Math.min(measured?.height ?? this.canvas.height, maxDim));
|
|
@@ -718,14 +716,14 @@ export class Renderer {
|
|
|
718
716
|
this.deviceLossSequence++;
|
|
719
717
|
this.deviceLost = true;
|
|
720
718
|
cancelRendererColorFrame(this);
|
|
719
|
+
releaseRendererGpuTiming(this);
|
|
721
720
|
this.recovery.lostReferenceImages = this.referenceImages.hasImages();
|
|
722
721
|
this.referenceImages.destroy();
|
|
723
722
|
this.deviceLostGeneration = this.initGeneration;
|
|
724
723
|
this.deviceLostInfo = info;
|
|
725
724
|
console.warn('[Renderer] GPU device lost — halting rendering until re-init:', info.message);
|
|
726
|
-
// Readiness describes
|
|
727
|
-
// `
|
|
728
|
-
// `whenReady()` is failed rather than left to be resolved by the init
|
|
725
|
+
// Readiness describes dead GPU objects: `isReady()` reports the loss
|
|
726
|
+
// and `whenReady()` waiters fail rather than awaiting the init
|
|
729
727
|
// this loss may have landed in the middle of. Done BEFORE the listeners
|
|
730
728
|
// run, so a listener that recovers by calling `init()` synchronously
|
|
731
729
|
// finds the waiters already settled and re-arms the wait for the next
|
|
@@ -894,8 +892,13 @@ export class Renderer {
|
|
|
894
892
|
beginPointCloudStream(meta) {
|
|
895
893
|
return beginPointCloudStreamImpl(this, meta);
|
|
896
894
|
}
|
|
897
|
-
|
|
898
|
-
|
|
895
|
+
/** `key` makes the chunk removable on its own via `removePointCloudChunk` (one COPC node, #6869). */
|
|
896
|
+
appendPointCloudChunk(handle, chunk, key) {
|
|
897
|
+
appendPointCloudChunkImpl(this, handle, chunk, key);
|
|
898
|
+
}
|
|
899
|
+
/** Free the chunks appended under `key`; returns the points removed (0 for a stale handle). */
|
|
900
|
+
removePointCloudChunk(handle, key) {
|
|
901
|
+
return removePointCloudChunkImpl(this, handle, key);
|
|
899
902
|
}
|
|
900
903
|
endPointCloudStream(handle) {
|
|
901
904
|
endPointCloudStreamImpl(this, handle);
|
|
@@ -904,14 +907,13 @@ export class Renderer {
|
|
|
904
907
|
removePointCloudAssetImpl(this, handle);
|
|
905
908
|
}
|
|
906
909
|
/**
|
|
907
|
-
*
|
|
908
|
-
*
|
|
909
|
-
* the
|
|
910
|
-
*
|
|
911
|
-
* buffer rewrite needed.
|
|
910
|
+
* Bind a streamed point cloud to its federation identity after upload:
|
|
911
|
+
* the post-offset globalId picking and deviation readback report, and,
|
|
912
|
+
* when given, the model index they attribute the asset to (#6887). Takes
|
|
913
|
+
* effect on the next render — no GPU buffer rewrite needed.
|
|
912
914
|
*/
|
|
913
|
-
relabelPointCloudAsset(handle, newExpressId) {
|
|
914
|
-
this.pointCloudRenderer?.relabelAsset(handle, newExpressId);
|
|
915
|
+
relabelPointCloudAsset(handle, newExpressId, modelIndex) {
|
|
916
|
+
this.pointCloudRenderer?.relabelAsset(handle, newExpressId, modelIndex);
|
|
915
917
|
this.requestRender();
|
|
916
918
|
}
|
|
917
919
|
/** Bounds across flat draw batches. */
|
|
@@ -964,6 +966,10 @@ export class Renderer {
|
|
|
964
966
|
getPointCloudTransform(handle) {
|
|
965
967
|
return this.pointCloudRenderer?.getAssetTransform(handle);
|
|
966
968
|
}
|
|
969
|
+
/** Exact float64 placement copy for CPU math; the f32 transform rounds map-grid origins (#6894). */
|
|
970
|
+
getPointCloudPlacement(handle) {
|
|
971
|
+
return this.pointCloudRenderer?.getAssetPlacement(handle);
|
|
972
|
+
}
|
|
967
973
|
/**
|
|
968
974
|
* Set/clear a streamed cloud's column-major model matrix (16 floats) for
|
|
969
975
|
* IfcMapConversion alignment (#1804). Applied on the next frame's uniform
|
|
@@ -981,22 +987,17 @@ export class Renderer {
|
|
|
981
987
|
* `deviation/deviation-computer.ts` for the full contract.
|
|
982
988
|
*/
|
|
983
989
|
async computeDeviations(opts = {}) {
|
|
984
|
-
return this.deviationComputer.compute(opts,
|
|
985
|
-
device: this.device,
|
|
986
|
-
scene: this.scene,
|
|
987
|
-
pointCloudRenderer: this.pointCloudRenderer,
|
|
988
|
-
requestRender: () => this.requestRender(),
|
|
989
|
-
});
|
|
990
|
+
return this.deviationComputer.compute(opts, this.deviationContext());
|
|
990
991
|
}
|
|
991
992
|
/** Read per-scan-asset signed-distance statistics after a completed run. */
|
|
992
993
|
async readDeviationAssetStats() {
|
|
993
|
-
return this.deviationComputer.readAssetStats(
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
});
|
|
994
|
+
return this.deviationComputer.readAssetStats(this.deviationContext());
|
|
995
|
+
}
|
|
996
|
+
/** Read every computed point's signed distance (4 B/point) for summary statistics (#6872). */
|
|
997
|
+
async readDeviationDistances() {
|
|
998
|
+
return this.deviationComputer.readDistances(this.deviationContext());
|
|
999
999
|
}
|
|
1000
|
+
deviationContext = () => ({ device: this.device, scene: this.scene, pointCloudRenderer: this.pointCloudRenderer, requestRender: () => this.requestRender() });
|
|
1000
1001
|
/**
|
|
1001
1002
|
* Toggle Eye-Dome Lighting and tune its strength.
|
|
1002
1003
|
*
|
|
@@ -1172,7 +1173,7 @@ export class Renderer {
|
|
|
1172
1173
|
}
|
|
1173
1174
|
/** The source batch's frame for an individual copy of `meshData` (see individual-mesh-upload.ts). */
|
|
1174
1175
|
individualMeshFrame(meshData) {
|
|
1175
|
-
return
|
|
1176
|
+
return this.scene.getIndividualMeshFrame(meshData);
|
|
1176
1177
|
}
|
|
1177
1178
|
/**
|
|
1178
1179
|
* Create a GPU Mesh from MeshData (lazy creation for selection highlighting)
|
|
@@ -1271,9 +1272,6 @@ export class Renderer {
|
|
|
1271
1272
|
}
|
|
1272
1273
|
});
|
|
1273
1274
|
}
|
|
1274
|
-
/**
|
|
1275
|
-
* Render frame
|
|
1276
|
-
*/
|
|
1277
1275
|
/** Get diagnostic info for mobile debugging */
|
|
1278
1276
|
getDiagnostics() {
|
|
1279
1277
|
const pos = this.camera.getPosition();
|
|
@@ -1294,15 +1292,15 @@ export class Renderer {
|
|
|
1294
1292
|
bounds: b ? `${b.min.x.toFixed(0)}..${b.max.x.toFixed(0)} ${b.min.y.toFixed(0)}..${b.max.y.toFixed(0)} ${b.min.z.toFixed(0)}..${b.max.z.toFixed(0)}` : 'none',
|
|
1295
1293
|
};
|
|
1296
1294
|
}
|
|
1295
|
+
setGpuFrameTiming(enabled) { configureRendererGpuTiming(this, enabled); }
|
|
1296
|
+
getGpuFrameTiming() { return readRendererGpuTiming(this); }
|
|
1297
1297
|
/**
|
|
1298
1298
|
* Statistics of the last COMPLETED render() call (draw calls issued,
|
|
1299
1299
|
* batches drawn / frustum-culled / contribution-culled), or null before
|
|
1300
1300
|
* the first frame. Pair with `getScene().getResidentGpuBytes()` for the
|
|
1301
1301
|
* load-complete telemetry snapshot (issue #1682 observability).
|
|
1302
1302
|
*/
|
|
1303
|
-
getFrameStats() {
|
|
1304
|
-
return this._lastFrameStats;
|
|
1305
|
-
}
|
|
1303
|
+
getFrameStats() { return this._lastFrameStats; }
|
|
1306
1304
|
/**
|
|
1307
1305
|
* Vendor/architecture identity of the GPU adapter, snapshotted during
|
|
1308
1306
|
* `init()` (issue #2624 device-loss telemetry), or null when the runtime
|
|
@@ -1327,8 +1325,10 @@ export class Renderer {
|
|
|
1327
1325
|
this.scene.setQuantizedBatches(true);
|
|
1328
1326
|
return ok;
|
|
1329
1327
|
}
|
|
1328
|
+
/** Draw a frame through the shared submission path, preserving the void API. */
|
|
1329
|
+
render(options = {}) { this.renderWithResult(options); }
|
|
1330
1330
|
/**
|
|
1331
|
-
* Draw one frame.
|
|
1331
|
+
* Draw one frame; true only when it submits without a contained synchronous failure (#6709).
|
|
1332
1332
|
*
|
|
1333
1333
|
* Never throws, so callers never need to guard this call to keep their
|
|
1334
1334
|
* animation loop alive.
|
|
@@ -1347,26 +1347,22 @@ export class Renderer {
|
|
|
1347
1347
|
* carries on. Once enough such frames have degraded without recovering,
|
|
1348
1348
|
* `onPersistentRenderDegradation` fires once.
|
|
1349
1349
|
*
|
|
1350
|
-
*
|
|
1351
|
-
*
|
|
1352
|
-
*
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
* no latch and no toast. Both now run the same policy; the encode catch
|
|
1356
|
-
* additionally balances the frame's validation error scope before doing so.
|
|
1357
|
-
*/
|
|
1358
|
-
render(options = {}) {
|
|
1350
|
+
* Frame setup and encoding through `submit` share `containFrameThrow`
|
|
1351
|
+
* (#2417); the encode catch also balances the validation error scope.
|
|
1352
|
+
* Submission is synchronous, distinct from GPU completion/validation.
|
|
1353
|
+
*/
|
|
1354
|
+
renderWithResult(options = {}) {
|
|
1359
1355
|
this._renderCallCount++;
|
|
1360
1356
|
// A lost device leaves every pipeline/buffer dead; rendering would only
|
|
1361
1357
|
// emit a stream of validation errors. Stay quiet until re-init.
|
|
1362
1358
|
if (this.deviceLost) {
|
|
1363
1359
|
this._renderSkipCount++;
|
|
1364
1360
|
cancelRendererColorFrame(this);
|
|
1365
|
-
return;
|
|
1361
|
+
return false;
|
|
1366
1362
|
}
|
|
1367
1363
|
try {
|
|
1368
1364
|
this.frameContainedThrow = false;
|
|
1369
|
-
this.renderFrame(options);
|
|
1365
|
+
const submitted = this.renderFrame(options);
|
|
1370
1366
|
// Only a frame that actually got through resets the run. A frame
|
|
1371
1367
|
// the ENCODE catch contained returns here normally (that catch is
|
|
1372
1368
|
// inside renderFrame), so "did not throw" is not the same question
|
|
@@ -1374,6 +1370,7 @@ export class Renderer {
|
|
|
1374
1370
|
if (!this.frameContainedThrow)
|
|
1375
1371
|
this.consecutiveDegradedFrames = 0;
|
|
1376
1372
|
retryRendererColorFrame(this, () => this.requestRender());
|
|
1373
|
+
return submitted;
|
|
1377
1374
|
}
|
|
1378
1375
|
catch (error) {
|
|
1379
1376
|
// Safari (26.5) reports device loss SYNCHRONOUSLY: a call against a
|
|
@@ -1390,24 +1387,25 @@ export class Renderer {
|
|
|
1390
1387
|
this._renderSkipCount++;
|
|
1391
1388
|
this.containFrameThrow(error, 'frame');
|
|
1392
1389
|
cancelRendererColorFrame(this);
|
|
1390
|
+
return false;
|
|
1393
1391
|
}
|
|
1394
1392
|
}
|
|
1395
1393
|
/**
|
|
1396
|
-
* The frame body. Throws on a synchronously-dead GPU device;
|
|
1397
|
-
* owns
|
|
1394
|
+
* The frame body. Throws on a synchronously-dead GPU device;
|
|
1395
|
+
* `renderWithResult()` owns containment for both public render methods.
|
|
1398
1396
|
*/
|
|
1399
1397
|
renderFrame(options) {
|
|
1400
1398
|
if (!this.device.isInitialized() || !this.pipeline) {
|
|
1401
1399
|
this._renderSkipCount++;
|
|
1402
|
-
return;
|
|
1400
|
+
return false;
|
|
1403
1401
|
}
|
|
1404
1402
|
// Drawing buffer = the element's device-pixel size (capped ratio, clamped
|
|
1405
1403
|
// to the GPU's max texture dimension); see computeDrawingBufferSize (#5383).
|
|
1406
|
-
const measured = measureDrawingBuffer(this.canvas, this.device.getMaxTextureDimension());
|
|
1404
|
+
const measured = measureDrawingBuffer(this.canvas, this.device.getMaxTextureDimension(), this.maxPixelRatio, options.maxPixelRatio);
|
|
1407
1405
|
// Skip rendering while the canvas is collapsed or too small.
|
|
1408
1406
|
if (!measured || measured.height < 10) {
|
|
1409
1407
|
this._renderSkipCount++;
|
|
1410
|
-
return;
|
|
1408
|
+
return false;
|
|
1411
1409
|
}
|
|
1412
1410
|
const { width, height } = measured;
|
|
1413
1411
|
this.pixelRatio = measured.pixelRatio;
|
|
@@ -1425,12 +1423,12 @@ export class Renderer {
|
|
|
1425
1423
|
// Skip rendering if canvas is invalid
|
|
1426
1424
|
if (this.canvas.width === 0 || this.canvas.height === 0) {
|
|
1427
1425
|
this._renderSkipCount++;
|
|
1428
|
-
return;
|
|
1426
|
+
return false;
|
|
1429
1427
|
}
|
|
1430
1428
|
// Ensure context is valid before rendering (handles HMR, focus changes, etc.)
|
|
1431
1429
|
if (!this.device.ensureContext()) {
|
|
1432
1430
|
this._renderSkipCount++;
|
|
1433
|
-
return; // Skip this frame, context will be ready next frame
|
|
1431
|
+
return false; // Skip this frame, context will be ready next frame
|
|
1434
1432
|
}
|
|
1435
1433
|
const device = this.device.getDevice();
|
|
1436
1434
|
const viewProj = this.camera.getViewProjMatrix().m;
|
|
@@ -1619,7 +1617,7 @@ export class Renderer {
|
|
|
1619
1617
|
errorScopePushed = false;
|
|
1620
1618
|
this.drainErrorScope(device);
|
|
1621
1619
|
}
|
|
1622
|
-
return; // Skip this frame, context will be reconfigured next frame
|
|
1620
|
+
return false; // Skip this frame, context will be reconfigured next frame
|
|
1623
1621
|
}
|
|
1624
1622
|
let colorCapture = null;
|
|
1625
1623
|
let colorReadback = null;
|
|
@@ -1762,6 +1760,7 @@ export class Renderer {
|
|
|
1762
1760
|
}
|
|
1763
1761
|
// Now record draw commands
|
|
1764
1762
|
const encoder = device.createCommandEncoder();
|
|
1763
|
+
beginRendererGpuTiming(this, device, encoder);
|
|
1765
1764
|
// Sun shadow-map pass (#2670, Phase 2). Off unless the caller opts
|
|
1766
1765
|
// in; when off the hot path pays only this check and (once) an
|
|
1767
1766
|
// enabled=0 reset on toggle-off. Runs BEFORE the colour pass (its
|
|
@@ -1927,6 +1926,7 @@ export class Renderer {
|
|
|
1927
1926
|
storeOp: (needsObjectIdPass ? 'store' : 'discard'),
|
|
1928
1927
|
});
|
|
1929
1928
|
const pass = encoder.beginRenderPass({
|
|
1929
|
+
timestampWrites: renderPassTimestampWrites(encoder, 'main'),
|
|
1930
1930
|
colorAttachments,
|
|
1931
1931
|
depthStencilAttachment: {
|
|
1932
1932
|
view: this.pipeline.getDepthTextureView(),
|
|
@@ -2306,6 +2306,10 @@ export class Renderer {
|
|
|
2306
2306
|
// probe (enableQuantizedBatches) verified they exist, so the
|
|
2307
2307
|
// base fallback here is type-safety, never taken.
|
|
2308
2308
|
const pipeFor = (batch, kind) => {
|
|
2309
|
+
const ghost = kind === 'transparent' && xray.isGhostBatch(batch)
|
|
2310
|
+
? this.pipeline.getGhostPipeline(!!batch.quantized, () => this.requestRender()) : null;
|
|
2311
|
+
if (ghost)
|
|
2312
|
+
return ghost;
|
|
2309
2313
|
const base = kind === 'opaque' ? this.pipeline.getPipeline() : this.pipeline.getTransparentPipeline();
|
|
2310
2314
|
if (!batch.quantized)
|
|
2311
2315
|
return base;
|
|
@@ -2800,6 +2804,7 @@ export class Renderer {
|
|
|
2800
2804
|
height: this.canvas.height,
|
|
2801
2805
|
// Depth-only: depth24plus-stencil8 cannot be sampled as texture_depth_* with aspect 'all'.
|
|
2802
2806
|
depthView: this.pipeline.getDepthOnlyTextureView(),
|
|
2807
|
+
maskDepthView: this.pipeline.getDepthTextureView(),
|
|
2803
2808
|
objectIdView,
|
|
2804
2809
|
projection: this.camera.getProjMatrix(),
|
|
2805
2810
|
enhancement: visualEnhancement,
|
|
@@ -2810,7 +2815,7 @@ export class Renderer {
|
|
|
2810
2815
|
selectionOutline,
|
|
2811
2816
|
});
|
|
2812
2817
|
colorReadback = colorCapture && encodeRendererColorFrameCapture(device, encoder, colorCapture);
|
|
2813
|
-
device
|
|
2818
|
+
submitRendererGpuTiming(this, device, encoder);
|
|
2814
2819
|
if (colorReadback && colorCapture) {
|
|
2815
2820
|
settleRendererColorFrameCapture(this, colorCapture, colorReadback);
|
|
2816
2821
|
colorCapture = null;
|
|
@@ -2837,8 +2842,10 @@ export class Renderer {
|
|
|
2837
2842
|
errorScopePushed = false;
|
|
2838
2843
|
this.drainErrorScope(device);
|
|
2839
2844
|
}
|
|
2845
|
+
return true;
|
|
2840
2846
|
}
|
|
2841
2847
|
catch (error) {
|
|
2848
|
+
releaseRendererGpuTiming(this);
|
|
2842
2849
|
discardRendererColorFrameReadback(colorReadback);
|
|
2843
2850
|
// Balance the validation scope if we threw before popping it above —
|
|
2844
2851
|
// an unpopped scope would capture every later frame's errors silently.
|
|
@@ -2875,6 +2882,7 @@ export class Renderer {
|
|
|
2875
2882
|
// the discriminator keys on the TYPE and not on "a frame threw".
|
|
2876
2883
|
this.containFrameThrow(error, 'encode');
|
|
2877
2884
|
cancelRendererColorFrame(this);
|
|
2885
|
+
return false;
|
|
2878
2886
|
}
|
|
2879
2887
|
}
|
|
2880
2888
|
/**
|
|
@@ -3007,6 +3015,8 @@ export class Renderer {
|
|
|
3007
3015
|
resize(width, height) {
|
|
3008
3016
|
resizeRendererViewport(this.canvas, this.camera, width, height);
|
|
3009
3017
|
}
|
|
3018
|
+
/** Cap the drawing buffer's device-pixel ratio, trading sharpness for fill on HiDPI screens; see computeDrawingBufferSize. */
|
|
3019
|
+
setMaxPixelRatio(ratio) { this.maxPixelRatio = ratio; this.requestRender(); }
|
|
3010
3020
|
/** Stage one new owner; borrowed mesh buffers must remain immutable until disposal. */
|
|
3011
3021
|
prepareAuthoredOwner(parts) {
|
|
3012
3022
|
if (this.deviceLost || !this.device.isInitialized() || !this.pipeline)
|
|
@@ -3286,6 +3296,7 @@ export class Renderer {
|
|
|
3286
3296
|
// Re-arm the section-bounds diagnostic log for the next model.
|
|
3287
3297
|
this._loggedSectionBounds = false;
|
|
3288
3298
|
}
|
|
3299
|
+
releaseRendererGpuTiming(this);
|
|
3289
3300
|
// Render pipelines (textures + uniform buffers)
|
|
3290
3301
|
this.pipeline?.destroy();
|
|
3291
3302
|
this.pipeline = null;
|