@react-three/fiber 10.0.0-alpha.4 → 10.0.0-canary.04087d8

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 (39) hide show
  1. package/dist/chunks/webgl.cjs +27 -0
  2. package/dist/chunks/webgl.mjs +11 -0
  3. package/dist/chunks/webgpu.cjs +37 -0
  4. package/dist/chunks/webgpu.mjs +21 -0
  5. package/dist/extension.cjs +13 -0
  6. package/dist/extension.d.cts +19 -0
  7. package/dist/extension.d.mts +19 -0
  8. package/dist/extension.d.ts +19 -0
  9. package/dist/extension.mjs +1 -0
  10. package/dist/index.cjs +97 -15367
  11. package/dist/index.d.cts +122 -3763
  12. package/dist/index.d.mts +122 -3763
  13. package/dist/index.d.ts +122 -3763
  14. package/dist/index.mjs +10 -15268
  15. package/dist/legacy.cjs +97 -15321
  16. package/dist/legacy.d.cts +115 -3763
  17. package/dist/legacy.d.mts +115 -3763
  18. package/dist/legacy.d.ts +115 -3763
  19. package/dist/legacy.mjs +14 -15225
  20. package/dist/shared/fiber.6b9jD03Q.d.mts +2925 -0
  21. package/dist/shared/fiber.B4_fPf4i.d.cts +48 -0
  22. package/dist/shared/fiber.Bkj8LWnk.d.ts +48 -0
  23. package/dist/shared/fiber.Bni-aPDD.cjs +16505 -0
  24. package/dist/shared/fiber.C2xW_v2C.mjs +371 -0
  25. package/dist/shared/fiber.CB0XkHB0.d.cts +812 -0
  26. package/dist/shared/fiber.CB0XkHB0.d.mts +812 -0
  27. package/dist/shared/fiber.CB0XkHB0.d.ts +812 -0
  28. package/dist/shared/fiber.CTwFJHqu.cjs +405 -0
  29. package/dist/shared/fiber.CUJMLlBv.d.mts +48 -0
  30. package/dist/shared/fiber.CwDuI1p8.mjs +16407 -0
  31. package/dist/shared/fiber.DYMtL-OI.d.cts +2925 -0
  32. package/dist/shared/fiber.rxFgA01i.d.ts +2925 -0
  33. package/dist/webgpu/index.cjs +100 -16207
  34. package/dist/webgpu/index.d.cts +120 -4092
  35. package/dist/webgpu/index.d.mts +120 -4092
  36. package/dist/webgpu/index.d.ts +120 -4092
  37. package/dist/webgpu/index.mjs +15 -16091
  38. package/package.json +11 -8
  39. package/readme.md +1 -1
@@ -0,0 +1,812 @@
1
+ import { FrameTimingState, FrameCallback as FrameCallback$1, SchedulerApi } from '@pmndrs/scheduler';
2
+ import * as THREE from 'three';
3
+ import { WebGLRenderer, WebGLRenderTarget, Color, ColorRepresentation } from 'three';
4
+ import * as React from 'react';
5
+ import * as ThreeWebGPU from 'three/webgpu';
6
+ import { WebGPURenderer, RenderTarget, CanvasTarget } from 'three/webgpu';
7
+ import { StoreApi } from 'zustand';
8
+ import { UseBoundStoreWithEqualityFn } from 'zustand/traditional';
9
+ import { uniform, nodeObject } from 'three/tsl';
10
+
11
+ //* Utility Types ==============================
12
+
13
+ type NonFunctionKeys<P> = { [K in keyof P]-?: P[K] extends Function ? never : K }[keyof P]
14
+ type Overwrite<P, O> = Omit<P, NonFunctionKeys<O>> & O
15
+ type Properties<T> = Pick<T, NonFunctionKeys<T>>
16
+ type Mutable<P> = { -readonly [K in keyof P]: P[K] }
17
+ type IsOptional<T> = undefined extends T ? true : false
18
+ type IsAllOptional<T extends any[]> = T extends [infer First, ...infer Rest]
19
+ ? IsOptional<First> extends true
20
+ ? IsAllOptional<Rest>
21
+ : false
22
+ : true
23
+
24
+ //* Camera Types ==============================
25
+
26
+ type ThreeCamera = (THREE.OrthographicCamera | THREE.PerspectiveCamera) & { manual?: boolean }
27
+
28
+ //* Act Type ==============================
29
+
30
+ type Act = <T = any>(cb: () => Promise<T>) => Promise<T>
31
+
32
+ //* Bridge & Block Types ==============================
33
+
34
+ type Bridge = React.FC<{ children?: React.ReactNode }>
35
+
36
+ type SetBlock = false | Promise<null> | null
37
+ type UnblockProps = { set: React.Dispatch<React.SetStateAction<SetBlock>>; children: React.ReactNode }
38
+
39
+ //* Object Map Type ==============================
40
+
41
+ /* Original version
42
+ export interface ObjectMap {
43
+ nodes: { [name: string]: THREE.Object3D }
44
+ materials: { [name: string]: THREE.Material }
45
+ meshes: { [name: string]: THREE.Mesh }
46
+ }
47
+ */
48
+ /* This version is an expansion found in a PR by itsdouges that seems abandoned but looks useful.
49
+ It allows expansion but falls back to the original shape. (deleted due to stale, but If it doesnt conflict
50
+ I will keep the use here)
51
+ https://github.com/pmndrs/react-three-fiber/commits/generic-object-map/
52
+ His description is:
53
+ The object map type is now generic and can optionally declare the available properties for nodes, materials, and meshes.
54
+ */
55
+ interface ObjectMap<
56
+ T extends { nodes?: string; materials?: string; meshes?: string } = {
57
+ nodes: string
58
+ materials: string
59
+ meshes: string
60
+ },
61
+ > {
62
+ nodes: Record<T['nodes'] extends string ? T['nodes'] : string, THREE.Object3D>
63
+ materials: Record<T['materials'] extends string ? T['materials'] : string, THREE.Material>
64
+ meshes: Record<T['meshes'] extends string ? T['meshes'] : string, THREE.Mesh>
65
+ }
66
+
67
+ //* Equality Config ==============================
68
+
69
+ interface EquConfig {
70
+ /** Compare arrays by reference equality a === b (default), or by shallow equality */
71
+ arrays?: 'reference' | 'shallow'
72
+ /** Compare objects by reference equality a === b (default), or by shallow equality */
73
+ objects?: 'reference' | 'shallow'
74
+ /** If true the keys in both a and b must match 1:1 (default), if false a's keys must intersect b's */
75
+ strict?: boolean
76
+ }
77
+
78
+ //* Disposable Type ==============================
79
+
80
+ interface Disposable {
81
+ type?: string
82
+ dispose?: () => void
83
+ }
84
+
85
+ //* Event-related Types =====================================
86
+
87
+ interface Intersection extends THREE.Intersection {
88
+ /** The event source (the object which registered the handler) */
89
+ eventObject: THREE.Object3D
90
+ }
91
+
92
+ type Camera = THREE.OrthographicCamera | THREE.PerspectiveCamera
93
+
94
+ interface IntersectionEvent<TSourceEvent> extends Intersection {
95
+ /** The event source (the object which registered the handler) */
96
+ eventObject: THREE.Object3D
97
+ /** An array of intersections */
98
+ intersections: Intersection[]
99
+ /** vec3.set(pointer.x, pointer.y, 0).unproject(camera) */
100
+ unprojectedPoint: THREE.Vector3
101
+ /** Normalized event coordinates */
102
+ pointer: THREE.Vector2
103
+ /** pointerId of the original event for multiple pointer events */
104
+ pointerId: number
105
+ /** Delta between first click and this event */
106
+ delta: number
107
+ /** The ray that pierced it */
108
+ ray: THREE.Ray
109
+ /** The camera that was used by the raycaster */
110
+ camera: Camera
111
+ /** stopPropagation will stop underlying handlers from firing */
112
+ stopPropagation: () => void
113
+ /** The original host event */
114
+ nativeEvent: TSourceEvent
115
+ /** If the event was stopped by calling stopPropagation */
116
+ stopped: boolean
117
+ }
118
+
119
+ type ThreeEvent<TEvent> = IntersectionEvent<TEvent> & Properties<TEvent>
120
+ type DomEvent = PointerEvent | MouseEvent | WheelEvent
121
+
122
+ /** DOM event handlers registered on the canvas element */
123
+ interface Events {
124
+ onClick: EventListener
125
+ onContextMenu: EventListener
126
+ onDoubleClick: EventListener
127
+ onWheel: EventListener
128
+ onPointerDown: EventListener
129
+ onPointerUp: EventListener
130
+ onPointerLeave: EventListener
131
+ onPointerMove: EventListener
132
+ onPointerCancel: EventListener
133
+ onLostPointerCapture: EventListener
134
+ onDragEnter: EventListener
135
+ onDragLeave: EventListener
136
+ onDragOver: EventListener
137
+ onDrop: EventListener
138
+ }
139
+
140
+ /** Event handlers that can be attached to R3F objects (meshes, groups, etc.) */
141
+ interface EventHandlers {
142
+ onClick?: (event: ThreeEvent<MouseEvent>) => void
143
+ onContextMenu?: (event: ThreeEvent<MouseEvent>) => void
144
+ onDoubleClick?: (event: ThreeEvent<MouseEvent>) => void
145
+ /** Fires continuously while dragging over the object */
146
+ onDragOver?: (event: ThreeEvent<DragEvent>) => void
147
+ /** Fires once when drag enters the object */
148
+ onDragOverEnter?: (event: ThreeEvent<DragEvent>) => void
149
+ /** Fires once when drag leaves the object */
150
+ onDragOverLeave?: (event: ThreeEvent<DragEvent>) => void
151
+ /** Fires when drag misses this object (for objects that have drag handlers) */
152
+ onDragOverMissed?: (event: DragEvent) => void
153
+ /** Fires when a drop occurs on this object */
154
+ onDrop?: (event: ThreeEvent<DragEvent>) => void
155
+ /** Fires when a drop misses this object (for objects that have drop handlers) */
156
+ onDropMissed?: (event: DragEvent) => void
157
+ onPointerUp?: (event: ThreeEvent<PointerEvent>) => void
158
+ onPointerDown?: (event: ThreeEvent<PointerEvent>) => void
159
+ onPointerOver?: (event: ThreeEvent<PointerEvent>) => void
160
+ onPointerOut?: (event: ThreeEvent<PointerEvent>) => void
161
+ onPointerEnter?: (event: ThreeEvent<PointerEvent>) => void
162
+ onPointerLeave?: (event: ThreeEvent<PointerEvent>) => void
163
+ onPointerMove?: (event: ThreeEvent<PointerEvent>) => void
164
+ onPointerMissed?: (event: MouseEvent) => void
165
+ onPointerCancel?: (event: ThreeEvent<PointerEvent>) => void
166
+ onWheel?: (event: ThreeEvent<WheelEvent>) => void
167
+ onLostPointerCapture?: (event: ThreeEvent<PointerEvent>) => void
168
+
169
+ //* Visibility Events --------------------------------
170
+ /** Fires when object enters/exits camera frustum. Receives true when in view, false when out. */
171
+ onFramed?: (inView: boolean) => void
172
+ /** Fires when object occlusion state changes (WebGPU only, requires occlusionTest=true on object) */
173
+ onOccluded?: (occluded: boolean) => void
174
+ /** Fires when combined visibility changes (frustum + occlusion + visible prop) */
175
+ onVisible?: (visible: boolean) => void
176
+ }
177
+
178
+ type FilterFunction = (items: THREE.Intersection[], state: RootState) => THREE.Intersection[]
179
+ type ComputeFunction = (event: DomEvent, root: RootState, previous?: RootState) => void
180
+
181
+ /** Configuration for XR pointer registration (controllers/hands) */
182
+ interface XRPointerConfig {
183
+ /** Ray origin (updated each frame by XR system) */
184
+ ray: THREE.Ray
185
+ /** Optional: custom compute function for this pointer */
186
+ compute?: (state: RootState) => void
187
+ /** Pointer type identifier */
188
+ type: 'controller' | 'hand' | 'gaze'
189
+ /** Which hand (for controller/hand types) */
190
+ handedness?: 'left' | 'right'
191
+ }
192
+
193
+ interface EventManager<TTarget> {
194
+ /** Determines if the event layer is active */
195
+ enabled: boolean
196
+ /** Event layer priority, higher prioritized layers come first and may stop(-propagate) lower layer */
197
+ priority: number
198
+ /** The compute function needs to set up the raycaster and an xy- pointer */
199
+ compute?: ComputeFunction
200
+ /** The filter can re-order or re-structure the intersections */
201
+ filter?: FilterFunction
202
+ /** The target node the event layer is tied to */
203
+ connected?: TTarget
204
+ /** All the pointer event handlers through which the host forwards native events */
205
+ handlers?: Events
206
+ /** Allows re-connecting to another target */
207
+ connect?: (target: TTarget) => void
208
+ /** Removes all existing events handlers from the target */
209
+ disconnect?: () => void
210
+ /** Triggers a onPointerMove with the last known event. This can be useful to enable raycasting without
211
+ * explicit user interaction, for instance when the camera moves a hoverable object underneath the cursor.
212
+ * @param pointerId - Optional pointer ID to update specific pointer only
213
+ */
214
+ update?: (pointerId?: number) => void
215
+ /** Defer pointer move raycasting to frame start (default: true) */
216
+ frameTimedRaycasts?: boolean
217
+ /** Always fire raycaster immediately on scroll events (default: true) */
218
+ alwaysFireOnScroll?: boolean
219
+ /** Automatically re-raycast every frame to detect hover changes from moving objects/camera (default: false) */
220
+ updateOnFrame?: boolean
221
+ /** Flush deferred pointer raycasts. Called by scheduler at frame start (input phase). */
222
+ flush?: () => void
223
+ /** Register an XR pointer (controller/hand). Returns assigned pointerId */
224
+ registerPointer?: (config: XRPointerConfig) => number
225
+ /** Unregister an XR pointer */
226
+ unregisterPointer?: (pointerId: number) => void
227
+ }
228
+
229
+ interface PointerCaptureTarget {
230
+ intersection: Intersection
231
+ target: Element
232
+ }
233
+
234
+ //* Visibility System Types =====================================
235
+
236
+ /** Entry in the visibility registry for tracking object visibility state */
237
+ interface VisibilityEntry {
238
+ object: THREE.Object3D
239
+ handlers: Pick<EventHandlers, 'onFramed' | 'onOccluded' | 'onVisible'>
240
+ lastFramedState: boolean | null
241
+ lastOccludedState: boolean | null
242
+ lastVisibleState: boolean | null
243
+ }
244
+
245
+ //* Scheduler Types (useFrame) ==============================
246
+ //
247
+ // The generic, framework-agnostic scheduler types now live in @pmndrs/scheduler.
248
+ // This file re-exports them and layers r3f's RootState-aware frame state on top,
249
+ // so existing `#types` imports across the codebase keep resolving unchanged.
250
+
251
+
252
+
253
+ // Frame State (r3f-specific) --------------------------------
254
+
255
+ /**
256
+ * State passed to useFrame callbacks (extends RootState with timing).
257
+ */
258
+ interface FrameNextState extends RootState, FrameTimingState {}
259
+
260
+ /** Alias for FrameNextState */
261
+ type FrameState = FrameNextState
262
+
263
+ // Callback Types (r3f-specific) --------------------------------
264
+
265
+ /**
266
+ * Callback function for useFrame. Receives the full r3f RootState plus timing.
267
+ */
268
+ type FrameNextCallback = FrameCallback$1<RootState>
269
+
270
+ /** Alias for FrameNextCallback */
271
+ type FrameCallback = FrameNextCallback
272
+
273
+ //* Renderer Support ==============================
274
+ // Core has no static imports from `three` or `three/webgpu`. Both are separate bundles built on one
275
+ // shared `three.core.js`, and there is no import that gives you the core alone -- so a core that
276
+ // statically imported either one would put that renderer into every app's eager graph. Instead each
277
+ // renderer is described by a *support* object, loaded when a root needs it, that carries the three
278
+ // namespace of its flavour plus the handful of renderer-specific classes core touches by name.
279
+
280
+ /** The Three.js namespace of either flavour. Classes in three's shared core are the same objects in both. */
281
+ type ThreeNamespace = typeof THREE | typeof ThreeWebGPU
282
+
283
+ /**
284
+ * Three's shared core: every export `three` and `three/webgpu` have in common (`Vector3`, `Scene`,
285
+ * `Mesh`, the constants, ...). This is what core code reads from `getThree()`. The renderer-specific
286
+ * exports are reached through the flavour's support object, never by name from here.
287
+ */
288
+ type ThreeCore = Pick<typeof THREE, Extract<keyof typeof THREE, keyof typeof ThreeWebGPU>>
289
+
290
+ /** Node classes and TSL functions the occlusion observer is built from (WebGPU only). */
291
+ interface OcclusionSupport {
292
+ Node: typeof ThreeWebGPU.Node
293
+ NodeUpdateType: typeof ThreeWebGPU.NodeUpdateType
294
+ MeshBasicNodeMaterial: typeof ThreeWebGPU.MeshBasicNodeMaterial
295
+ uniform: typeof uniform
296
+ nodeObject: typeof nodeObject
297
+ }
298
+
299
+ /** WebGL renderer support: the `three` namespace and the classes only it exports. */
300
+ interface WebGLSupport {
301
+ kind: 'webgl'
302
+ /** `import * as THREE from 'three'`: JSX constructors for roots on this renderer, and core's classes. */
303
+ three: typeof THREE
304
+ Renderer: typeof THREE.WebGLRenderer
305
+ /** Render target for `useRenderTarget`. */
306
+ RenderTarget: typeof THREE.WebGLRenderTarget
307
+ /** Cube render target for `<Environment>`. */
308
+ CubeRenderTarget: typeof THREE.WebGLCubeRenderTarget
309
+ }
310
+
311
+ /** WebGPU renderer support: the `three/webgpu` namespace and the classes only it exports. */
312
+ interface WebGPUSupport {
313
+ kind: 'webgpu'
314
+ /** `import * as THREE from 'three/webgpu'`: JSX constructors (node materials included) and core's classes. */
315
+ three: typeof ThreeWebGPU
316
+ Renderer: typeof ThreeWebGPU.WebGPURenderer
317
+ /** Render target for `useRenderTarget`. */
318
+ RenderTarget: typeof ThreeWebGPU.RenderTarget
319
+ /** Cube render target for `<Environment>`. */
320
+ CubeRenderTarget: typeof ThreeWebGPU.CubeRenderTarget
321
+ /** Canvas target for secondary canvases sharing a primary's renderer. */
322
+ CanvasTarget: typeof ThreeWebGPU.CanvasTarget
323
+ occlusion: OcclusionSupport
324
+ }
325
+
326
+ /** Support for the renderer a root ended up with. Selected by `configure()`, kept on `state.internal.support`. */
327
+ type RendererSupport = WebGLSupport | WebGPUSupport
328
+
329
+ /**
330
+ * What an entry point hands to `createRoot`/`Canvas`: a loader per renderer it can construct.
331
+ *
332
+ * The root entry provides both as dynamic imports, so an app downloads only the renderer its
333
+ * Canvas asks for. `/legacy` and `/webgpu` provide one each, statically, for apps that would rather
334
+ * have no extra request than the choice.
335
+ */
336
+ interface RendererProvider {
337
+ webgl?: () => WebGLSupport | Promise<WebGLSupport>
338
+ webgpu?: () => WebGPUSupport | Promise<WebGPUSupport>
339
+ }
340
+
341
+ //* Register ==============================
342
+ // The root entry can construct either renderer, so by default `state.renderer` is the union of
343
+ // both and a WebGPU-only member (`renderer.compute`, `renderer.backend`) needs a narrow. An app that
344
+ // has decided on one renderer says so once, and every renderer-typed field follows -- `useThree`,
345
+ // `useFrame`, `onCreated`, `useRenderTarget`, `state.internal.support`:
346
+ //
347
+ // declare module '@react-three/fiber' {
348
+ // interface Register {
349
+ // renderer: 'webgpu'
350
+ // }
351
+ // }
352
+ //
353
+ // Same pattern as `Register` in @react-three/tsl (and TanStack Router). Nothing registered means
354
+ // the union, unchanged. The `/legacy` and `/webgpu` entries are the same thing decided by import
355
+ // path; this is for apps on `@react-three/fiber` that want the narrowed types without changing it.
356
+
357
+ /**
358
+ * Augment this to type `RootState` for the renderer your app uses. Recognised keys:
359
+ * - `renderer`: `'webgpu'` or `'webgl'`
360
+ */
361
+ interface Register {}
362
+
363
+ /** The registered renderer, or `'any'` when nothing is registered. */
364
+ type RegisteredRenderer = Register extends { renderer: infer R extends 'webgl' | 'webgpu' } ? R : 'any'
365
+
366
+ /** Pick the type for the registered renderer: WebGPU, WebGL, or both when nothing is registered. */
367
+ type ForRegisteredRenderer<WebGPU, WebGL, Either = WebGPU | WebGL> = RegisteredRenderer extends 'webgpu'
368
+ ? WebGPU
369
+ : RegisteredRenderer extends 'webgl'
370
+ ? WebGL
371
+ : Either
372
+
373
+ /** The renderer type of `state.renderer`: a union of both unless one is registered. */
374
+ type R3FRenderer = ForRegisteredRenderer<WebGPURenderer, WebGLRenderer>
375
+
376
+ /** What `useRenderTarget` returns: a union of both target classes unless a renderer is registered. */
377
+ type R3FRenderTarget = ForRegisteredRenderer<RenderTarget, WebGLRenderTarget>
378
+
379
+ /** The renderer support on `state.internal.support`, narrowed to the registered renderer. */
380
+ type R3FRendererSupport = ForRegisteredRenderer<WebGPUSupport, WebGLSupport, RendererSupport>
381
+
382
+ //* Core Store Types ========================================
383
+
384
+ type Subscription = {
385
+ ref: React.RefObject<RenderCallback>
386
+ priority: number
387
+ store: RootStore
388
+ }
389
+
390
+ /** Per-pointer state for multi-touch and XR support */
391
+ type PointerState = {
392
+ /** Objects currently hovered by this pointer */
393
+ hovered: Map<string, ThreeEvent<DomEvent>>
394
+ /** Objects capturing this pointer */
395
+ captured: Map<THREE.Object3D, PointerCaptureTarget>
396
+ /** Initial click position [x, y] */
397
+ initialClick: [x: number, y: number]
398
+ /** Objects hit on initial click */
399
+ initialHits: THREE.Object3D[]
400
+ }
401
+
402
+ type Dpr = number | [min: number, max: number]
403
+
404
+ interface Size {
405
+ width: number
406
+ height: number
407
+ top: number
408
+ left: number
409
+ }
410
+
411
+ type Frameloop = 'always' | 'demand' | 'never'
412
+
413
+ interface Viewport extends Size {
414
+ /** The initial pixel ratio */
415
+ initialDpr: number
416
+ /** Current pixel ratio */
417
+ dpr: number
418
+ /** size.width / viewport.width */
419
+ factor: number
420
+ /** Camera distance */
421
+ distance: number
422
+ /** Camera aspect ratio: width / height */
423
+ aspect: number
424
+ }
425
+
426
+ type RenderCallback = (state: RootState, delta: number, frame?: XRFrame) => void
427
+
428
+ interface Performance {
429
+ /** Current performance normal, between min and max */
430
+ current: number
431
+ /** How low the performance can go, between 0 and max */
432
+ min: number
433
+ /** How high the performance can go, between min and max */
434
+ max: number
435
+ /** Time until current returns to max in ms */
436
+ debounce: number
437
+ /** Sets current to min, puts the system in regression */
438
+ regress: () => void
439
+ }
440
+
441
+ interface InternalState {
442
+ interaction: THREE.Object3D[]
443
+ subscribers: Subscription[]
444
+ /** Per-pointer state (hover, capture, click tracking) - replaces hovered, capturedMap, initialClick, initialHits */
445
+ pointerMap: Map<number, PointerState>
446
+ /** Pointers needing raycast this frame (used with frameTimedRaycasts) */
447
+ pointerDirty: Map<number, DomEvent>
448
+ /** Last event received (for events.update() compatibility) */
449
+ lastEvent: React.RefObject<DomEvent | null>
450
+ /** @deprecated Use pointerMap.get(pointerId).hovered instead */
451
+ hovered: Map<string, ThreeEvent<DomEvent>>
452
+ /** @deprecated Use pointerMap.get(pointerId).captured instead */
453
+ capturedMap: Map<number, Map<THREE.Object3D, PointerCaptureTarget>>
454
+ /** @deprecated Use pointerMap.get(pointerId).initialClick instead */
455
+ initialClick: [x: number, y: number]
456
+ /** @deprecated Use pointerMap.get(pointerId).initialHits instead */
457
+ initialHits: THREE.Object3D[]
458
+ /** Visibility event registry (onFramed, onOccluded, onVisible) */
459
+ visibilityRegistry: Map<string, VisibilityEntry>
460
+ /** Whether occlusion queries are enabled (WebGPU only) */
461
+ occlusionEnabled: boolean
462
+ /** Reference to the invisible occlusion observer mesh */
463
+ occlusionObserver: THREE.Mesh | null
464
+ /** Cached occlusion results from render pass - keyed by Object3D */
465
+ occlusionCache: Map<THREE.Object3D, boolean | null>
466
+ /** Internal helper group for R3F system objects (occlusion observer, etc.) */
467
+ helperGroup: THREE.Group | null
468
+ active: boolean
469
+ priority: number
470
+ frames: number
471
+ subscribe: (callback: React.RefObject<RenderCallback>, priority: number, store: RootStore) => () => void
472
+ /** Internal renderer storage - use state.renderer or state.gl to access */
473
+ actualRenderer: R3FRenderer
474
+ /**
475
+ * The renderer support `configure()` loaded for this root: the three namespace of that flavour
476
+ * (JSX constructors, core's classes) and the renderer-specific classes core needs by name.
477
+ * Selected once, from the entry's provider, and copied into portals with the rest of `internal`.
478
+ */
479
+ support: R3FRendererSupport
480
+ /**
481
+ * Releases this root's lease on its renderer. The last release disposes a renderer R3F created;
482
+ * a renderer passed in as an instance is never disposed by R3F.
483
+ */
484
+ releaseRenderer?: () => void | Promise<void>
485
+ /** Global scheduler reference (for useFrame hook) */
486
+ scheduler: SchedulerApi | null
487
+ /**
488
+ * Replaces `renderer.render(scene, camera)` in the default render job when set. Set it with
489
+ * `setRenderOverride(store, fn)`; the job keeps its fps throttle, error handling and user
490
+ * render-phase takeover. Used by `useRenderPipeline`.
491
+ */
492
+ renderOverride?: (() => void) | null
493
+ /** This root's unique ID in the global scheduler */
494
+ rootId?: string
495
+ /** Function to unregister this root from the global scheduler */
496
+ unregisterRoot?: () => void
497
+ /** Function to stop following devicePixelRatio changes */
498
+ unwatchDpr?: () => void
499
+ /** Container for child attachment (scene for root, original container for portals) */
500
+ container?: THREE.Object3D
501
+ /**
502
+ * The CanvasTarget this root sizes and renders through.
503
+ *
504
+ * A primary (`<Canvas id>`) owns the renderer's default target -- the one three itself built
505
+ * around the canvas element -- so sizing it is sizing the renderer. A secondary owns a target
506
+ * R3F created for its own element. Either way there is exactly one target per canvas element,
507
+ * and the canvas-target job makes it the renderer's active one before this root renders.
508
+ * Absent on WebGL and on a WebGPU canvas that is neither a primary nor sharing, where the renderer
509
+ * is sized directly.
510
+ * @see https://threejs.org/docs/#api/en/renderers/common/CanvasTarget
511
+ */
512
+ canvasTarget?: CanvasTarget
513
+ /**
514
+ * Set when this root's canvas target has been resized and the backend's cached render pass
515
+ * descriptor (which holds a depth-stencil view built once per canvas) is therefore stale.
516
+ *
517
+ * Flushed by the canvas-target job in the `start` phase, which is the only place this root's
518
+ * target is guaranteed to be the renderer's active one — `backend.updateSize()` operates on
519
+ * whatever `getCanvasTarget()` returns, so calling it from the resize subscription would
520
+ * invalidate some other canvas's descriptor instead.
521
+ *
522
+ * @see https://github.com/pmndrs/react-three-fiber/issues/3847
523
+ */
524
+ canvasTargetSizeDirty?: boolean
525
+ /**
526
+ * Whether multi-canvas rendering is active.
527
+ * True on a `<Canvas primary>` once another canvas shares its renderer, and on that canvas.
528
+ * When true, setCanvasTarget is called before each render.
529
+ */
530
+ isMultiCanvas?: boolean
531
+ /**
532
+ * Whether this canvas is a secondary canvas sharing another's renderer: it found a
533
+ * `<Canvas primary>` (automatically, or through `share="id"`) and borrows its renderer.
534
+ */
535
+ isSecondary?: boolean
536
+ /**
537
+ * The id of the primary canvas this secondary canvas shares.
538
+ * Only set when isSecondary is true and the primary has an `id`.
539
+ */
540
+ targetId?: string
541
+ /**
542
+ * This secondary stopped sharing because the primary's renderer fell back to its
543
+ * WebGL2 backend (#3965): it owns the renderer it constructed, so it is not
544
+ * `isSecondary` (which marks a canvas borrowing another's renderer).
545
+ */
546
+ sharedRendererFallback?: boolean
547
+ /**
548
+ * Function to withdraw this primary canvas from the registry.
549
+ * Only set on a `<Canvas primary>`.
550
+ */
551
+ unregisterPrimary?: () => void
552
+ /**
553
+ * Function to stop tracking this canvas as one that built its own WebGPU renderer while no primary
554
+ * existed (for the late-primary warning).
555
+ */
556
+ untrackStandalone?: () => void
557
+ /** Whether canvas dimensions are forced to even numbers */
558
+ forceEven?: boolean
559
+ }
560
+
561
+ interface XRManager {
562
+ connect: () => void
563
+ disconnect: () => void
564
+ }
565
+
566
+ //* Root State Interface ====================================
567
+
568
+ interface RootState {
569
+ /** Set current state */
570
+ set: StoreApi<RootState>['setState']
571
+ /** Get current state */
572
+ get: StoreApi<RootState>['getState']
573
+ /**
574
+ * The store of the canvas that owns this root's renderer.
575
+ * - For primary/independent canvases: points to its own store (self-reference)
576
+ * - For secondary canvases: points to the primary canvas's store
577
+ * - Portals copy it from their parent
578
+ *
579
+ * Anything shared per renderer rather than per canvas (e.g. @react-three/tsl's resources)
580
+ * resolves through it.
581
+ */
582
+ primaryStore: RootStore
583
+ /** @deprecated Use `renderer` instead. The instance of the renderer (typed as WebGLRenderer for backwards compat) */
584
+ gl: ForRegisteredRenderer<WebGPURenderer, THREE.WebGLRenderer, THREE.WebGLRenderer>
585
+ /**
586
+ * The renderer instance. Both renderers unless the app registered one
587
+ * (`declare module '@react-three/fiber' { interface Register { renderer: 'webgpu' } }`), or the
588
+ * entry decides it (`/webgpu`, `/legacy`).
589
+ */
590
+ renderer: R3FRenderer
591
+ /** Inspector of the webGPU Renderer. Init in the canvas */
592
+ inspector: any // Inspector type from three/webgpu
593
+
594
+ /** Default camera */
595
+ camera: ThreeCamera
596
+ /** Camera frustum for visibility checks - auto-updated each frame when autoUpdateFrustum is true */
597
+ frustum: THREE.Frustum
598
+ /** Whether to automatically update the frustum each frame (default: true) */
599
+ autoUpdateFrustum: boolean
600
+ /** Default scene (may be overridden in portals to point to the portal container) */
601
+ scene: THREE.Scene
602
+ /** The actual root THREE.Scene - always points to the true scene, even inside portals */
603
+ rootScene: THREE.Scene
604
+ /** Default raycaster */
605
+ raycaster: THREE.Raycaster
606
+ /** Event layer interface, contains the event handler and the node they're connected to */
607
+ events: EventManager<any>
608
+ /** XR interface */
609
+ xr: XRManager
610
+ /** Currently used controls */
611
+ controls: THREE.EventDispatcher | null
612
+ /** Normalized event coordinates */
613
+ pointer: THREE.Vector2
614
+ /** @deprecated Normalized event coordinates, use "pointer" instead! */
615
+ mouse: THREE.Vector2
616
+ /** Color space assigned to 8-bit input textures (color maps). Most textures are authored in sRGB. */
617
+ textureColorSpace: THREE.ColorSpace
618
+ /** Render loop flags */
619
+ frameloop: Frameloop
620
+ performance: Performance
621
+ /** Reactive pixel-size of the canvas */
622
+ size: Size
623
+ /** Reactive size of the viewport in threejs units */
624
+ viewport: Viewport & {
625
+ getCurrentViewport: (
626
+ camera?: ThreeCamera,
627
+ target?: THREE.Vector3 | Parameters<THREE.Vector3['set']>,
628
+ size?: Size,
629
+ ) => Omit<Viewport, 'dpr' | 'initialDpr'>
630
+ }
631
+ /** Flags the canvas for render, but doesn't render in itself */
632
+ invalidate: (frames?: number, stackFrames?: boolean) => void
633
+ /** Advance (render) one step */
634
+ advance: (timestamp: number, runGlobalEffects?: boolean) => void
635
+ /** Shortcut to setting the event layer */
636
+ setEvents: (events: Partial<EventManager<any>>) => void
637
+ /** Shortcut to manual sizing. No args resets to props/container. Single arg creates square. */
638
+ setSize: (width?: number, height?: number, top?: number, left?: number) => void
639
+ /** Shortcut to manual setting the pixel ratio */
640
+ setDpr: (dpr: Dpr) => void
641
+ /** Shortcut to setting frameloop flags. No args resets to 'always'. */
642
+ setFrameloop: (frameloop?: Frameloop) => void
643
+ /** Set error state to propagate to error boundary */
644
+ setError: (error: Error | null) => void
645
+ /** Current error state (null when no error) */
646
+ error: Error | null
647
+ /** Global Texture registry (key → Texture, usually keyed by URL) - use useTextures() hook for access + lifecycle */
648
+ textures: Map<string, THREE.Texture>
649
+ /** Internal: refcount per texture key, driven by mounted useTexture consumers (registry enrollment is on by default) */
650
+ _textureRefs: Map<string, number>
651
+ /** Internal: whether setSize() has taken ownership of canvas dimensions */
652
+ _sizeImperative: boolean
653
+ /** Internal: stored size props from Canvas for reset functionality */
654
+ _sizeProps: { width?: number; height?: number } | null
655
+ /** When the canvas was clicked but nothing was hit */
656
+ onPointerMissed?: (event: MouseEvent) => void
657
+ /** When a dragover event has missed any target */
658
+ onDragOverMissed?: (event: DragEvent) => void
659
+ /** When a drop event has missed any target */
660
+ onDropMissed?: (event: DragEvent) => void
661
+ /** If this state model is layered (via createPortal) then this contains the previous layer */
662
+ previousRoot?: RootStore
663
+ /** Internals */
664
+ internal: InternalState
665
+ // flags for triggers
666
+ // if we are using the webGl renderer, this will be true
667
+ isLegacy: ForRegisteredRenderer<false, true, boolean>
668
+ // regardless of renderer, if the system supports webGpu, this will be true
669
+ webGPUSupported: boolean
670
+ //if we are on native
671
+ isNative: boolean
672
+ }
673
+
674
+ type RootStore = UseBoundStoreWithEqualityFn<StoreApi<RootState>>
675
+
676
+ //* Reconciler Types ==============================
677
+
678
+ // FiberRoot is an opaque internal React type - we define it locally
679
+ // to avoid bundling @types/react-reconciler which causes absolute path issues
680
+ type FiberRoot = any
681
+
682
+ /** A promise tagged with its state, the protocol React's `use` reads */
683
+ type TrackedPromise<T> = Promise<T> &
684
+ ({ status: 'pending' } | { status: 'fulfilled'; value: T } | { status: 'rejected'; reason: unknown })
685
+
686
+ interface Root {
687
+ fiber: FiberRoot
688
+ store: RootStore
689
+ /** Set while a teardown waits on React. Configure and render clear it, which cancels the teardown */
690
+ unmountClaim: symbol | null
691
+ /** Pending only while a renderer is being created */
692
+ ready: TrackedPromise<unknown>
693
+ }
694
+
695
+ type AttachFnType<O = any> = (parent: any, self: O) => () => void
696
+ type AttachType<O = any> = string | AttachFnType<O>
697
+
698
+ type ConstructorRepresentation<T = any> = new (...args: any[]) => T
699
+
700
+ interface Catalogue {
701
+ [name: string]: ConstructorRepresentation
702
+ }
703
+
704
+ // TODO: handle constructor overloads
705
+ // https://github.com/pmndrs/react-three-fiber/pull/2931
706
+ // https://github.com/microsoft/TypeScript/issues/37079
707
+ type Args<T> = T extends ConstructorRepresentation
708
+ ? T extends typeof Color
709
+ ? [r: number, g: number, b: number] | [color: ColorRepresentation]
710
+ : ConstructorParameters<T>
711
+ : any[]
712
+
713
+ type ArgsProp<P> = P extends ConstructorRepresentation
714
+ ? IsAllOptional<ConstructorParameters<P>> extends true
715
+ ? { args?: Args<P> }
716
+ : { args: Args<P> }
717
+ : { args: unknown[] }
718
+
719
+ type InstanceProps<T = any, P = any> = ArgsProp<P> & {
720
+ object?: T
721
+ dispose?: null
722
+ attach?: AttachType<T>
723
+ }
724
+
725
+ interface Instance<O = any> {
726
+ root: RootStore
727
+ type: string
728
+ parent: Instance | null
729
+ children: Instance[]
730
+ props: InstanceProps<O> & Record<string, unknown>
731
+ object: O & { __r3f?: Instance<O> }
732
+ eventCount: number
733
+ handlers: Partial<EventHandlers>
734
+ attach?: AttachType<O>
735
+ previousAttach?: any
736
+ isHidden: boolean
737
+ /** Set of props that have been applied via once() */
738
+ appliedOnce?: Set<string>
739
+ }
740
+
741
+ interface HostConfig {
742
+ type: string
743
+ props: Instance['props']
744
+ container: RootStore
745
+ instance: Instance
746
+ textInstance: void
747
+ suspenseInstance: Instance
748
+ hydratableInstance: never
749
+ formInstance: never
750
+ publicInstance: Instance['object']
751
+ hostContext: {}
752
+ childSet: never
753
+ timeoutHandle: number | undefined
754
+ noTimeout: -1
755
+ TransitionStatus: null
756
+ }
757
+ declare global {
758
+ var IS_REACT_ACT_ENVIRONMENT: boolean | undefined
759
+ }
760
+
761
+ interface RootExtension {
762
+ /** Unique name. Registering the same name again replaces the entry (HMR-safe); roots it already
763
+ * set up are not set up a second time, but get the new entry's dispose and hmr. */
764
+ name: string;
765
+ /**
766
+ * Called once per root, after its renderer exists and before `onCreated` and the first frame.
767
+ * `isLegacy` and `primaryStore` are known by then, so an extension can skip WebGL roots or defer
768
+ * to the primary canvas. Return fields to merge into the root's state, or nothing.
769
+ */
770
+ setup?(store: RootStore): Partial<RootState> | void;
771
+ /** Called when a root this extension set up unmounts. */
772
+ dispose?(store: RootStore): void;
773
+ /** Called when `<Canvas>` detects hot module replacement (skipped with `hmr={false}`). */
774
+ hmr?(store: RootStore): void;
775
+ }
776
+ /**
777
+ * Register an extension. It is set up on every live root immediately, and on every root created
778
+ * afterwards. Returns a function that unregisters it: new roots are no longer set up, while roots
779
+ * it already set up keep its state and still get its dispose when they unmount.
780
+ */
781
+ declare function registerRootExtension(extension: RootExtension): () => void;
782
+ /**
783
+ * Point a root's default render job at a different render function, or back at
784
+ * `renderer.render(scene, camera)` with `null`.
785
+ *
786
+ * The default job keeps everything else: the Canvas `fps` throttle, error propagation to the error
787
+ * boundary, and backing off when a user `useFrame(..., { phase: 'render' })` job takes over.
788
+ */
789
+ declare function setRenderOverride(store: RootStore, render: (() => void) | null): void;
790
+
791
+ /**
792
+ * Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
793
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
794
+ */
795
+ declare function useStore(): RootStore;
796
+ /**
797
+ * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
798
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
799
+ */
800
+ declare function useThree<T = RootState>(selector?: (state: RootState) => T, equalityFn?: <T>(state: T, newState: T) => boolean): T;
801
+
802
+ /**
803
+ * React context that carries the current root's {@link RootStore}. Each root provides its store and
804
+ * each portal provides its own scoped one; `useStore`, and every hook built on it, reads it.
805
+ *
806
+ * Stored on `globalThis` under `Symbol.for('@react-three/fiber.context')`, so every copy and entry
807
+ * of fiber shares a single context.
808
+ */
809
+ declare const context: React.Context<RootStore>;
810
+
811
+ export { useStore as ah, useThree as ai, context as aj, registerRootExtension as r, setRenderOverride as s };
812
+ export type { ObjectMap as $, AttachFnType as A, ArgsProp as B, ConstructorRepresentation as C, Dpr as D, Events as E, Frameloop as F, InstanceProps as G, Instance as H, InternalState as I, HostConfig as J, Properties as K, IsOptional as L, Mutable as M, NonFunctionKeys as N, Overwrite as O, PointerState as P, IsAllOptional as Q, R3FRenderTarget as R, Subscription as S, ThreeEvent as T, ThreeCamera as U, Viewport as V, Act as W, XRManager as X, Bridge as Y, SetBlock as Z, UnblockProps as _, RootExtension as a, EquConfig as a0, Disposable as a1, FrameNextState as a2, FrameState as a3, FrameNextCallback as a4, FrameCallback as a5, ThreeNamespace as a6, ThreeCore as a7, OcclusionSupport as a8, WebGLSupport as a9, WebGPUSupport as aa, RendererSupport as ab, RendererProvider as ac, Register as ad, RegisteredRenderer as ae, ForRegisteredRenderer as af, R3FRendererSupport as ag, R3FRenderer as b, Size as c, RenderCallback as d, Performance as e, RootState as f, RootStore as g, Intersection as h, Camera as i, IntersectionEvent as j, DomEvent as k, EventHandlers as l, FilterFunction as m, ComputeFunction as n, XRPointerConfig as o, EventManager as p, PointerCaptureTarget as q, VisibilityEntry as t, FiberRoot as u, TrackedPromise as v, Root as w, AttachType as x, Catalogue as y, Args as z };