@equinor/videx-3d 2.0.0 → 3.1.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 (63) hide show
  1. package/dist/chunk-DKAquGKk.js +2820 -0
  2. package/dist/chunk-DsUZyEG_.js +16 -0
  3. package/dist/generators.js +512 -727
  4. package/dist/main.js +7182 -10552
  5. package/dist/sdk.js +2 -787
  6. package/dist/src/sdk/materials/shaderLib/procedural-normal.glsl +274 -0
  7. package/dist/types/components/Ocean/Ocean.d.ts +333 -0
  8. package/dist/types/components/Ocean/index.d.ts +6 -0
  9. package/dist/types/components/Ocean/ocean-bed-material.d.ts +60 -0
  10. package/dist/types/components/Ocean/ocean-contact.d.ts +39 -0
  11. package/dist/types/components/Ocean/ocean-material.d.ts +145 -0
  12. package/dist/types/components/Ocean/ocean-sampler.d.ts +93 -0
  13. package/dist/types/components/Ocean/ocean-volume-material.d.ts +54 -0
  14. package/dist/types/components/Tanker/Tanker.d.ts +47 -0
  15. package/dist/types/components/Tanker/TankerSuperstructure.d.ts +23 -0
  16. package/dist/types/components/Tanker/tanker-geometry-builder.d.ts +21 -0
  17. package/dist/types/components/Wellbores/Casings/CasingMaterial.d.ts +229 -1
  18. package/dist/types/components/Wellbores/Casings/CasingSection.d.ts +6 -1
  19. package/dist/types/components/Wellbores/Casings/Casings.d.ts +45 -4
  20. package/dist/types/components/Wellbores/Casings/casings-defs.d.ts +44 -0
  21. package/dist/types/components/Wellbores/Casings/index.d.ts +2 -1
  22. package/dist/types/main.d.ts +1 -0
  23. package/dist/types/rendering/Pass.d.ts +10 -1
  24. package/dist/types/rendering/RenderingPipeline.d.ts +10 -1
  25. package/dist/types/rendering/debug/DebugBoxOutputPass.d.ts +22 -0
  26. package/dist/types/rendering/debug/DebugPatternPass.d.ts +30 -0
  27. package/dist/types/rendering/fxaa-resolver.d.ts +25 -0
  28. package/dist/types/rendering/index.d.ts +1 -0
  29. package/dist/types/rendering/passes/AnnotationsPass.d.ts +1 -0
  30. package/dist/types/rendering/passes/FXAAPass.d.ts +11 -6
  31. package/dist/types/rendering/passes/OITRenderPass.d.ts +147 -0
  32. package/dist/types/rendering/passes/OutputPass.d.ts +9 -0
  33. package/dist/types/rendering/passes/RenderPass.d.ts +2 -0
  34. package/dist/types/rendering/passes/index.d.ts +0 -2
  35. package/dist/types/rendering/smaa-resolver.d.ts +58 -0
  36. package/dist/types/rendering/taa-resolver.d.ts +161 -0
  37. package/dist/types/rendering/temporal-resolver.d.ts +152 -0
  38. package/dist/types/sdk/geometries/boundary-loops.d.ts +38 -0
  39. package/dist/types/sdk/geometries/geometry-attributes.d.ts +37 -0
  40. package/dist/types/sdk/geometries/grid-sampling.d.ts +50 -0
  41. package/dist/types/sdk/geometries/ocean-geometry.d.ts +288 -0
  42. package/dist/types/sdk/geometries/packing.d.ts +1 -1
  43. package/dist/types/sdk/geometries/tessellation.d.ts +25 -0
  44. package/dist/types/sdk/index.d.ts +5 -0
  45. package/dist/types/sdk/utils/vector-operations.d.ts +7 -0
  46. package/package.json +11 -18
  47. package/dist/chunk-61X6qE5N.js +0 -981
  48. package/dist/chunk-ChG5d4HC.js +0 -675
  49. package/dist/chunk-DuRASjkF.js +0 -17
  50. package/dist/chunk-M-Pcc_Yg.js +0 -689
  51. package/dist/types/rendering/passes/SMAAPass.d.ts +0 -40
  52. package/dist/types/rendering/passes/TAAPass.d.ts +0 -94
  53. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/color-conversion.glsl +0 -0
  54. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/colors.glsl +0 -0
  55. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/glyphs.glsl +0 -0
  56. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/oit.glsl +0 -0
  57. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/random.glsl +0 -0
  58. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/remap.glsl +0 -0
  59. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/render-number.glsl +0 -0
  60. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/render-text.glsl +0 -0
  61. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/rotation.glsl +0 -0
  62. /package/dist/{shaderLib → src/sdk/materials/shaderLib}/sdf-functions.glsl +0 -0
  63. /package/dist/textures/{normal_map.jpg → public/normal_map.jpg} +0 -0
@@ -1,4 +1,5 @@
1
1
  import { PointerEvents } from '../../../main';
2
+ import { CasingEffects } from './CasingMaterial';
2
3
  import { CasingSectionMaterialOptions } from './Casings';
3
4
  import { CasingSectionType } from './casings-defs';
4
5
  type CasingSectionProps = {
@@ -11,6 +12,10 @@ type CasingSectionProps = {
11
12
  autoSlicePosition?: boolean;
12
13
  opacity?: number;
13
14
  renderOrder?: number;
15
+ effects?: CasingEffects;
16
+ wellLength?: number;
17
+ sectionIndex?: number;
18
+ schematic?: boolean;
14
19
  } & 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;
20
+ export declare const CasingSection: ({ section, materialOptions, radialSegments, sizeMultiplier, sliceAngle, sliceOffset, autoSlicePosition, opacity, renderOrder, effects, wellLength, sectionIndex, schematic, onPointerClick, onPointerEnter, onPointerLeave, onPointerMove, }: CasingSectionProps) => import("react/jsx-runtime").JSX.Element;
16
21
  export {};
@@ -1,16 +1,17 @@
1
1
  import { ReactElement } from 'react';
2
- import { Group, MeshStandardMaterialParameters, Object3D } from 'three';
2
+ import { Group, Object3D } from 'three';
3
3
  import { CommonComponentProps } from '../../../common/types';
4
4
  import { PointerEvents } from '../../../main';
5
+ import { CasingEffects, CasingMaterialParameters } from './CasingMaterial';
5
6
  import { CasingSectionType } from './casings-defs';
6
7
  /**
7
8
  * CasingSectionMaterialOptions
8
9
  * @expand
9
10
  */
10
11
  export type CasingSectionMaterialOptions = {
11
- primary: MeshStandardMaterialParameters;
12
- inner?: MeshStandardMaterialParameters;
13
- slice?: MeshStandardMaterialParameters;
12
+ primary: CasingMaterialParameters;
13
+ inner?: CasingMaterialParameters;
14
+ slice?: CasingMaterialParameters;
14
15
  };
15
16
  /**
16
17
  * MaterialOptions
@@ -31,9 +32,29 @@ export type CasingProps = PointerEvents & CommonComponentProps & {
31
32
  shoeFactor?: number;
32
33
  overrideSegmentsPerMeter?: number;
33
34
  overrideSimplificationThreshold?: number;
35
+ /** Schematic (diagram) mode: an unlit, flat-shaded look for a clean "cutaway
36
+ * schematic" rather than realism. Locks the slice to a half-cut that always faces
37
+ * the camera (`sliceAngle = PI`, `autoSlicePosition = true`, `sliceOffset = 0` -
38
+ * those props are ignored), renders each face with only its flat `color` (all
39
+ * lighting/env, textures and realism detail are ignored) plus the `silhouette`
40
+ * outline for contrast. Dropping the specular lighting also removes the dominant
41
+ * source of casing aliasing; note that geometric silhouette-edge anti-aliasing still
42
+ * relies on the host render pipeline (MSAA/FXAA/SMAA). Default false. */
43
+ schematic?: boolean;
44
+ /** Maps each section to its material parameters. Keep this a STABLE reference
45
+ * (module-level function or `useCallback`) - a new function identity each render
46
+ * rebuilds every section's materials and forces a shader recompile per frame,
47
+ * which is the main cause of sluggish casing updates. Defaults to a stable
48
+ * module-level function. */
34
49
  materialOptions?: MaterialOptions;
35
50
  opacity?: number;
36
51
  priority?: number;
52
+ /** Grouped casing stylization effects (silhouette outline, section edge shading,
53
+ * procedural weathering, per-section variation and micro-normal surface detail).
54
+ * Applied as the global default for every section; a section's per-face
55
+ * `materialOptions.*.effects` override individual sub-effects on top of this.
56
+ * Defaults to {@link defaultCasingEffects}. */
57
+ effects?: CasingEffects;
37
58
  };
38
59
  /**
39
60
  * Generic render of casings based on depths, diameters and type. Must be a child of the `Wellbore` component.
@@ -66,7 +87,27 @@ export declare const Casings: import('react').ForwardRefExoticComponent<PointerE
66
87
  shoeFactor?: number;
67
88
  overrideSegmentsPerMeter?: number;
68
89
  overrideSimplificationThreshold?: number;
90
+ /** Schematic (diagram) mode: an unlit, flat-shaded look for a clean "cutaway
91
+ * schematic" rather than realism. Locks the slice to a half-cut that always faces
92
+ * the camera (`sliceAngle = PI`, `autoSlicePosition = true`, `sliceOffset = 0` -
93
+ * those props are ignored), renders each face with only its flat `color` (all
94
+ * lighting/env, textures and realism detail are ignored) plus the `silhouette`
95
+ * outline for contrast. Dropping the specular lighting also removes the dominant
96
+ * source of casing aliasing; note that geometric silhouette-edge anti-aliasing still
97
+ * relies on the host render pipeline (MSAA/FXAA/SMAA). Default false. */
98
+ schematic?: boolean;
99
+ /** Maps each section to its material parameters. Keep this a STABLE reference
100
+ * (module-level function or `useCallback`) - a new function identity each render
101
+ * rebuilds every section's materials and forces a shader recompile per frame,
102
+ * which is the main cause of sluggish casing updates. Defaults to a stable
103
+ * module-level function. */
69
104
  materialOptions?: MaterialOptions;
70
105
  opacity?: number;
71
106
  priority?: number;
107
+ /** Grouped casing stylization effects (silhouette outline, section edge shading,
108
+ * procedural weathering, per-section variation and micro-normal surface detail).
109
+ * Applied as the global default for every section; a section's per-face
110
+ * `materialOptions.*.effects` override individual sub-effects on top of this.
111
+ * Defaults to {@link defaultCasingEffects}. */
112
+ effects?: CasingEffects;
72
113
  } & import('react').RefAttributes<Group<import('three').Object3DEventMap>>>;
@@ -1,4 +1,6 @@
1
+ import { Color } from 'three';
1
2
  import { Vec3 } from '../../../sdk';
3
+ import { CasingEffects } from './CasingMaterial';
2
4
  export declare const casings = "casings";
3
5
  export type CasingSectionType = {
4
6
  type: string;
@@ -15,3 +17,45 @@ export type CasingSectionType = {
15
17
  };
16
18
  };
17
19
  export type CasingsGeneratorResponse = CasingSectionType[];
20
+ /**
21
+ * The component-level default {@link CasingEffects} applied globally to every section
22
+ * (a section's per-face `materialOptions.*.effects` can override individual sub-effects
23
+ * on top of this). Tuned to help adjacent/nested strings read apart.
24
+ */
25
+ export declare const defaultCasingEffects: CasingEffects;
26
+ /**
27
+ * A custom function may be passed to the component, but this is not well documented at this time
28
+ * as this behavior is subject to change.
29
+ */
30
+ export declare const defaultMaterialOptions: (section: CasingSectionType) => {
31
+ primary: {
32
+ color: string;
33
+ roughness: number;
34
+ metalness: number;
35
+ effects: {
36
+ weathering: {
37
+ resistance: number;
38
+ };
39
+ };
40
+ };
41
+ inner: {
42
+ color: string;
43
+ roughness: number;
44
+ metalness: number;
45
+ };
46
+ slice: {
47
+ color: Color;
48
+ roughness: number;
49
+ metalness: number;
50
+ effects: {
51
+ weathering: {
52
+ resistance: number;
53
+ };
54
+ };
55
+ } | {
56
+ color: Color;
57
+ roughness: number;
58
+ metalness: number;
59
+ effects?: undefined;
60
+ };
61
+ };
@@ -1,5 +1,6 @@
1
+ export * from './CasingMaterial';
1
2
  export * from './Casings';
2
3
  export * from './casings-defs';
4
+ export * from './CasingAnnotations/casing-annotations-defs';
3
5
  export * from './CasingAnnotations/CasingAnnotations';
4
6
  export * from './CasingAnnotations/CasingLabel';
5
- export * from './CasingAnnotations/casing-annotations-defs';
@@ -9,6 +9,7 @@ export * from './components/Grids';
9
9
  export * from './components/Highlighter';
10
10
  export * from './components/Html';
11
11
  export * from './components/ObservableGroup/ObservableGroup';
12
+ export * from './components/Ocean';
12
13
  export * from './components/SDFTest/SDFTest';
13
14
  export * from './components/Surfaces';
14
15
  export * from './components/Symbol';
@@ -1,6 +1,15 @@
1
- import { WebGLRenderer, WebGLRenderTarget } from 'three';
1
+ import { Color, WebGLRenderer, WebGLRenderTarget } from 'three';
2
2
  export declare abstract class Pass {
3
3
  writeToScreen: boolean;
4
+ /**
5
+ * Explicit background for passes that clear the frame (e.g. {@link RenderPass} and
6
+ * the OIT opaque clear). When set, the pass clears to this colour/alpha instead of
7
+ * the renderer's current clear state, giving a single source of truth so the
8
+ * background is identical regardless of which base pass renders the scene. When
9
+ * `null` the pass falls back to the renderer's current clear colour/alpha.
10
+ */
11
+ clearColor: Color | null;
12
+ clearAlpha: number;
4
13
  setSize?(width: number, height: number, pixelRatio: number): void;
5
14
  dispose?(): void;
6
15
  abstract render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
@@ -6,7 +6,16 @@ import { Pass } from './Pass';
6
6
  export type RenderingPipelineProps = {
7
7
  /** Ordered list of passes to execute every frame. */
8
8
  passes: Pass[];
9
- /** Multisample count for the main render target. Defaults to 0. */
9
+ /**
10
+ * Multisample count (MSAA) for the main render target. Defaults to 0.
11
+ *
12
+ * This applies hardware MSAA to the pipeline's shared render target and is only
13
+ * meaningful for an opaque {@link RenderPass}-based pipeline. When the base pass
14
+ * is an {@link OITRenderPass}, keep this at `0`: OIT renders into its own
15
+ * multi-target buffers, so pipeline-level MSAA would add cost without
16
+ * anti-aliasing the resolved result. Use {@link OITRenderPass.opaqueSamples}
17
+ * instead to multisample the opaque sub-pass inside OIT.
18
+ */
10
19
  samples?: number;
11
20
  /** Render target supersampling factor. Defaults to 1. */
12
21
  supersample?: number;
@@ -0,0 +1,22 @@
1
+ import { RawShaderMaterial, WebGLRenderer, WebGLRenderTarget } from 'three';
2
+ import { FullscreenRenderer } from '../fullscreen-renderer';
3
+ import { Pass } from '../Pass';
4
+ /**
5
+ * Alternative output pass that performs an explicit NxN box downsample of the
6
+ * supersampled buffer straight to the screen. Intended purely as an A/B reference
7
+ * against the mipmap-based {@link OutputPass}: with the same scene/pattern and
8
+ * supersample factor, the only difference is the resample filter, which isolates
9
+ * whether the perceived aliasing comes from the downsample step.
10
+ *
11
+ * Tone mapping is not applied here (only sRGB / linear output encode), so pair it
12
+ * with tone mapping = none for a fair comparison. Story/debug only.
13
+ */
14
+ export declare class DebugBoxOutputPass extends Pass {
15
+ fullscreenRenderer: FullscreenRenderer;
16
+ material: RawShaderMaterial;
17
+ supersample: number;
18
+ constructor(supersample?: number);
19
+ setSize(width: number, height: number): void;
20
+ render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
21
+ dispose(): void;
22
+ }
@@ -0,0 +1,30 @@
1
+ import { RawShaderMaterial, WebGLRenderer, WebGLRenderTarget } from 'three';
2
+ import { FullscreenRenderer } from '../fullscreen-renderer';
3
+ import { Pass } from '../Pass';
4
+ /**
5
+ * Named test signals produced by {@link DebugPatternPass}.
6
+ * - `zonePlate` / `grid` / `checker`: high-frequency signals for anti-aliasing /
7
+ * supersampling / downsample inspection.
8
+ * - `gradient` / `colorBars` / `grayStep` / `grayCard`: known linear values for
9
+ * colour-space and tone-mapping verification.
10
+ */
11
+ export type DebugPattern = 'zonePlate' | 'grid' | 'checker' | 'gradient' | 'colorBars' | 'grayStep' | 'grayCard';
12
+ /**
13
+ * Debug pass that overwrites the shared pipeline buffer with a synthetic test
14
+ * signal (see {@link DebugPattern}). It writes *linear* values at the buffer's
15
+ * (supersampled) resolution, replacing scene geometry so the rest of the pipeline
16
+ * — supersample downsample, tone mapping and output colour-space encode — can be
17
+ * validated against a known input.
18
+ *
19
+ * Story/debug only — not part of the public rendering API.
20
+ */
21
+ export declare class DebugPatternPass extends Pass {
22
+ fullscreenRenderer: FullscreenRenderer;
23
+ material: RawShaderMaterial;
24
+ constructor(pattern?: DebugPattern, scale?: number);
25
+ set pattern(value: DebugPattern);
26
+ set scale(value: number);
27
+ setSize(width: number, height: number): void;
28
+ render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
29
+ dispose(): void;
30
+ }
@@ -0,0 +1,25 @@
1
+ import { WebGLRenderer, WebGLRenderTarget } from 'three';
2
+ /**
3
+ * Fast Approximate Anti-Aliasing (FXAA) resolver. A single-pass, purely spatial
4
+ * morphological technique: it estimates edge direction from local luma and blends
5
+ * along it. Very cheap, but softer than SMAA and — like all spatial techniques —
6
+ * unable to recover sub-pixel features (thin lines/tubes that fall between
7
+ * samples); those need supersampling or the temporal mode.
8
+ *
9
+ * It operates entirely in the pipeline's linear FP16 space: the shader detects
10
+ * edges with a cheap perceptual luma but blends the linear texels, so brightness
11
+ * is untouched, flat regions are an exact passthrough, and HDR values above 1 are
12
+ * preserved (no LDR clamp). Because the neighbourhood taps cannot read the same
13
+ * target being written, it resolves into a scratch target and blits the result
14
+ * back into the buffer in place.
15
+ */
16
+ export declare class FxaaResolver {
17
+ private scratch;
18
+ private fxaaMaterial;
19
+ private blitMaterial;
20
+ private fullscreenRenderer;
21
+ constructor();
22
+ setSize(width: number, height: number): void;
23
+ dispose(): void;
24
+ render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
25
+ }
@@ -6,3 +6,4 @@ export * from './Pass';
6
6
  export * from './passes';
7
7
  export * from './rendering-state';
8
8
  export * from './RenderingPipeline';
9
+ export type { SMAAQuality } from './smaa-resolver';
@@ -26,6 +26,7 @@ export declare class AnnotationsPass extends Pass {
26
26
  private occlusionChanged;
27
27
  connectorTargetFrameTime: number;
28
28
  connectorStretchSlack: number;
29
+ connectorRestStretch: number;
29
30
  constructor(camera: Camera, clock: Clock, pointer: Vector2, maxVisible?: number);
30
31
  updateAnnotationsData(buffer: Uint8Array): void;
31
32
  updateOverlayTexture(inViewSpace: AnnotationInstance[]): void;
@@ -1,11 +1,16 @@
1
1
  import { WebGLRenderer, WebGLRenderTarget } from 'three';
2
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();
3
+ /**
4
+ * Standalone FXAA post pass. Wraps a {@link FxaaResolver} and composites it in
5
+ * place into the shared pipeline buffer, so it works after any base pass
6
+ * ({@link RenderPass} or {@link OITRenderPass}) — unlike the OIT-internal SMAA /
7
+ * temporal modes it does not require order-independent transparency.
8
+ *
9
+ * Insert it between the base pass and the {@link OutputPass}:
10
+ * `[base, new FXAAPass(), new OutputPass()]`.
11
+ */
12
+ export declare class FXAAPass extends Pass {
13
+ private resolver;
9
14
  setSize(width: number, height: number): void;
10
15
  dispose(): void;
11
16
  render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
@@ -1,5 +1,8 @@
1
1
  import { Camera, Scene, WebGLRenderer, WebGLRenderTarget } from 'three';
2
2
  import { Pass } from '../Pass';
3
+ import { SMAAQuality } from '../smaa-resolver';
4
+ import { TaaResolver } from '../taa-resolver';
5
+ import { TemporalResolver } from '../temporal-resolver';
3
6
  /** Per-frame object counts for each classification, exposed for debugging. */
4
7
  export type OITRenderPassStats = {
5
8
  /** Plain opaque renderables (not OIT-capable, not overlay). */
@@ -81,6 +84,14 @@ export type OITRenderPassTimings = {
81
84
  /** Sum of the measured OIT segments above. */
82
85
  total: number;
83
86
  };
87
+ /**
88
+ * Built-in anti-aliasing mode for {@link OITRenderPass.antialias}. See that field for
89
+ * the per-mode description. Exported as the single source of truth so consumers
90
+ * (and Storybook arg types) can reference it instead of re-declaring the union.
91
+ *
92
+ * @group Rendering
93
+ */
94
+ export type OITAntialiasMode = 'none' | 'temporal' | 'smaa' | 'temporal-smaa' | 'taa' | 'fxaa';
84
95
  /**
85
96
  * Hybrid order-independent-transparency (OIT) render pass for use with the
86
97
  * {@link RenderingPipeline} (or any custom composer). Renders the nearest transparent
@@ -122,6 +133,106 @@ export declare class OITRenderPass extends Pass {
122
133
  * Useful for isolating tail behaviour and comparing against the hybrid result.
123
134
  */
124
135
  skipFront: boolean;
136
+ /**
137
+ * Number of MSAA samples (0 = off) for the hybrid multisample path. When > 0 the
138
+ * opaque geometry (including fully-opaque OIT occluders such as casings/completion
139
+ * tools), the emissive layer, the weighted-blended (WBOIT) tail composite, the exact
140
+ * front layer and the overlay are all rendered into ONE dedicated multisample target
141
+ * sharing the pipeline depth. The single-sample min-depth/accum aux targets read the
142
+ * opaque depth resolved on the first switch away from the multisample target; the
143
+ * final colour is resolved ONCE more and blitted into the single-sample pipeline
144
+ * buffer (~2 resolves total). This costs more than multisampling the opaque pass
145
+ * alone but far less than multisampling the whole half-float pipeline buffer
146
+ * (~4 resolves). Clamped to `renderer.capabilities.maxSamples`.
147
+ *
148
+ * **MSAA is not recommended with OIT.** The min-depth/accum aux buffers must be
149
+ * single-sample (WebGL2 cannot sample a multisample texture), so the transparent
150
+ * tail is composited single-sample over the multisample opaque edges. Opaque edges
151
+ * are matted against the cleared background before the transparent surfaces exist,
152
+ * and the single-sample composite cannot reconstruct per-sample coverage — so a
153
+ * background-coloured fringe survives along opaque and thin-line edges *over
154
+ * transparent surfaces*. This is structural and cannot be made clean here; only
155
+ * supersampling the whole composite (an {@link antialias} temporal mode, or the
156
+ * {@link RenderingPipeline} `supersample` prop) removes it.
157
+ *
158
+ * `opaqueSamples` is therefore intended only for the narrow **opaque-only** close-up
159
+ * (no transparent surfaces composited in front — e.g. a casing detail view), where
160
+ * the fringe cannot occur. For anything with transparent surfaces leave this at `0`
161
+ * and use {@link antialias} (temporal / SMAA / TAA / FXAA) or the
162
+ * {@link RenderingPipeline} `supersample` prop instead. (Pipeline-level `samples`
163
+ * does not anti-alias the OIT result either, and is only for a plain opaque
164
+ * `RenderPass` pipeline with no OIT.)
165
+ *
166
+ * Do not combine `opaqueSamples > 0` with an {@link antialias} temporal mode
167
+ * (`'temporal'`/`'temporal-smaa'`/`'taa'`): it is wasteful — the multisample colour
168
+ * is resolved first and the temporal resolver then runs on the already-resolved
169
+ * buffer, so you pay for MSAA rasterisation on top of temporal supersampling that
170
+ * already anti-aliases the same edges.
171
+ */
172
+ opaqueSamples: number;
173
+ /**
174
+ * Built-in anti-aliasing mode for the composited result.
175
+ *
176
+ * - `'none'`: no built-in AA. Pair with {@link opaqueSamples} (MSAA) for
177
+ * opaque-edge AA in an opaque-only close-up; transparent/additive edges stay
178
+ * un-anti-aliased, and MSAA leaves a background-coloured fringe over transparent
179
+ * surfaces (see {@link opaqueSamples}).
180
+ * - `'temporal'`: temporal supersampling (see {@link TemporalResolver}). The camera
181
+ * is sub-pixel jittered each frame and the composited frame is accumulated into a
182
+ * running average **while the camera is still**, converging to a genuinely
183
+ * supersampled image (thin trajectory lines, transparent-surface edges, contour
184
+ * lines and the additive highlight all anti-alias). There is no reprojection, so
185
+ * nothing ghosts; while the camera moves the current frame is shown un-jittered
186
+ * (the moving frame is not anti-aliased unless combined with SMAA or MSAA).
187
+ * - `'smaa'`: subpixel morphological AA (see {@link smaaQuality}) applied as a
188
+ * spatial post pass every frame. Anti-aliases moving frames too, but (like all
189
+ * morphological techniques) cannot recover sub-pixel features such as 1px lines
190
+ * that fall between samples.
191
+ * - `'temporal-smaa'`: both, mutually exclusive per frame — temporal accumulation
192
+ * while the camera is still (crisp, recovers sub-pixel detail) and SMAA while it
193
+ * moves. SMAA never softens the converged still image and only costs GPU time
194
+ * during motion.
195
+ * - `'taa'` (default): reprojected temporal anti-aliasing (see {@link TaaResolver}).
196
+ * Like `'temporal'` the camera is sub-pixel jittered, but the history is
197
+ * reprojected every frame using the nearest visible surface's depth (opaque
198
+ * hardware depth refined by the OIT front-layer depth), so anti-aliasing is
199
+ * retained *during* camera motion. Ghosting from additive/animated/disoccluded
200
+ * content is bounded by neighbourhood colour clamping. This is the recommended
201
+ * default for the OIT pipeline — it anti-aliases both still and moving frames.
202
+ * Use `'temporal'` instead if you need guaranteed ghost-free stills and don't
203
+ * mind losing motion AA.
204
+ * - `'fxaa'`: fast approximate AA (see {@link FxaaResolver}) applied as a single
205
+ * cheap spatial post pass every frame. Cheaper and softer than `'smaa'`, with no
206
+ * OIT or temporal coupling. Like all spatial techniques it cannot recover
207
+ * sub-pixel features. Also available as the standalone {@link FXAAPass} for
208
+ * non-OIT (plain `RenderPass`) setups.
209
+ *
210
+ * The jitter is applied to the shared camera only between this pass's own scene
211
+ * render and resolve, so it never leaks to later passes (annotations, picking).
212
+ * This is the OIT pipeline's high-quality AA. Non-OIT setups (plain `RenderPass`)
213
+ * should use MSAA instead.
214
+ */
215
+ antialias: OITAntialiasMode;
216
+ /**
217
+ * SMAA quality preset used by the `'smaa'` and `'temporal-smaa'` {@link antialias}
218
+ * modes (default `'high'`). Ignored by the other modes.
219
+ */
220
+ smaaQuality: SMAAQuality;
221
+ /**
222
+ * The temporal-supersampling resolver, exposed for debug/tuning (e.g. its
223
+ * `clampStrength` anti-ghost knob). Non-null only while {@link antialias} is
224
+ * `'temporal'` / `'temporal-smaa'` and after at least one frame has rendered (it is
225
+ * created lazily and recreated on a mode switch, resetting to defaults).
226
+ */
227
+ get temporalResolver(): TemporalResolver | null;
228
+ /**
229
+ * The reprojected-TAA resolver, exposed for debug/tuning (e.g. its
230
+ * `restClampStrength` / `restBoxGamma` / `restNeighbourhoodRadius` anti-ghost knobs).
231
+ * Non-null only while {@link antialias} is `'taa'` and after at least one frame has
232
+ * rendered (it is created lazily and recreated on a mode switch, resetting to
233
+ * defaults).
234
+ */
235
+ get taaResolver(): TaaResolver | null;
125
236
  /**
126
237
  * Optional feature (default off): after the transparent OIT passes, stamp depth
127
238
  * for transparent surfaces wherever their own alpha is at least
@@ -185,9 +296,28 @@ export declare class OITRenderPass extends Pass {
185
296
  */
186
297
  readonly resources: OITRenderPassResources;
187
298
  private fullscreenRenderer;
299
+ /** Lazily-created temporal-supersampling resolver, used when {@link antialias} is `'temporal'`. */
300
+ private temporal;
301
+ /**
302
+ * Lazily-created reprojected-TAA resolver, used when {@link antialias} is `'taa'`.
303
+ */
304
+ private taa;
305
+ /**
306
+ * Lazily-created SMAA spatial resolver, used when {@link antialias} is `'smaa'` or
307
+ * `'temporal-smaa'`.
308
+ */
309
+ private smaa;
310
+ /** Lazily-created FXAA spatial resolver, used when {@link antialias} is `'fxaa'`. */
311
+ private fxaa;
188
312
  private minDepthTarget;
189
313
  private accumTarget;
190
314
  private compositeMaterial;
315
+ /** Shared multisample target for the hybrid MSAA path (see {@link opaqueSamples}). */
316
+ private opaqueTarget;
317
+ /** Sample count the current opaqueTarget was built with (-1 = none yet). */
318
+ private opaqueTargetSamples;
319
+ /** Blit material: copy the resolved multisample colour into the buffer (no blending). */
320
+ private opaqueBlitMaterial;
191
321
  /** Lazily-created material for the debug-target thumbnails. */
192
322
  private debugMaterial;
193
323
  /** Lazily-created GPU timer, only when {@link profile} is first enabled. */
@@ -210,9 +340,24 @@ export declare class OITRenderPass extends Pass {
210
340
  private height;
211
341
  private depthFar;
212
342
  constructor(scene: Scene, camera: Camera);
343
+ /**
344
+ * Create or resize the shared multisample target, sharing the pipeline's depth
345
+ * texture so resolving writes the AA colour AND the resolved opaque depth the
346
+ * auxiliary OIT passes read. Recreated when sample count, size or shared depth
347
+ * texture changes.
348
+ */
349
+ private ensureOpaqueTarget;
350
+ private disposeOpaqueTarget;
213
351
  setSize(width: number, height: number): void;
214
352
  dispose(): void;
215
353
  private getEntry;
354
+ /**
355
+ * Whether an OIT entry is currently fully invisible (every OIT-capable material
356
+ * has opacity ≤ 0). Such objects are hidden from all passes — they contribute
357
+ * nothing to any render target, so rasterising them (even through the cheap aux
358
+ * passes) is pure waste.
359
+ */
360
+ private isEntryInvisible;
216
361
  /**
217
362
  * Traverse the scene once, classifying renderables into transparent-OIT,
218
363
  * plain-opaque, emissive (additive/glow) and always-on-top overlay sets.
@@ -251,6 +396,8 @@ export declare class OITRenderPass extends Pass {
251
396
  private static effectiveOpacity;
252
397
  /** Whether a material currently renders as fully opaque. */
253
398
  private static isMaterialOpaque;
399
+ /** Whether a material currently renders as fully invisible (opacity ≤ 0). */
400
+ private static isMaterialInvisible;
254
401
  /**
255
402
  * Whether an OIT entry is currently fully opaque (every OIT-capable material is
256
403
  * opaque). Such objects are drawn in the opaque pass as real occluders instead of
@@ -1,6 +1,15 @@
1
1
  import { MeshBasicMaterial, WebGLRenderer, WebGLRenderTarget } from 'three';
2
2
  import { FullscreenRenderer } from '../fullscreen-renderer';
3
3
  import { Pass } from '../Pass';
4
+ /**
5
+ * Terminal pass: composites the pipeline's linear HDR buffer to the screen and
6
+ * applies tone mapping + sRGB output encoding once, for the whole buffer, via
7
+ * `renderer.toneMapping` / `toneMappingExposure` (`toneMapped: true` below).
8
+ *
9
+ * Because tone mapping is deferred to this single pass, scene materials must render
10
+ * linear (`toneMapped: false`) or they double-tone-map, and the per-material
11
+ * `toneMapped = false` opt-out is not honored. See documents/oit-guide.md §7.
12
+ */
4
13
  export declare class OutputPass extends Pass {
5
14
  fullscreenRenderer: FullscreenRenderer;
6
15
  material: MeshBasicMaterial;
@@ -3,6 +3,8 @@ import { Pass } from '../Pass';
3
3
  export declare class RenderPass extends Pass {
4
4
  private scene;
5
5
  private camera;
6
+ /** Reused scratch for saving the renderer clear colour (no per-frame alloc). */
7
+ private prevClearColor;
6
8
  constructor(scene: Scene, camera: Camera);
7
9
  render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
8
10
  }
@@ -2,5 +2,3 @@ export * from './FXAAPass';
2
2
  export * from './OITRenderPass';
3
3
  export * from './OutputPass';
4
4
  export * from './RenderPass';
5
- export * from './SMAAPass';
6
- export * from './TAAPass';
@@ -0,0 +1,58 @@
1
+ import { WebGLRenderer, WebGLRenderTarget } from 'three';
2
+ /**
3
+ * Quality preset for SMAA. Higher presets lower the edge-detection threshold (so
4
+ * fainter edges are anti-aliased) and increase the orthogonal search distance (so
5
+ * longer near-horizontal/vertical edges are reconstructed). The underlying
6
+ * three-stdlib SMAA shaders do not implement the reference SMAA's diagonal search
7
+ * and corner rounding, so those are unaffected by the preset.
8
+ *
9
+ * @group Rendering
10
+ */
11
+ export type SMAAQuality = 'low' | 'medium' | 'high' | 'ultra';
12
+ /**
13
+ * Subpixel Morphological Anti-Aliasing (SMAA) resolver, used internally by
14
+ * {@link OITRenderPass} when its `antialias` mode is `'smaa'` or `'temporal-smaa'`.
15
+ * It detects edges by colour discontinuity and reconstructs anti-aliased
16
+ * silhouettes using precomputed area/search lookup tables, giving clean long edges
17
+ * with little detail blurring.
18
+ *
19
+ * It operates in linear space (the OIT buffer is linear FP16) but detects edges on
20
+ * an sRGB-encoded copy so the perceptual thresholds behave as intended; the blend
21
+ * and output stay linear, so brightness is untouched.
22
+ *
23
+ * This wraps the well-tested SMAA shaders and lookup textures from `three-stdlib`
24
+ * and drives the three sub-passes (edge detection, blend-weight calculation,
25
+ * neighbourhood blending) through a {@link FullscreenRenderer}, compositing the
26
+ * result back into the shared buffer in place.
27
+ *
28
+ * Like all morphological techniques it cannot recover sub-pixel features (e.g. 1px
29
+ * WebGL lines that fall between samples) — those are handled by the temporal
30
+ * supersampling mode while the camera is still.
31
+ */
32
+ export declare class SmaaResolver {
33
+ private inner;
34
+ private scratch;
35
+ private encoded;
36
+ private encodeMaterial;
37
+ private blitMaterial;
38
+ private fullscreenRenderer;
39
+ private materialEdges;
40
+ private materialWeights;
41
+ private materialBlend;
42
+ private _quality;
43
+ /** Reused scratch for saving the renderer clear colour each frame (no per-frame alloc). */
44
+ private prevClearColor;
45
+ constructor(quality?: SMAAQuality);
46
+ /**
47
+ * Quality preset (default `'high'`). Assigning it rewrites the edge-detection
48
+ * threshold and orthogonal search-distance shader defines and recompiles the two
49
+ * affected sub-pass programs. The recompile only happens when the value actually
50
+ * changes, so reading/writing the same value every frame is free.
51
+ */
52
+ get quality(): SMAAQuality;
53
+ set quality(value: SMAAQuality);
54
+ private applyQuality;
55
+ setSize(width: number, height: number): void;
56
+ dispose(): void;
57
+ render(renderer: WebGLRenderer, buffer: WebGLRenderTarget): void;
58
+ }