@equinor/videx-3d 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -120
- package/dist/chunk-61X6qE5N.js +981 -0
- package/dist/chunk-ChG5d4HC.js +675 -0
- package/dist/{chunk-BolRQZt9.js → chunk-M-Pcc_Yg.js} +22 -20
- package/dist/generators.js +271 -260
- package/dist/main.js +5185 -3434
- package/dist/sdk.js +492 -316
- package/dist/shaderLib/oit.glsl +106 -0
- package/dist/types/components/Annotations/AutoUpdate.d.ts +1 -1
- package/dist/types/components/Annotations/index.d.ts +2 -2
- package/dist/types/components/Annotations/types.d.ts +3 -1
- package/dist/types/components/Annotations/update-annotations.d.ts +10 -0
- package/dist/types/components/EventEmitter/EventEmitterContext.d.ts +2 -1
- package/dist/types/components/EventEmitter/index.d.ts +1 -0
- package/dist/types/components/EventEmitter/picking-helper.d.ts +25 -0
- package/dist/types/components/EventEmitter/picking-material.d.ts +8 -5
- package/dist/types/components/Surfaces/Surface.d.ts +8 -1
- package/dist/types/components/Surfaces/SurfaceMaterial.d.ts +3 -0
- package/dist/types/components/Surfaces/surface-defs.d.ts +1 -0
- package/dist/types/components/Wellbores/Casings/CasingEmitterMaterial.d.ts +16 -0
- package/dist/types/components/Wellbores/Casings/CasingSection.d.ts +3 -2
- package/dist/types/components/Wellbores/Casings/Casings.d.ts +3 -2
- package/dist/types/generators/surface-generator.d.ts +1 -1
- package/dist/types/layers/layers.d.ts +4 -0
- package/dist/types/rendering/OitMaterial.d.ts +59 -0
- package/dist/types/rendering/Pass.d.ts +7 -0
- package/dist/types/rendering/RenderingPipeline.d.ts +37 -0
- package/dist/types/rendering/fullscreen-renderer.d.ts +1 -0
- package/dist/types/rendering/gpu-timer.d.ts +46 -0
- package/dist/types/rendering/index.d.ts +7 -1
- package/dist/types/rendering/oit-material.d.ts +122 -0
- package/dist/types/{components/Annotations/annotations-renderer.d.ts → rendering/passes/AnnotationsPass.d.ts} +13 -4
- package/dist/types/rendering/passes/FXAAPass.d.ts +12 -0
- package/dist/types/rendering/passes/OITRenderPass.d.ts +282 -0
- package/dist/types/rendering/passes/OutputPass.d.ts +10 -0
- package/dist/types/rendering/passes/RenderPass.d.ts +8 -0
- package/dist/types/rendering/passes/SMAAPass.d.ts +40 -0
- package/dist/types/rendering/passes/TAAPass.d.ts +94 -0
- package/dist/types/rendering/passes/index.d.ts +6 -0
- package/dist/types/rendering/rendering-state.d.ts +59 -0
- package/dist/types/sdk/index.d.ts +2 -0
- package/dist/types/sdk/utils/elevation-map.d.ts +23 -0
- package/dist/types/sdk/utils/trigonometry.d.ts +4 -1
- package/package.json +1 -1
- package/dist/chunk-CnY6Tmof.js +0 -358
- package/dist/chunk-iY0wQ9Z6.js +0 -887
- package/dist/types/rendering/render-passes.d.ts +0 -16
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Camera, CanvasTexture, Clock, PerspectiveCamera, ShaderMaterial, Vector2, WebGLRenderer, WebGLRenderTarget } from 'three';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
2
|
+
import { AnnotationInstance } from '../../components/Annotations/types';
|
|
3
|
+
import { FullscreenRenderer } from '../fullscreen-renderer';
|
|
4
|
+
import { Pass } from '../Pass';
|
|
5
|
+
export declare class AnnotationsPass extends Pass {
|
|
5
6
|
maxVisible: number;
|
|
6
7
|
camera: PerspectiveCamera;
|
|
7
8
|
clock: Clock;
|
|
@@ -12,11 +13,19 @@ export declare class AnnotationsRenderer {
|
|
|
12
13
|
annotationsRenderTarget: WebGLRenderTarget;
|
|
13
14
|
annotationsBuffer: Uint8Array;
|
|
14
15
|
annotationsMaterial: ShaderMaterial;
|
|
15
|
-
fullscreenRenderer: FullscreenRenderer;
|
|
16
16
|
annotationsData: AnnotationInstance[];
|
|
17
17
|
isBusy: boolean;
|
|
18
18
|
dataTextureNeedsUpdate: boolean;
|
|
19
|
+
fullscreenRenderer: FullscreenRenderer;
|
|
19
20
|
unsubscribeListeners: () => void;
|
|
21
|
+
private prevCameraMatrix;
|
|
22
|
+
private prevPointerX;
|
|
23
|
+
private prevPointerY;
|
|
24
|
+
private prevSizeX;
|
|
25
|
+
private prevSizeY;
|
|
26
|
+
private occlusionChanged;
|
|
27
|
+
connectorTargetFrameTime: number;
|
|
28
|
+
connectorStretchSlack: number;
|
|
20
29
|
constructor(camera: Camera, clock: Clock, pointer: Vector2, maxVisible?: number);
|
|
21
30
|
updateAnnotationsData(buffer: Uint8Array): void;
|
|
22
31
|
updateOverlayTexture(inViewSpace: AnnotationInstance[]): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { WebGLRenderer, WebGLRenderTarget } from 'three';
|
|
2
|
+
import { Pass } from '../Pass';
|
|
3
|
+
export declare class FxaaPass extends Pass {
|
|
4
|
+
private scratch;
|
|
5
|
+
private fxaaMaterial;
|
|
6
|
+
private blitMaterial;
|
|
7
|
+
private fullscreenRenderer;
|
|
8
|
+
constructor();
|
|
9
|
+
setSize(width: number, height: number): void;
|
|
10
|
+
dispose(): void;
|
|
11
|
+
render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { Camera, Scene, WebGLRenderer, WebGLRenderTarget } from 'three';
|
|
2
|
+
import { Pass } from '../Pass';
|
|
3
|
+
/** Per-frame object counts for each classification, exposed for debugging. */
|
|
4
|
+
export type OITRenderPassStats = {
|
|
5
|
+
/** Plain opaque renderables (not OIT-capable, not overlay). */
|
|
6
|
+
opaque: number;
|
|
7
|
+
/** OIT-capable renderables currently transparent (routed through OIT). */
|
|
8
|
+
oit: number;
|
|
9
|
+
/**
|
|
10
|
+
* OIT-capable renderables that are currently fully opaque and therefore drawn in
|
|
11
|
+
* the opaque pass as real occluders (depth-writing), bypassing the OIT passes.
|
|
12
|
+
*/
|
|
13
|
+
oitOpaque: number;
|
|
14
|
+
/** Additive/glow renderables (tagged `LAYERS.EMISSIVE`), drawn before the transparent layers. */
|
|
15
|
+
emissive: number;
|
|
16
|
+
/** Always-on-top renderables (tagged `LAYERS.OVERLAY`), drawn after the transparent layers. */
|
|
17
|
+
overlay: number;
|
|
18
|
+
/** Subset of `oit` whose whole material is OIT-capable (hidden in opaque pass). */
|
|
19
|
+
oitHidden: number;
|
|
20
|
+
/** Subset of `oit` that are mixed multi-material meshes (some opaque groups). */
|
|
21
|
+
oitMixed: number;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Resource/accumulation counters for leak monitoring. Unlike {@link OITRenderPassStats}
|
|
25
|
+
* (per-frame object classification, which naturally varies with the camera), these
|
|
26
|
+
* track internal structures and global GPU resources that should stay *bounded* over
|
|
27
|
+
* time. Watch them while toggling the pipeline on/off (which recreates the passes): a
|
|
28
|
+
* steady climb indicates passes or GPU resources are not being disposed.
|
|
29
|
+
*/
|
|
30
|
+
export type OITRenderPassResources = {
|
|
31
|
+
/**
|
|
32
|
+
* Active OIT pipeline registrations on this canvas (the ref-counted
|
|
33
|
+
* {@link RenderingState} `_oitCount`). Should read 1 while a single OIT pipeline is
|
|
34
|
+
* mounted; a value that climbs each time the pipeline is recreated means a pass was
|
|
35
|
+
* acquired but never released in {@link OITRenderPass.dispose} (a real leak).
|
|
36
|
+
*/
|
|
37
|
+
oitPipelines: number;
|
|
38
|
+
/**
|
|
39
|
+
* Total classification entries created since this pass instance was constructed
|
|
40
|
+
* (monotonic). Resets only when the pass itself is recreated, so it grows quickly
|
|
41
|
+
* during warm-up and should then plateau.
|
|
42
|
+
*/
|
|
43
|
+
entriesTotal: number;
|
|
44
|
+
/**
|
|
45
|
+
* Classification entries created this frame (cache misses). ~0 in steady state; a
|
|
46
|
+
* persistently non-zero value means object material identities churn every frame,
|
|
47
|
+
* which also churns the cached per-pass OIT variants.
|
|
48
|
+
*/
|
|
49
|
+
entriesThisFrame: number;
|
|
50
|
+
/** GPU textures currently tracked by the renderer (global; watch for unbounded growth). */
|
|
51
|
+
textures: number;
|
|
52
|
+
/** GPU geometries currently tracked by the renderer (global). */
|
|
53
|
+
geometries: number;
|
|
54
|
+
/** Compiled shader programs currently held by the renderer (global). `-1` if unavailable. */
|
|
55
|
+
programs: number;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Per-segment GPU timings in milliseconds, populated when {@link OITRenderPass.profile}
|
|
59
|
+
* is enabled and the platform supports timer queries. `-1` means "no result yet"
|
|
60
|
+
* (or unsupported). `tail` is the single weighted-blended OIT pass cost.
|
|
61
|
+
*/
|
|
62
|
+
export type OITRenderPassTimings = {
|
|
63
|
+
/** Opaque pass (step 1), including any forced-opaque OIT occluders. */
|
|
64
|
+
opaque: number;
|
|
65
|
+
/** Additive/glow emissive pass (step 1b). */
|
|
66
|
+
emissive: number;
|
|
67
|
+
/** Min-depth pre-pass (step 2). */
|
|
68
|
+
minDepth: number;
|
|
69
|
+
/** Weighted-blended OIT tail pass (step 3). */
|
|
70
|
+
tail: number;
|
|
71
|
+
/** Fullscreen tail composite (step 4). */
|
|
72
|
+
composite: number;
|
|
73
|
+
/** Exact front-layer pass (step 5). */
|
|
74
|
+
front: number;
|
|
75
|
+
/** Optional occlusion depth-stamp pass (step 5b). */
|
|
76
|
+
occlusion: number;
|
|
77
|
+
/** Optional emitter depth-stamp pass (step 1c). */
|
|
78
|
+
emitterStamp: number;
|
|
79
|
+
/** Always-on-top overlay pass (step 6). */
|
|
80
|
+
overlay: number;
|
|
81
|
+
/** Sum of the measured OIT segments above. */
|
|
82
|
+
total: number;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Hybrid order-independent-transparency (OIT) render pass for use with the
|
|
86
|
+
* {@link RenderingPipeline} (or any custom composer). Renders the nearest transparent
|
|
87
|
+
* layer exactly (depth-peeled, alpha-over) and the remaining layers using
|
|
88
|
+
* weighted-blended OIT (WBOIT), partitioned per-pixel in view-space linear depth.
|
|
89
|
+
*
|
|
90
|
+
* Transparency is opt-in: this pass only affects materials that are OIT-capable
|
|
91
|
+
* (library materials, or stock/user materials patched with `makeOitCompatible`).
|
|
92
|
+
* Two per-object escape-hatch layers override the default routing: `LAYERS.FORCE_OPAQUE`
|
|
93
|
+
* draws the object as a depth-writing opaque occluder (its material is temporarily
|
|
94
|
+
* forced to `depthWrite=true, transparent=false`); `LAYERS.OIT_EXCLUDED` also draws it
|
|
95
|
+
* in the opaque pass but leaves the material's own properties untouched.
|
|
96
|
+
* Additive/glow objects tagged with the `LAYERS.EMISSIVE` layer are drawn between the
|
|
97
|
+
* opaque and transparent layers (so transparent surfaces in front attenuate them);
|
|
98
|
+
* always-on-top objects tagged with the `LAYERS.OVERLAY` layer are drawn last, on top
|
|
99
|
+
* of the resolved transparency. While this pass is active it sets the per-canvas
|
|
100
|
+
* rendering state to `'oit'` so components can disable conflicting self-transparency
|
|
101
|
+
* workarounds.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```tsx
|
|
105
|
+
* const passes = useMemo(
|
|
106
|
+
* () => [new OITRenderPass(scene, camera), new OutputPass()],
|
|
107
|
+
* [scene, camera],
|
|
108
|
+
* );
|
|
109
|
+
* return <RenderingPipeline passes={passes} />;
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
112
|
+
* @group Rendering
|
|
113
|
+
* @see {@link RenderingPipeline}
|
|
114
|
+
* @see {@link makeOitCompatible}
|
|
115
|
+
*/
|
|
116
|
+
export declare class OITRenderPass extends Pass {
|
|
117
|
+
private scene;
|
|
118
|
+
private camera;
|
|
119
|
+
/**
|
|
120
|
+
* Debug: when true, the exact depth-peeled front layer is disabled and every
|
|
121
|
+
* transparent fragment is resolved through the weighted-blended (WBOIT) tail.
|
|
122
|
+
* Useful for isolating tail behaviour and comparing against the hybrid result.
|
|
123
|
+
*/
|
|
124
|
+
skipFront: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Optional feature (default off): after the transparent OIT passes, stamp depth
|
|
127
|
+
* for transparent surfaces wherever their own alpha is at least
|
|
128
|
+
* {@link occlusionDepthThreshold}. Transparent surfaces normally write no depth, so
|
|
129
|
+
* annotation labels behind a high-but-not-full opacity surface are never occluded;
|
|
130
|
+
* enabling this makes a surface occlude labels once its alpha clears the threshold.
|
|
131
|
+
*
|
|
132
|
+
* The test is per-fragment and per-surface (each surface judged on its own alpha,
|
|
133
|
+
* not accumulated coverage), and the stamped depth uses the same encoding the
|
|
134
|
+
* {@link AnnotationsPass} already samples. Costs one extra transparent-geometry
|
|
135
|
+
* pass per frame when enabled; nothing (not even a shader compile) when off.
|
|
136
|
+
*/
|
|
137
|
+
occlusionDepthStamp: boolean;
|
|
138
|
+
/** Alpha threshold (0..1) for {@link occlusionDepthStamp}. Default 0.5. */
|
|
139
|
+
occlusionDepthThreshold: number;
|
|
140
|
+
/**
|
|
141
|
+
* Optional feature (default off): stamp depth for emissive/glow emitters (objects
|
|
142
|
+
* on `LAYERS.EMISSIVE`) wherever their fragment strength is at least
|
|
143
|
+
* {@link emitterDepthThreshold}, drawn before the transparent OIT passes. This lets
|
|
144
|
+
* the dense core of an additive emitter (e.g. perforation jets) occlude transparent
|
|
145
|
+
* surfaces behind it, preventing the wash-out where a far transparent surface would
|
|
146
|
+
* otherwise dim the emitter. Surfaces in front still attenuate it.
|
|
147
|
+
*
|
|
148
|
+
* An emitter opts in by exposing a depth-only stamp material on its material's
|
|
149
|
+
* `userData.occlusionDepthMaterial` (with a `uOcclusionThreshold` uniform the pass
|
|
150
|
+
* drives). Emitters without one are simply skipped. Costs one extra emissive pass
|
|
151
|
+
* per frame when enabled; nothing when off.
|
|
152
|
+
*/
|
|
153
|
+
emitterDepthStamp: boolean;
|
|
154
|
+
/** Strength threshold (0..1) for {@link emitterDepthStamp}. Default 0.5. */
|
|
155
|
+
emitterDepthThreshold: number;
|
|
156
|
+
/**
|
|
157
|
+
* When true, draws small thumbnails of the internal render targets (min-depth,
|
|
158
|
+
* accumulation) into the bottom-left of the output, for debugging.
|
|
159
|
+
* GPU-only; no pixel readback.
|
|
160
|
+
*/
|
|
161
|
+
debugTargets: boolean;
|
|
162
|
+
/**
|
|
163
|
+
* When true, measures per-segment GPU time (opaque/emissive/min-depth/tail/
|
|
164
|
+
* composite/front/overlay) via timer queries and exposes it on {@link timings}. Adds a
|
|
165
|
+
* little CPU/driver overhead and lags a few frames, so it is off by default. No-op
|
|
166
|
+
* on platforms without `EXT_disjoint_timer_query_webgl2`.
|
|
167
|
+
*
|
|
168
|
+
* The most relevant figure for the transparent-geometry cost is
|
|
169
|
+
* {@link OITRenderPassTimings.tail}.
|
|
170
|
+
*/
|
|
171
|
+
profile: boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Per-segment GPU timings (ms) from the last completed measurement. Only updated
|
|
174
|
+
* while {@link profile} is enabled. `-1` means "no result yet" or unsupported.
|
|
175
|
+
*/
|
|
176
|
+
readonly timings: OITRenderPassTimings;
|
|
177
|
+
/**
|
|
178
|
+
* Per-frame object counts for each pass, updated every {@link render}. Useful for
|
|
179
|
+
* verifying which objects are routed through OIT vs. drawn opaque/overlay.
|
|
180
|
+
*/
|
|
181
|
+
readonly stats: OITRenderPassStats;
|
|
182
|
+
/**
|
|
183
|
+
* Resource/accumulation counters for leak monitoring, updated every {@link render}.
|
|
184
|
+
* See {@link OITRenderPassResources}.
|
|
185
|
+
*/
|
|
186
|
+
readonly resources: OITRenderPassResources;
|
|
187
|
+
private fullscreenRenderer;
|
|
188
|
+
private minDepthTarget;
|
|
189
|
+
private accumTarget;
|
|
190
|
+
private compositeMaterial;
|
|
191
|
+
/** Lazily-created material for the debug-target thumbnails. */
|
|
192
|
+
private debugMaterial;
|
|
193
|
+
/** Lazily-created GPU timer, only when {@link profile} is first enabled. */
|
|
194
|
+
private gpuTimer;
|
|
195
|
+
/**
|
|
196
|
+
* OIT pipeline registration release handle. Acquired lazily on the first
|
|
197
|
+
* {@link render} rather than in the constructor: the host (e.g. a `useMemo`) may
|
|
198
|
+
* construct passes that React then discards without ever committing/rendering them,
|
|
199
|
+
* and a constructor-time acquire on such an orphan would never be released. Only
|
|
200
|
+
* committed passes are rendered, so acquiring here keeps the registration count
|
|
201
|
+
* symmetric with {@link dispose}.
|
|
202
|
+
*/
|
|
203
|
+
private releaseOit?;
|
|
204
|
+
private entryCache;
|
|
205
|
+
/** Monotonic count of classification entries created (cache misses). */
|
|
206
|
+
private entriesCreated;
|
|
207
|
+
/** Saved material state for OIT objects temporarily forced opaque this frame. */
|
|
208
|
+
private forcedOpaque;
|
|
209
|
+
private width;
|
|
210
|
+
private height;
|
|
211
|
+
private depthFar;
|
|
212
|
+
constructor(scene: Scene, camera: Camera);
|
|
213
|
+
setSize(width: number, height: number): void;
|
|
214
|
+
dispose(): void;
|
|
215
|
+
private getEntry;
|
|
216
|
+
/**
|
|
217
|
+
* Traverse the scene once, classifying renderables into transparent-OIT,
|
|
218
|
+
* plain-opaque, emissive (additive/glow) and always-on-top overlay sets.
|
|
219
|
+
* OIT-capable objects that are currently fully opaque, or explicitly tagged with
|
|
220
|
+
* the `LAYERS.FORCE_OPAQUE` layer, are added to both `opaqueList` (for the
|
|
221
|
+
* visibility lifecycle) and `oitOpaqueList` (so their materials can be forced
|
|
222
|
+
* depth-writing), making them real occluders. Objects tagged `LAYERS.OIT_EXCLUDED`
|
|
223
|
+
* are added to `opaqueList` only, so they render with their material untouched.
|
|
224
|
+
* Emissive objects are detected by the EMISSIVE layer, overlay objects by the
|
|
225
|
+
* OVERLAY layer.
|
|
226
|
+
*/
|
|
227
|
+
private collect;
|
|
228
|
+
/**
|
|
229
|
+
* Prepare the OIT renderables for the opaque pass. Objects whose whole material
|
|
230
|
+
* is OIT-capable are simply hidden (and collected into `hidden` for restore), so
|
|
231
|
+
* their geometry isn't rasterised at all. Mixed multi-material meshes are swapped
|
|
232
|
+
* to their opaque variant (opaque groups kept, OIT groups drawn as no-op).
|
|
233
|
+
*/
|
|
234
|
+
private applyOpaqueSwap;
|
|
235
|
+
private applyPassSwap;
|
|
236
|
+
private restoreMaterials;
|
|
237
|
+
private setOitUniforms;
|
|
238
|
+
private setVisible;
|
|
239
|
+
/**
|
|
240
|
+
* Resolve the opt-in depth-stamp material for an emissive emitter, if any. The
|
|
241
|
+
* emitter exposes it on `material.userData.occlusionDepthMaterial`; this also drives
|
|
242
|
+
* its `uOcclusionThreshold` uniform from {@link emitterDepthThreshold}. Returns null
|
|
243
|
+
* when the emitter provides no stamp material (it is then skipped).
|
|
244
|
+
*/
|
|
245
|
+
private getEmitterStamp;
|
|
246
|
+
/**
|
|
247
|
+
* Current effective opacity of a material. `ShaderMaterial`s drive opacity through
|
|
248
|
+
* a `uniforms.opacity` value (the material's own `opacity` field is often left at
|
|
249
|
+
* 1), so prefer that; otherwise use `Material.opacity`.
|
|
250
|
+
*/
|
|
251
|
+
private static effectiveOpacity;
|
|
252
|
+
/** Whether a material currently renders as fully opaque. */
|
|
253
|
+
private static isMaterialOpaque;
|
|
254
|
+
/**
|
|
255
|
+
* Whether an OIT entry is currently fully opaque (every OIT-capable material is
|
|
256
|
+
* opaque). Such objects are drawn in the opaque pass as real occluders instead of
|
|
257
|
+
* being routed through the (more expensive, depth-non-writing) OIT passes.
|
|
258
|
+
*/
|
|
259
|
+
private isEntryOpaque;
|
|
260
|
+
/**
|
|
261
|
+
* Temporarily force the OIT-capable materials of the given entries to write depth
|
|
262
|
+
* and render opaque, so they act as genuine occluders during the opaque pass. The
|
|
263
|
+
* previous state is saved and restored by {@link restoreForcedOpaque}. These
|
|
264
|
+
* objects are hidden during the OIT sub-passes, so the forced state only takes
|
|
265
|
+
* effect where intended.
|
|
266
|
+
*/
|
|
267
|
+
private applyForcedOpaque;
|
|
268
|
+
private restoreForcedOpaque;
|
|
269
|
+
/**
|
|
270
|
+
* Copy the latest smoothed GPU timings out of the timer into {@link timings} and
|
|
271
|
+
* recompute the `total`. Segments without a result yet (or skipped this frame)
|
|
272
|
+
* report `-1` and are excluded from the total.
|
|
273
|
+
*/
|
|
274
|
+
private updateTimings;
|
|
275
|
+
render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
|
|
276
|
+
/**
|
|
277
|
+
* Draw small thumbnails of the auxiliary render targets along the bottom-left of
|
|
278
|
+
* the output buffer (min-depth, accumulation). Uses the buffer's viewport
|
|
279
|
+
* to scope each draw; GPU-only.
|
|
280
|
+
*/
|
|
281
|
+
private renderDebugTargets;
|
|
282
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MeshBasicMaterial, WebGLRenderer, WebGLRenderTarget } from 'three';
|
|
2
|
+
import { FullscreenRenderer } from '../fullscreen-renderer';
|
|
3
|
+
import { Pass } from '../Pass';
|
|
4
|
+
export declare class OutputPass extends Pass {
|
|
5
|
+
fullscreenRenderer: FullscreenRenderer;
|
|
6
|
+
material: MeshBasicMaterial;
|
|
7
|
+
constructor();
|
|
8
|
+
render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
|
|
9
|
+
dispose(): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Camera, Scene, WebGLRenderer, WebGLRenderTarget } from 'three';
|
|
2
|
+
import { Pass } from '../Pass';
|
|
3
|
+
export declare class RenderPass extends Pass {
|
|
4
|
+
private scene;
|
|
5
|
+
private camera;
|
|
6
|
+
constructor(scene: Scene, camera: Camera);
|
|
7
|
+
render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Vector2, WebGLRenderer, WebGLRenderTarget } from 'three';
|
|
2
|
+
import { Pass } from '../Pass';
|
|
3
|
+
/**
|
|
4
|
+
* Subpixel Morphological Anti-Aliasing (SMAA) post-process pass for use with the
|
|
5
|
+
* {@link RenderingPipeline}. A drop-in alternative to {@link FxaaPass}: it detects
|
|
6
|
+
* edges by colour discontinuity and reconstructs anti-aliased silhouettes using
|
|
7
|
+
* precomputed area/search lookup tables, giving noticeably cleaner long edges on
|
|
8
|
+
* opaque geometry than FXAA, with less detail blurring.
|
|
9
|
+
*
|
|
10
|
+
* SMAA operates in linear space and must run before the {@link OutputPass} (i.e.
|
|
11
|
+
* before tone-mapping / output-encoding), exactly like {@link FxaaPass}.
|
|
12
|
+
*
|
|
13
|
+
* Like all morphological techniques it cannot recover sub-pixel features (e.g.
|
|
14
|
+
* 1px WebGL lines that fall between samples) — use {@link TAAPass} for those.
|
|
15
|
+
*
|
|
16
|
+
* This wraps the well-tested SMAA shaders and lookup textures from `three-stdlib`
|
|
17
|
+
* and drives the three sub-passes (edge detection, blend-weight calculation,
|
|
18
|
+
* neighbourhood blending) through the pipeline's {@link FullscreenRenderer},
|
|
19
|
+
* compositing the result back into the shared buffer in place.
|
|
20
|
+
*
|
|
21
|
+
* @group Rendering
|
|
22
|
+
* @see {@link RenderingPipeline}
|
|
23
|
+
* @see {@link FxaaPass}
|
|
24
|
+
* @see {@link TAAPass}
|
|
25
|
+
*/
|
|
26
|
+
export declare class SMAAPass extends Pass {
|
|
27
|
+
private inner;
|
|
28
|
+
private scratch;
|
|
29
|
+
private blitMaterial;
|
|
30
|
+
private fullscreenRenderer;
|
|
31
|
+
private materialEdges;
|
|
32
|
+
private materialWeights;
|
|
33
|
+
private materialBlend;
|
|
34
|
+
constructor();
|
|
35
|
+
setSize(width: number, height: number): void;
|
|
36
|
+
dispose(): void;
|
|
37
|
+
render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
|
|
38
|
+
/** Resolution uniform helper kept for parity with other passes. */
|
|
39
|
+
get resolution(): Vector2;
|
|
40
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Camera, WebGLRenderer, WebGLRenderTarget } from 'three';
|
|
2
|
+
import { Pass } from '../Pass';
|
|
3
|
+
/**
|
|
4
|
+
* Temporal Anti-Aliasing pass (jittered accumulation) for use with the
|
|
5
|
+
* {@link RenderingPipeline}.
|
|
6
|
+
*
|
|
7
|
+
* Each frame the camera's projection is offset by a sub-pixel jitter from a
|
|
8
|
+
* Halton(2,3) sequence and the freshly rendered buffer is accumulated into a
|
|
9
|
+
* history target as a running average. Because the 1px-line problem with
|
|
10
|
+
* supersampling is that the line stays one device-pixel wide as the buffer
|
|
11
|
+
* grows, jittered accumulation is the technique that *does* anti-alias thin
|
|
12
|
+
* features: the same 1px line lands on slightly different sub-pixel positions
|
|
13
|
+
* each frame, so the average is coverage-weighted without thinning.
|
|
14
|
+
*
|
|
15
|
+
* The accumulation resets whenever the (un-jittered) camera view changes, so an
|
|
16
|
+
* orbit-and-inspect workflow converges to near-supersampled quality within a
|
|
17
|
+
* handful of static frames. Once the full jitter sequence has accumulated the
|
|
18
|
+
* pass freezes (no further jitter or blending) and presents the converged image
|
|
19
|
+
* until the next camera move, so a still camera settles to a stable result.
|
|
20
|
+
* Place it where you would place {@link FxaaPass} — before the {@link OutputPass}.
|
|
21
|
+
*
|
|
22
|
+
* Limitations (no history reprojection / neighbourhood clamping): animated
|
|
23
|
+
* content that moves while the camera is static (e.g. additive jet streams) does
|
|
24
|
+
* not update once the image has converged and frozen, and ghosts before then.
|
|
25
|
+
* Camera motion itself never ghosts because it triggers a reset.
|
|
26
|
+
*
|
|
27
|
+
* @todo Improve TAA. Current trade-offs to address: (1) AA is only present once
|
|
28
|
+
* the camera settles — during motion the image is un-anti-aliased and it takes
|
|
29
|
+
* roughly a second of stillness to converge; (2) because the pass freezes on
|
|
30
|
+
* convergence, content that changes while the camera is static (a highlight
|
|
31
|
+
* toggled on, async geometry finishing loading) does not appear until the next
|
|
32
|
+
* camera move. A proper fix needs motion vectors + history reprojection +
|
|
33
|
+
* neighbourhood colour clamping so the history can be reused under motion and
|
|
34
|
+
* invalidated per-pixel on content change, rather than the all-or-nothing
|
|
35
|
+
* reset-on-camera-move + freeze-on-convergence heuristic used here. Likely
|
|
36
|
+
* revisited as part of the WebGPU/TSL renderer migration.
|
|
37
|
+
*
|
|
38
|
+
* @group Rendering
|
|
39
|
+
* @see {@link RenderingPipeline}
|
|
40
|
+
* @see {@link FxaaPass}
|
|
41
|
+
* @see {@link SMAAPass}
|
|
42
|
+
*/
|
|
43
|
+
export declare class TAAPass extends Pass {
|
|
44
|
+
private camera;
|
|
45
|
+
/**
|
|
46
|
+
* Number of unique jitter samples to cycle through before the average is
|
|
47
|
+
* considered fully converged. Higher = smoother but slower to settle.
|
|
48
|
+
*/
|
|
49
|
+
sampleCount: number;
|
|
50
|
+
private historyRead;
|
|
51
|
+
private historyWrite;
|
|
52
|
+
private resolveMaterial;
|
|
53
|
+
private blitMaterial;
|
|
54
|
+
private fullscreenRenderer;
|
|
55
|
+
private width;
|
|
56
|
+
private height;
|
|
57
|
+
/** Index into the jitter sequence for the current frame. */
|
|
58
|
+
private sampleIndex;
|
|
59
|
+
/** How many frames have been accumulated since the last reset. */
|
|
60
|
+
private accumulated;
|
|
61
|
+
/** Jitter (in clip-space units) currently baked into the camera projection. */
|
|
62
|
+
private appliedJitterX;
|
|
63
|
+
private appliedJitterY;
|
|
64
|
+
/** Snapshot of the previous frame's camera state used to detect motion. The
|
|
65
|
+
* view matrix and the projection are stored separately so the two projection
|
|
66
|
+
* elements we jitter can be excluded from the comparison (see `detectMotion`). */
|
|
67
|
+
private prevView;
|
|
68
|
+
private prevProjection;
|
|
69
|
+
private hasPrev;
|
|
70
|
+
constructor(camera: Camera, sampleCount?: number);
|
|
71
|
+
setSize(width: number, height: number): void;
|
|
72
|
+
dispose(): void;
|
|
73
|
+
/** Force the accumulation to restart on the next frame. */
|
|
74
|
+
reset(): void;
|
|
75
|
+
/** Indices into the projection matrix offset elements for the active camera. */
|
|
76
|
+
private jitterElements;
|
|
77
|
+
private clearJitter;
|
|
78
|
+
private applyJitter;
|
|
79
|
+
/**
|
|
80
|
+
* Compare the current camera against the previous frame and reset the
|
|
81
|
+
* accumulation on any real view change (orbit, pan, zoom, fov).
|
|
82
|
+
*
|
|
83
|
+
* Motion is measured from the camera's view matrix (`matrixWorldInverse`,
|
|
84
|
+
* which we never touch) and its projection matrix *excluding* the two elements
|
|
85
|
+
* we jitter (`ex`/`ey`). This is critical: deriving motion from a quantity that
|
|
86
|
+
* includes our own sub-pixel jitter — or trying to subtract the jitter back out
|
|
87
|
+
* of the projection — couples the test to the jitter and makes every frame look
|
|
88
|
+
* like motion (the jitter delta dwarfs the tolerance), so the accumulation
|
|
89
|
+
* resets forever and the image never settles. By ignoring the jittered slots
|
|
90
|
+
* outright, only genuine camera changes trigger a reset.
|
|
91
|
+
*/
|
|
92
|
+
private detectMotion;
|
|
93
|
+
render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
|
|
94
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Object3D } from 'three';
|
|
2
|
+
import { StoreApi } from 'zustand/vanilla';
|
|
3
|
+
/**
|
|
4
|
+
* Transparency rendering mode currently active for a given scene/canvas.
|
|
5
|
+
*
|
|
6
|
+
* - `'standard'`: default rendering, as if no custom rendering pipeline is used.
|
|
7
|
+
* Components apply their default self-transparency workarounds.
|
|
8
|
+
* - `'oit'`: an order-independent-transparency pipeline (e.g. {@link OITRenderPass})
|
|
9
|
+
* is active. Components should disable workarounds that conflict with OIT (such as
|
|
10
|
+
* depth-only mask passes) and let the pipeline resolve transparency.
|
|
11
|
+
*/
|
|
12
|
+
export type TransparencyMode = 'standard' | 'oit';
|
|
13
|
+
/**
|
|
14
|
+
* Per-canvas rendering pipeline state.
|
|
15
|
+
*
|
|
16
|
+
* Lets components react to which rendering pipeline (if any) is active without the
|
|
17
|
+
* user having to manually configure each component. The defaults match the behavior
|
|
18
|
+
* of default rendering with no custom pipeline.
|
|
19
|
+
*
|
|
20
|
+
* @group Rendering
|
|
21
|
+
*/
|
|
22
|
+
export type RenderingState = {
|
|
23
|
+
/** The active transparency mode. Defaults to `'standard'`. */
|
|
24
|
+
transparencyMode: TransparencyMode;
|
|
25
|
+
/** @internal reference count of active OIT pipelines. */
|
|
26
|
+
_oitCount: number;
|
|
27
|
+
/**
|
|
28
|
+
* Register an active OIT pipeline. Sets {@link RenderingState.transparencyMode}
|
|
29
|
+
* to `'oit'`. Returns a release function that must be called when the pipeline is
|
|
30
|
+
* disposed; the mode reverts to `'standard'` once all registrations are released.
|
|
31
|
+
* Reference counted so multiple/short-lived passes behave correctly.
|
|
32
|
+
*/
|
|
33
|
+
acquireOit: () => () => void;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Get (or lazily create) the {@link RenderingState} store for a given scene.
|
|
37
|
+
*
|
|
38
|
+
* Both the rendering passes (which hold a reference to the scene) and the hooks used
|
|
39
|
+
* by components (which resolve the scene via R3F) call this with the same scene, so
|
|
40
|
+
* they share a single store instance per canvas. No provider is required — the store
|
|
41
|
+
* is created on first access, so components used without any pipeline still work and
|
|
42
|
+
* simply observe the `'standard'` default.
|
|
43
|
+
*
|
|
44
|
+
* @group Rendering
|
|
45
|
+
*/
|
|
46
|
+
export declare function getRenderingState(scene: Object3D): StoreApi<RenderingState>;
|
|
47
|
+
/**
|
|
48
|
+
* Hook to read the per-canvas {@link RenderingState}. Resolves the store from the
|
|
49
|
+
* current R3F scene, so it must be used inside a `Canvas`.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```tsx
|
|
53
|
+
* const isOit = useRenderingState(state => state.transparencyMode === 'oit');
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @group Hooks
|
|
57
|
+
* @category Rendering
|
|
58
|
+
*/
|
|
59
|
+
export declare function useRenderingState<T>(selector: (state: RenderingState) => T): T;
|
|
@@ -11,7 +11,9 @@ export * from './geometries/curve/curve-3d';
|
|
|
11
11
|
export * from './geometries/curve/tube-geometry';
|
|
12
12
|
export * from './geometries/delatin';
|
|
13
13
|
export * from './geometries/fence';
|
|
14
|
+
export * from './geometries/geometry';
|
|
14
15
|
export * from './geometries/packing';
|
|
16
|
+
export * from './geometries/planar-geometry';
|
|
15
17
|
export * from './geometries/triangulate-grid';
|
|
16
18
|
export * from './geometries/triangulate-grid-delaunay';
|
|
17
19
|
export * from './managers/CameraManager';
|
|
@@ -13,3 +13,26 @@ export declare function createNormalTexture(buffer: Uint8Array, width: number, h
|
|
|
13
13
|
* Create a data texture from RGBA encoded depth values
|
|
14
14
|
*/
|
|
15
15
|
export declare function createElevationTexture(buffer: Float32Array, width: number, height: number): DataTexture;
|
|
16
|
+
/**
|
|
17
|
+
* Compute geometric surface normals from an elevation grid, encoded as a compact
|
|
18
|
+
* RG8 buffer (2 bytes/texel) using a hemisphere encoding: only the grid-local
|
|
19
|
+
* `x` and `z` components are stored (mapped to [0, 1]); the consumer reconstructs
|
|
20
|
+
* `y = sqrt(1 - x^2 - z^2)`.
|
|
21
|
+
*
|
|
22
|
+
* This replicates the per-fragment normal that `SurfaceMaterial`'s shader derives
|
|
23
|
+
* from the elevation texture (same four diagonal neighbours, cross products and
|
|
24
|
+
* hole handling), but pays the cost once on the CPU instead of in every OIT pass.
|
|
25
|
+
* The result is laid out to match the elevation buffer (row-major, intended for a
|
|
26
|
+
* `flipY = true` texture), so it samples 1:1 with the same grid UVs.
|
|
27
|
+
*
|
|
28
|
+
* @param data elevation values (row-major, holes < 0)
|
|
29
|
+
* @param columns number of columns (nx)
|
|
30
|
+
* @param rows number of rows (ny)
|
|
31
|
+
* @param xScale column spacing (xinc)
|
|
32
|
+
* @param yScale row spacing (yinc)
|
|
33
|
+
*/
|
|
34
|
+
export declare function computeSurfaceNormalsRG(data: Float32Array, columns: number, rows: number, xScale: number, yScale: number): Uint8Array<ArrayBuffer>;
|
|
35
|
+
/**
|
|
36
|
+
* Create an RG8 data texture from a buffer produced by {@link computeSurfaceNormalsRG}.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createPackedNormalTexture(buffer: Uint8Array, width: number, height: number): DataTexture;
|
|
@@ -8,5 +8,8 @@ export declare const PI8: number;
|
|
|
8
8
|
* Given a 2D rectangle and an angle off the center, find the point
|
|
9
9
|
* of the closest corner. Used for anchoring connector lines
|
|
10
10
|
* to annotation labels.
|
|
11
|
+
*
|
|
12
|
+
* Pass an optional `target` array to write the result into, avoiding
|
|
13
|
+
* an allocation in hot paths.
|
|
11
14
|
*/
|
|
12
|
-
export declare function edgeOfRectangle(rect: Vec2, theta: number): Vec2;
|
|
15
|
+
export declare function edgeOfRectangle(rect: Vec2, theta: number, target?: Vec2): Vec2;
|