@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.
Files changed (47) hide show
  1. package/README.md +120 -120
  2. package/dist/chunk-61X6qE5N.js +981 -0
  3. package/dist/chunk-ChG5d4HC.js +675 -0
  4. package/dist/{chunk-BolRQZt9.js → chunk-M-Pcc_Yg.js} +22 -20
  5. package/dist/generators.js +271 -260
  6. package/dist/main.js +5185 -3434
  7. package/dist/sdk.js +492 -316
  8. package/dist/shaderLib/oit.glsl +106 -0
  9. package/dist/types/components/Annotations/AutoUpdate.d.ts +1 -1
  10. package/dist/types/components/Annotations/index.d.ts +2 -2
  11. package/dist/types/components/Annotations/types.d.ts +3 -1
  12. package/dist/types/components/Annotations/update-annotations.d.ts +10 -0
  13. package/dist/types/components/EventEmitter/EventEmitterContext.d.ts +2 -1
  14. package/dist/types/components/EventEmitter/index.d.ts +1 -0
  15. package/dist/types/components/EventEmitter/picking-helper.d.ts +25 -0
  16. package/dist/types/components/EventEmitter/picking-material.d.ts +8 -5
  17. package/dist/types/components/Surfaces/Surface.d.ts +8 -1
  18. package/dist/types/components/Surfaces/SurfaceMaterial.d.ts +3 -0
  19. package/dist/types/components/Surfaces/surface-defs.d.ts +1 -0
  20. package/dist/types/components/Wellbores/Casings/CasingEmitterMaterial.d.ts +16 -0
  21. package/dist/types/components/Wellbores/Casings/CasingSection.d.ts +3 -2
  22. package/dist/types/components/Wellbores/Casings/Casings.d.ts +3 -2
  23. package/dist/types/generators/surface-generator.d.ts +1 -1
  24. package/dist/types/layers/layers.d.ts +4 -0
  25. package/dist/types/rendering/OitMaterial.d.ts +59 -0
  26. package/dist/types/rendering/Pass.d.ts +7 -0
  27. package/dist/types/rendering/RenderingPipeline.d.ts +37 -0
  28. package/dist/types/rendering/fullscreen-renderer.d.ts +1 -0
  29. package/dist/types/rendering/gpu-timer.d.ts +46 -0
  30. package/dist/types/rendering/index.d.ts +7 -1
  31. package/dist/types/rendering/oit-material.d.ts +122 -0
  32. package/dist/types/{components/Annotations/annotations-renderer.d.ts → rendering/passes/AnnotationsPass.d.ts} +13 -4
  33. package/dist/types/rendering/passes/FXAAPass.d.ts +12 -0
  34. package/dist/types/rendering/passes/OITRenderPass.d.ts +282 -0
  35. package/dist/types/rendering/passes/OutputPass.d.ts +10 -0
  36. package/dist/types/rendering/passes/RenderPass.d.ts +8 -0
  37. package/dist/types/rendering/passes/SMAAPass.d.ts +40 -0
  38. package/dist/types/rendering/passes/TAAPass.d.ts +94 -0
  39. package/dist/types/rendering/passes/index.d.ts +6 -0
  40. package/dist/types/rendering/rendering-state.d.ts +59 -0
  41. package/dist/types/sdk/index.d.ts +2 -0
  42. package/dist/types/sdk/utils/elevation-map.d.ts +23 -0
  43. package/dist/types/sdk/utils/trigonometry.d.ts +4 -1
  44. package/package.json +1 -1
  45. package/dist/chunk-CnY6Tmof.js +0 -358
  46. package/dist/chunk-iY0wQ9Z6.js +0 -887
  47. package/dist/types/rendering/render-passes.d.ts +0 -16
@@ -0,0 +1,106 @@
1
+ // Order-independent transparency (OIT) shared shader chunk.
2
+ //
3
+ // Provides the uniforms and the per-pass output logic used by the OITRenderPass
4
+ // hybrid pipeline (exact depth-peeled front layer + weighted-blended OIT tail).
5
+ //
6
+ // Usage (library ShaderMaterials, GLSL1 / gl_FragColor):
7
+ // #include <this file> // brings uniforms + oitProcess()
8
+ // ...
9
+ // gl_FragColor = ...; // compute final straight (non-premultiplied) color
10
+ // #ifdef USE_OIT
11
+ // gl_FragColor = oitProcess(gl_FragColor);
12
+ // #endif
13
+ //
14
+ // The fragment shader must have `vViewPosition` (view-space position) available.
15
+ //
16
+ // Pass selection is driven by defines set on the per-pass variant materials:
17
+ // USE_OIT enables the whole block
18
+ // OIT_DEPTH_PASS min-depth pre-pass (writes linear view-space depth)
19
+ // OIT_FRONT_PASS exact front layer (alpha-over, discards tail fragments)
20
+ // (none of the above, USE_OIT only) => single-buffer weighted-blended OIT tail
21
+ //
22
+ // The WBOIT tail uses a single RGBA16F accumulation target with optical-depth
23
+ // weighting: each fragment contributes weight b = -ln(1 - alpha), so
24
+ // accum.rgb = sum(rgb * b), accum.a = sum(b).
25
+ // The composite recovers the weighted-average colour as accum.rgb / accum.a and the
26
+ // coverage as 1 - exp(-accum.a) = 1 - prod(1 - alpha) -- identical to a separate
27
+ // (ZERO, ONE_MINUS_SRC_COLOR) reveal pass, but without the extra rasterisation.
28
+ //
29
+ // The `oitSkipFront` uniform (1) disables front peeling so the tail pass keeps the
30
+ // front fragments too (debug: everything resolved through WBOIT).
31
+
32
+ #ifdef USE_OIT
33
+
34
+ uniform float oitDepthFar; // normalisation factor for view-space depth
35
+ uniform vec2 oitScreenSize; // render target size in pixels
36
+ uniform sampler2D oitMinDepthTexture; // per-pixel min linear depth (front layer)
37
+ uniform int oitSkipFront; // 1 = disable front peeling (debug: all WBOIT)
38
+ uniform float oitOcclusionThreshold; // occlusion-stamp pass: min alpha to write depth
39
+
40
+ // Process the straight (non-premultiplied) fragment color for the active pass.
41
+ vec4 oitProcess(vec4 color) {
42
+ #ifdef OIT_OCCLUSION_PASS
43
+ // Occlusion depth stamp: write depth only where this surface is opaque enough
44
+ // (its own alpha clears the threshold). Colour writes are disabled on the
45
+ // variant, so the returned colour is ignored; discarding skips the depth write.
46
+ // Lets sufficiently-opaque transparent surfaces occlude annotation labels even
47
+ // though they don't write depth in the regular OIT passes.
48
+ if(color.a < oitOcclusionThreshold)
49
+ discard;
50
+ return color;
51
+ #endif
52
+
53
+ // View-space linear depth, normalised. Independent of the (logarithmic) depth
54
+ // buffer encoding, so the partition is correct at any camera scale.
55
+ float linZ = abs(vViewPosition.z) / oitDepthFar;
56
+
57
+ #ifdef OIT_DEPTH_PASS
58
+
59
+ // Written into an R32F target with MinEquation blending => per-pixel minimum.
60
+ return vec4(linZ, 0.0, 0.0, 1.0);
61
+
62
+ #else
63
+
64
+ // Gradient-relative tolerance: only the surface that produced the per-pixel
65
+ // minimum qualifies as "front". A fixed epsilon would form a depth slab and let
66
+ // distinct surfaces grazing within it bleed into each other.
67
+ vec2 uv = gl_FragCoord.xy / oitScreenSize;
68
+ float minZ = texture2D(oitMinDepthTexture, uv).r;
69
+ // Depth-relative tolerance. The min-depth pre-pass and this pass rasterise the
70
+ // SAME geometry with the SAME vertex transform, so the genuine front fragment's
71
+ // linZ matches the stored minZ to near bit-exactness; a tiny epsilon suffices.
72
+ // Avoid fwidth(linZ) here: at self-overlap silhouettes the 2x2 derivative quads
73
+ // straddle the depth discontinuity between layers, so fwidth spikes and inflates
74
+ // the tolerance, misclassifying back-layer fragments as front (visible edges).
75
+ float tol = minZ * 1e-3 + 1e-6;
76
+ bool isFront = (linZ - minZ) <= tol;
77
+
78
+ #ifdef OIT_FRONT_PASS
79
+
80
+ // Exact front layer: keep only the nearest fragment, blended alpha-over.
81
+ if(!isFront)
82
+ discard;
83
+ return color;
84
+
85
+ #else
86
+
87
+ // Tail pass: exclude the front fragment (handled exactly by the front pass),
88
+ // unless front peeling is disabled (debug: every fragment goes through WBOIT).
89
+ if(isFront && oitSkipFront == 0)
90
+ discard;
91
+
92
+ float alpha = color.a;
93
+
94
+ // Optical-depth weight b = -ln(1 - alpha). Additive (ONE, ONE) blending then gives
95
+ // accum.rgb = sum(rgb * b), accum.a = sum(b). The composite reconstructs both the
96
+ // weighted-average colour (accum.rgb / accum.a) and the coverage
97
+ // (1 - exp(-accum.a) = 1 - prod(1 - alpha)) from this single buffer, so no separate
98
+ // reveal pass is needed. alpha is clamped below 1 to keep b finite.
99
+ float b = -log(1.0 - clamp(alpha, 0.0, 0.9999));
100
+ return vec4(color.rgb * b, b);
101
+
102
+ #endif // OIT_FRONT_PASS
103
+ #endif // OIT_DEPTH_PASS
104
+ }
105
+
106
+ #endif // USE_OIT
@@ -1,3 +1,3 @@
1
1
  export declare const AutoUpdate: ({ maxVisible }: {
2
2
  maxVisible: number;
3
- }) => null;
3
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,8 @@
1
1
  import { Vec3 } from '../../sdk';
2
2
  import { AnnotationProps } from './types';
3
+ export * from '../../rendering/passes/AnnotationsPass';
3
4
  export * from './Annotations';
4
- export * from './annotations-renderer';
5
5
  export * from './annotations-state';
6
6
  export * from './AnnotationsLayer';
7
7
  export * from './types';
8
- export declare const getAnnotationPosition: (annotation: AnnotationProps) => Vec3;
8
+ export declare const getAnnotationPosition: (annotation: AnnotationProps, target?: Vec3) => Vec3;
@@ -55,7 +55,7 @@ export type AnnotationInstanceState = {
55
55
  kill?: boolean;
56
56
  cooldown?: number;
57
57
  opacity?: number;
58
- labelWidht: number;
58
+ labelWidth: number;
59
59
  labelHeight: number;
60
60
  labelX?: number;
61
61
  labelY?: number;
@@ -68,6 +68,8 @@ export type AnnotationInstanceState = {
68
68
  _zIndex?: string;
69
69
  _transform?: string;
70
70
  _needsUpdate?: boolean;
71
+ _connPrevX?: number;
72
+ _connPrevY?: number;
71
73
  };
72
74
  export type AnnotationInstance = {
73
75
  id: string;
@@ -1,6 +1,16 @@
1
1
  import { Clock, PerspectiveCamera } from 'three';
2
2
  import { Vec2 } from '../../sdk';
3
3
  import { AnnotationInstance } from './types';
4
+ /**
5
+ * Activity flags updated by preprocessInstances each frame. Used by
6
+ * AnnotationsPass to skip the expensive post-process/overlay work when the
7
+ * scene is settled (camera static and no animations in progress).
8
+ */
9
+ export declare const annotationsActivity: {
10
+ animating: boolean;
11
+ positionChanged: boolean;
12
+ deltaTime: number;
13
+ };
4
14
  /**
5
15
  * PRE-PROCESS INSTANCES
6
16
  */
@@ -1,4 +1,4 @@
1
- import { Camera, Object3D } from 'three';
1
+ import { Camera, Material, Object3D } from 'three';
2
2
  import { Vec2, Vec3 } from '../../sdk';
3
3
  export type KeysPressed = {
4
4
  altKey: boolean;
@@ -22,6 +22,7 @@ export type Listener = {
22
22
  ref?: any;
23
23
  threshold?: number;
24
24
  handlers: Record<string, EventEmitterCallback>;
25
+ customMaterial?: Material;
25
26
  };
26
27
  export type Emitter = {
27
28
  source: Object3D;
@@ -1,3 +1,4 @@
1
1
  export * from './EventEmitter';
2
2
  export * from './EventEmitterContext';
3
3
  export * from './picking-helper';
4
+ export * from './picking-material';
@@ -19,7 +19,26 @@ export declare class PickingHelper {
19
19
  private _radius;
20
20
  private _pbo;
21
21
  private _buffer;
22
+ private _prevClearColor;
22
23
  private _material;
24
+ /**
25
+ * Dedicated camera used for the picking render so the shared scene camera is
26
+ * never mutated. `setViewOffset` rebuilds a camera's projection (it remaps the
27
+ * frustum to the tiny patch under the cursor), and that mutation would clobber
28
+ * any external modification of the real camera's projection — e.g. the
29
+ * sub-pixel jitter a TAA pass bakes in. Each pick this camera is `copy()`d from
30
+ * the real camera (which faithfully mirrors `matrixWorld`,
31
+ * `matrixWorldInverse`, the projection and all intrinsics) and the view offset
32
+ * is applied here instead. `matrixWorldAutoUpdate` is disabled so the renderer
33
+ * uses the copied world matrix verbatim rather than recomputing it.
34
+ */
35
+ private _camera;
36
+ private _listeners;
37
+ private _emitters;
38
+ private _mapStarts;
39
+ private _mapObjectIds;
40
+ private _objectMapLength;
41
+ private _objectMapCount;
23
42
  constructor(options?: {});
24
43
  private traverseObject;
25
44
  updateListeners: () => void;
@@ -27,6 +46,12 @@ export declare class PickingHelper {
27
46
  getListener: (id: number) => Listener | undefined;
28
47
  removeListener: (id: number) => void;
29
48
  render(pointer: Vector2, renderer: WebGLRenderer, scene: Scene, camera: PerspectiveCamera): Promise<PickResult>;
49
+ /**
50
+ * Locate the emitter owning a flat id via binary search. Emitter ranges are
51
+ * contiguous and sorted by start, so the owner is the rightmost entry whose
52
+ * start is `<= flatId`.
53
+ */
54
+ private findEmitterIndex;
30
55
  private pick;
31
56
  dispose(): void;
32
57
  }
@@ -1,11 +1,14 @@
1
- import { Camera, Object3D, Scene, ShaderMaterial, WebGLRenderer } from 'three';
1
+ import { Camera, Object3D, Scene, ShaderMaterial, Uniform, WebGLRenderer } from 'three';
2
2
  import { BufferGeometry } from 'three/webgpu';
3
- import { Emitter, Listener } from './EventEmitterContext';
3
+ export declare const pickingMaterialUniforms: {
4
+ emitterId: Uniform<number>;
5
+ side: Uniform<number>;
6
+ };
4
7
  export declare class PickingMaterial extends ShaderMaterial {
5
- listeners: Map<number, Listener>;
6
- emitters: Map<number, Emitter>;
7
- currentObjectMap: Array<number> | null;
8
8
  constructor();
9
9
  dispose(): void;
10
10
  onBeforeRender(_renderer: WebGLRenderer, _scene: Scene, _camera: Camera, _geometry: BufferGeometry, object: Object3D): void;
11
11
  }
12
+ export declare class CustomPickingMaterial extends PickingMaterial {
13
+ constructor(vertexShader?: string, uniforms?: Record<string, Uniform>);
14
+ }
@@ -28,6 +28,13 @@ export type SurfaceProps = CommonComponentProps & PointerEvents & {
28
28
  wireframe?: boolean;
29
29
  normalMap?: Texture;
30
30
  normalScale?: Vec2;
31
+ /**
32
+ * Precompute the surface normals into a compact texture instead of deriving
33
+ * them per-fragment from the elevation map. This skips the normal recompute
34
+ * the shader otherwise repeats across the order-independent transparency
35
+ * passes, at the cost of a little extra texture memory. Defaults to `false`.
36
+ */
37
+ precomputeNormals?: boolean;
31
38
  debug?: boolean;
32
39
  };
33
40
  /**
@@ -43,4 +50,4 @@ export type SurfaceProps = CommonComponentProps & PointerEvents & {
43
50
  *
44
51
  * @group Components
45
52
  */
46
- export declare const Surface: ({ meta, color, colorRamp, rampMin, rampMax, reverseRamp, useColorRamp, showContours, contoursInterval, contoursColorMode, contoursColorModeFactor, contoursThickness, contoursColor, opacity, priority, maxError, doubleSide, wireframe, normalMap, normalScale, name, userData, receiveShadow, castShadow, layers, position, renderOrder, visible, debug, onPointerClick, onPointerEnter, onPointerLeave, onPointerMove, }: SurfaceProps) => import("react/jsx-runtime").JSX.Element | null;
53
+ export declare const Surface: ({ meta, color, colorRamp, rampMin, rampMax, reverseRamp, useColorRamp, showContours, contoursInterval, contoursColorMode, contoursColorModeFactor, contoursThickness, contoursColor, opacity, priority, maxError, doubleSide, wireframe, normalMap, normalScale, precomputeNormals, name, userData, receiveShadow, castShadow, layers, position, renderOrder, visible, debug, onPointerClick, onPointerEnter, onPointerLeave, onPointerMove, }: SurfaceProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -20,6 +20,7 @@ export type SurfaceMaterialParameters = ShaderMaterialParameters & MeshLambertMa
20
20
  contoursColor?: string | number | Color;
21
21
  elevationTexture?: Texture;
22
22
  normalTexture?: Texture;
23
+ usePrecomputedNormals?: boolean;
23
24
  debug?: boolean;
24
25
  };
25
26
  /**
@@ -48,6 +49,8 @@ export declare class SurfaceMaterial extends ShaderMaterial {
48
49
  set showContours(value: any);
49
50
  get debug(): any;
50
51
  set debug(value: any);
52
+ get usePrecomputedNormals(): any;
53
+ set usePrecomputedNormals(value: any);
51
54
  dispose(): void;
52
55
  onBeforeCompile(): void;
53
56
  }
@@ -4,4 +4,5 @@ export declare const surfaceTextures = "surfaceTextures";
4
4
  export type SurfaceGeometryResponse = PackedBufferGeometry;
5
5
  export type SurfaceTexturesResponse = {
6
6
  elevationImageBuffer: Float32Array;
7
+ normalImageBuffer?: Uint8Array;
7
8
  };
@@ -0,0 +1,16 @@
1
+ import { CustomPickingMaterial } from '../../EventEmitter/picking-material';
2
+ export declare class CasingEmitterMaterial extends CustomPickingMaterial {
3
+ constructor();
4
+ get sizeMultiplier(): number;
5
+ set sizeMultiplier(v: number);
6
+ get radius(): number;
7
+ set radius(v: number);
8
+ get innerRadius(): number;
9
+ set innerRadius(v: number);
10
+ get sliceOffset(): number;
11
+ set sliceOffset(v: number);
12
+ get sliceAngle(): number;
13
+ set sliceAngle(v: number);
14
+ get autoSlicePosition(): boolean;
15
+ set autoSlicePosition(v: boolean);
16
+ }
@@ -1,3 +1,4 @@
1
+ import { PointerEvents } from '../../../main';
1
2
  import { CasingSectionMaterialOptions } from './Casings';
2
3
  import { CasingSectionType } from './casings-defs';
3
4
  type CasingSectionProps = {
@@ -10,6 +11,6 @@ type CasingSectionProps = {
10
11
  autoSlicePosition?: boolean;
11
12
  opacity?: number;
12
13
  renderOrder?: number;
13
- };
14
- export declare const CasingSection: ({ section, materialOptions, radialSegments, sizeMultiplier, sliceAngle, sliceOffset, autoSlicePosition, opacity, renderOrder, }: CasingSectionProps) => import("react/jsx-runtime").JSX.Element;
14
+ } & PointerEvents;
15
+ export declare const CasingSection: ({ section, materialOptions, radialSegments, sizeMultiplier, sliceAngle, sliceOffset, autoSlicePosition, opacity, renderOrder, onPointerClick, onPointerEnter, onPointerLeave, onPointerMove, }: CasingSectionProps) => import("react/jsx-runtime").JSX.Element;
15
16
  export {};
@@ -1,6 +1,7 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { Group, MeshStandardMaterialParameters, Object3D } from 'three';
3
3
  import { CommonComponentProps } from '../../../common/types';
4
+ import { PointerEvents } from '../../../main';
4
5
  import { CasingSectionType } from './casings-defs';
5
6
  /**
6
7
  * CasingSectionMaterialOptions
@@ -20,7 +21,7 @@ export type MaterialOptions = (section: CasingSectionType) => CasingSectionMater
20
21
  * Casing props
21
22
  * @expand
22
23
  */
23
- export type CasingProps = CommonComponentProps & {
24
+ export type CasingProps = PointerEvents & CommonComponentProps & {
24
25
  fallback?: () => ReactElement<Object3D>;
25
26
  radialSegments?: number;
26
27
  sliceAngle?: number;
@@ -55,7 +56,7 @@ export type CasingProps = CommonComponentProps & {
55
56
  *
56
57
  * @group Components
57
58
  */
58
- export declare const Casings: import('react').ForwardRefExoticComponent<CommonComponentProps & {
59
+ export declare const Casings: import('react').ForwardRefExoticComponent<PointerEvents & CommonComponentProps & {
59
60
  fallback?: () => ReactElement<Object3D>;
60
61
  radialSegments?: number;
61
62
  sliceAngle?: number;
@@ -1,4 +1,4 @@
1
1
  import { SurfaceTexturesResponse } from '../main';
2
2
  import { PackedBufferGeometry, ReadonlyStore } from '../sdk';
3
- export declare function generateSurfaceTexturesData(this: ReadonlyStore, id: string): Promise<SurfaceTexturesResponse | null>;
3
+ export declare function generateSurfaceTexturesData(this: ReadonlyStore, id: string, computeNormals?: boolean): Promise<SurfaceTexturesResponse | null>;
4
4
  export declare function generateSurfaceGeometry(this: ReadonlyStore, id: string, maxError?: number): Promise<PackedBufferGeometry | null>;
@@ -1,5 +1,9 @@
1
1
  import { Layers } from 'three';
2
2
  export declare const LAYERS: {
3
+ OIT_EXCLUDED: number;
4
+ FORCE_OPAQUE: number;
5
+ OVERLAY: number;
6
+ EMISSIVE: number;
3
7
  NOT_EMITTER: number;
4
8
  EMITTER: number;
5
9
  };
@@ -0,0 +1,59 @@
1
+ import { Side } from 'three';
2
+ /**
3
+ * Props for {@link OitMaterial}.
4
+ * @expand
5
+ */
6
+ export type OitMaterialProps = {
7
+ /**
8
+ * Force a specific `side` on the OIT variants (e.g. `DoubleSide`). Defaults to
9
+ * the material's own side.
10
+ */
11
+ side?: Side;
12
+ /**
13
+ * Names of custom uniform-container properties on the material to share by
14
+ * reference with the per-pass variants. Only needed for non-`ShaderMaterial`
15
+ * materials that read a custom uniforms object in `onBeforeCompile`.
16
+ */
17
+ shareUniforms?: string[];
18
+ /**
19
+ * Names of value properties (e.g. `color`, `metalness`) to keep live on the
20
+ * per-pass variants of a cloned built-in material. See
21
+ * {@link OitMaterialOptions.syncProperties}. Ignored for `ShaderMaterial`s
22
+ * (already live via shared uniforms).
23
+ */
24
+ syncProperties?: string[];
25
+ /**
26
+ * - `inject` (default): patch the material's shaders at compile time (stock or
27
+ * inline materials whose shader does not already include `oit.glsl`).
28
+ * - `attach`: the material's shader already `#include`s `oit.glsl` and calls
29
+ * `oitProcess` (library materials); only wire up the variant machinery.
30
+ */
31
+ mode?: 'inject' | 'attach';
32
+ };
33
+ /**
34
+ * A declarative helper that makes the material of its parent `mesh` participate in
35
+ * the {@link OITRenderPass} pipeline, so transparent inline materials are resolved
36
+ * order-independently instead of being treated as opaque occluders.
37
+ *
38
+ * Drop it in as a sibling of the material, inside the `mesh`:
39
+ *
40
+ * ```tsx
41
+ * <mesh geometry={geometry}>
42
+ * <shaderMaterial
43
+ * uniforms={uniforms}
44
+ * vertexShader={vertexShader}
45
+ * fragmentShader={fragmentShader}
46
+ * transparent
47
+ * />
48
+ * <OitMaterial side={DoubleSide} />
49
+ * </mesh>
50
+ * ```
51
+ *
52
+ * It renders an invisible, empty `object3D` purely to locate the parent mesh; the
53
+ * wiring is idempotent and a no-op outside the OIT pipeline.
54
+ *
55
+ * @group Rendering
56
+ * @see {@link makeOitCompatible}
57
+ * @see {@link attachOitVariants}
58
+ */
59
+ export declare function OitMaterial({ side, shareUniforms, syncProperties, mode, }: OitMaterialProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { WebGLRenderer, WebGLRenderTarget } from 'three';
2
+ export declare abstract class Pass {
3
+ writeToScreen: boolean;
4
+ setSize?(width: number, height: number, pixelRatio: number): void;
5
+ dispose?(): void;
6
+ abstract render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
7
+ }
@@ -0,0 +1,37 @@
1
+ import { Pass } from './Pass';
2
+ /**
3
+ * Props for the {@link RenderingPipeline} component.
4
+ * @expand
5
+ */
6
+ export type RenderingPipelineProps = {
7
+ /** Ordered list of passes to execute every frame. */
8
+ passes: Pass[];
9
+ /** Multisample count for the main render target. Defaults to 0. */
10
+ samples?: number;
11
+ /** Render target supersampling factor. Defaults to 1. */
12
+ supersample?: number;
13
+ /** Frame priority (passed to `useFrame`). Defaults to 1. */
14
+ priority?: number;
15
+ };
16
+ /**
17
+ * Generic render pipeline component that runs an ordered list of {@link Pass} objects
18
+ * against a shared `WebGLRenderTarget` (color + depth texture). Use it to compose
19
+ * custom rendering pipelines — e.g. a {@link OITRenderPass} based pipeline for
20
+ * order-independent transparency.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * const passes = useMemo(
25
+ * () => [new OITRenderPass(scene, camera), new OutputPass()],
26
+ * [scene, camera],
27
+ * );
28
+ * return <RenderingPipeline passes={passes} />;
29
+ * ```
30
+ *
31
+ * @group Components
32
+ * @category Rendering
33
+ * @see {@link Pass}
34
+ * @see {@link OITRenderPass}
35
+ * @see {@link OutputPass}
36
+ */
37
+ export declare const RenderingPipeline: ({ passes, samples, supersample, priority, }: RenderingPipelineProps) => null;
@@ -4,6 +4,7 @@ export declare class FullscreenRenderer {
4
4
  mesh: Mesh;
5
5
  copyMaterial: RawShaderMaterial;
6
6
  constructor();
7
+ dispose(): void;
7
8
  renderMaterial(renderer: WebGLRenderer, buffer: WebGLRenderTarget | null, material: Material): void;
8
9
  renderTexture(renderer: WebGLRenderer, buffer: WebGLRenderTarget | null, texture: Texture, opacity?: number): void;
9
10
  }
@@ -0,0 +1,46 @@
1
+ import { WebGLRenderer } from 'three';
2
+ /**
3
+ * Tiny GPU timer for WebGL2 built on `EXT_disjoint_timer_query_webgl2`.
4
+ *
5
+ * DEBUG-ONLY instrumentation: it brackets named, non-overlapping segments with
6
+ * `TIME_ELAPSED` queries and reads the results back asynchronously (a few frames
7
+ * later), reporting a smoothed millisecond figure per segment. Because the GPU runs
8
+ * behind the CPU, results are never available the same frame they are issued, so a
9
+ * small ring of queries per segment is kept in flight.
10
+ *
11
+ * Only one timer query can be active at a time per spec, so {@link begin}/{@link end}
12
+ * calls must be strictly sequential (never nested). All methods are no-ops when the
13
+ * extension is unavailable (older browsers, or the WebGPU renderer), so call sites
14
+ * can leave instrumentation in place unconditionally.
15
+ *
16
+ * This is measurement only — it issues no draws and mutates no render state — so it
17
+ * does not affect the rendered result and is safe to leave compiled in behind a flag.
18
+ *
19
+ * @group Rendering
20
+ */
21
+ export declare class GpuTimer {
22
+ private gl;
23
+ private ext;
24
+ private segments;
25
+ private pool;
26
+ private active;
27
+ private activeSeg;
28
+ /** Whether GPU timing is available in this context. */
29
+ get supported(): boolean;
30
+ constructor(renderer: WebGLRenderer);
31
+ /** Begin timing a segment. No-op if unsupported or another segment is active. */
32
+ begin(label: string): void;
33
+ /** End timing the current segment. */
34
+ end(): void;
35
+ /**
36
+ * Harvest finished queries and update the smoothed timings. Call once per frame
37
+ * (e.g. at the top of the host pass's render). Disjoint frames (GPU context
38
+ * disruption) are discarded.
39
+ */
40
+ poll(): void;
41
+ /** Smoothed elapsed milliseconds for a segment, or -1 if no result yet. */
42
+ get(label: string): number;
43
+ /** Snapshot of every segment's smoothed timing in milliseconds. */
44
+ snapshot(): Record<string, number>;
45
+ dispose(): void;
46
+ }
@@ -1,2 +1,8 @@
1
1
  export * from './fullscreen-renderer';
2
- export * from './render-passes';
2
+ export * from './gpu-timer';
3
+ export * from './oit-material';
4
+ export * from './OitMaterial';
5
+ export * from './Pass';
6
+ export * from './passes';
7
+ export * from './rendering-state';
8
+ export * from './RenderingPipeline';
@@ -0,0 +1,122 @@
1
+ import { IUniform, Material, ShaderMaterial, Side, Texture, Vector2 } from 'three';
2
+ /**
3
+ * The OIT render passes a material provides a variant for.
4
+ * - `depthMin`: min view-space linear depth pre-pass (front-layer detection)
5
+ * - `accum`: single-buffer weighted-blended OIT tail (b-weighted, carries coverage)
6
+ * - `front`: exact depth-peeled front layer (alpha-over)
7
+ * - `occlusion`: optional depth-only stamp that writes depth where the surface's own
8
+ * alpha clears `oitOcclusionThreshold` (used to occlude annotation labels). Off by
9
+ * default; its program is only compiled by Three when the pass actually renders it.
10
+ */
11
+ export type OitPass = 'depthMin' | 'accum' | 'front' | 'occlusion';
12
+ /** The set of per-pass variant materials used by the OITRenderPass. */
13
+ export type OitVariants = Record<OitPass, Material>;
14
+ /** The OIT uniforms shared across a material's variants and set by the pass. */
15
+ export type OitUniforms = {
16
+ oitDepthFar: IUniform<number>;
17
+ oitScreenSize: IUniform<Vector2>;
18
+ oitMinDepthTexture: IUniform<Texture | null>;
19
+ oitSkipFront: IUniform<number>;
20
+ oitOcclusionThreshold: IUniform<number>;
21
+ };
22
+ /**
23
+ * A material that can participate in the {@link OITRenderPass} hybrid pipeline.
24
+ * Implemented by library materials (via {@link attachOitVariants}) and by patched
25
+ * stock / user materials (via {@link makeOitCompatible}).
26
+ */
27
+ export interface OitCapableMaterial {
28
+ /** Returns the lazily-built per-pass variant materials (shared uniforms). */
29
+ getOitVariants(): OitVariants;
30
+ /** Returns the OIT uniforms object the pass updates each frame. */
31
+ getOitUniforms(): OitUniforms;
32
+ }
33
+ /** Options for making a material OIT-compatible. */
34
+ export type OitMaterialOptions = {
35
+ /**
36
+ * Force a specific `side` on all variants (e.g. `DoubleSide` for surfaces so back
37
+ * faces contribute to the tail). Defaults to the base material's side.
38
+ */
39
+ side?: Side;
40
+ /**
41
+ * Names of properties on the material that hold uniform containers (objects of
42
+ * `IUniform`) which should be shared *by reference* with each per-pass variant.
43
+ * `ShaderMaterial` variants already share `uniforms`, but non-`ShaderMaterial`
44
+ * materials are cloned, so any custom uniform object they read in
45
+ * `onBeforeCompile` (e.g. a `uniforms` field used for slicing) must be listed
46
+ * here for live per-frame updates to reach the variants.
47
+ */
48
+ shareUniforms?: string[];
49
+ /**
50
+ * Names of **value** properties to keep in sync from the base material onto the
51
+ * per-pass variants every frame. Only relevant for stock/built-in materials, whose
52
+ * variants are *cloned* and would otherwise snapshot their appearance at build time
53
+ * (`ShaderMaterial` variants share `uniforms` and are always live, so this is
54
+ * ignored for them).
55
+ *
56
+ * Restricted to value properties that do **not** affect the compiled program:
57
+ * - primitives (e.g. `metalness`, `roughness`, `emissiveIntensity`), and
58
+ * - copyable value objects with a `.copy()` method (e.g. `color`, `emissive` —
59
+ * `Color`; or `Vector2/3/4`), which are copied in place (no allocation, no
60
+ * recompile).
61
+ *
62
+ * Do **not** list program-affecting properties here (textures such as `map`,
63
+ * `vertexColors`, anything that toggles a shader `#define`) — changing those needs
64
+ * a recompile and is intentionally unsupported through this fast path. `opacity` is
65
+ * always kept live and need not be listed. Use {@link COMMON_OIT_SYNC_PROPS} for a
66
+ * sensible default set.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * makeOitCompatible(material, { syncProperties: ['color', 'metalness'] });
71
+ * // or spread the common set:
72
+ * makeOitCompatible(material, { syncProperties: [...COMMON_OIT_SYNC_PROPS] });
73
+ * ```
74
+ */
75
+ syncProperties?: string[];
76
+ };
77
+ /**
78
+ * A convenient default set of common appearance properties to pass as
79
+ * {@link OitMaterialOptions.syncProperties} so runtime changes (e.g. recoloring) are
80
+ * reflected through the OIT passes for cloned built-in materials. Properties not
81
+ * present on a given material are ignored.
82
+ *
83
+ * @group Rendering
84
+ */
85
+ export declare const COMMON_OIT_SYNC_PROPS: readonly ["color", "emissive", "emissiveIntensity", "metalness", "roughness"];
86
+ /** Type guard for {@link OitCapableMaterial}. */
87
+ export declare function isOitCapable(material: Material | null | undefined): material is Material & OitCapableMaterial;
88
+ /**
89
+ * Make a library `ShaderMaterial` OIT-capable. The material's fragment shader is
90
+ * expected to already `#include` `oit.glsl` and call `oitProcess(gl_FragColor)`
91
+ * guarded by `#ifdef USE_OIT` (a no-op in the default pipeline). This adds the OIT
92
+ * uniforms to the material and attaches the per-pass variant machinery.
93
+ *
94
+ * @param material - the library ShaderMaterial to extend
95
+ * @param options - optional overrides (e.g. `side`)
96
+ * @returns the same material, typed as {@link OitCapableMaterial}
97
+ *
98
+ * @group Rendering
99
+ * @see {@link makeOitCompatible}
100
+ */
101
+ export declare function attachOitVariants<T extends ShaderMaterial>(material: T, options?: OitMaterialOptions): T & OitCapableMaterial;
102
+ /**
103
+ * Make any stock Three.js material or user-authored material OIT-compatible by
104
+ * patching its shaders at compile time (via `onBeforeCompile`) to include the OIT
105
+ * logic, and attaching the per-pass variant machinery.
106
+ *
107
+ * Works with lit built-in materials (which provide `vViewPosition`) and with
108
+ * materials lacking it (e.g. `LineBasicMaterial`), in which case `vViewPosition` is
109
+ * injected automatically. All injected code is guarded by `#ifdef USE_OIT`, so the
110
+ * base program is unchanged outside the OIT pipeline.
111
+ *
112
+ * Note: targets materials compiled by Three.js (built-ins, `ShaderMaterial`). Raw
113
+ * `RawShaderMaterial` (no Three.js shader prelude) is not auto-patched.
114
+ *
115
+ * @param material - the material to patch
116
+ * @param options - optional overrides (e.g. `side`)
117
+ * @returns the same material, typed as {@link OitCapableMaterial}
118
+ *
119
+ * @group Rendering
120
+ * @see {@link attachOitVariants}
121
+ */
122
+ export declare function makeOitCompatible<T extends Material>(material: T, options?: OitMaterialOptions): T & OitCapableMaterial;