@react-three/fiber 10.0.0-alpha.0 → 10.0.0-alpha.2

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.
@@ -1,13 +1,12 @@
1
1
  import * as three_webgpu from 'three/webgpu';
2
- import { Node, ShaderNodeObject, Euler as Euler$1, Color as Color$2, ColorRepresentation as ColorRepresentation$1, Layers as Layers$1, Raycaster, Intersection as Intersection$1, Vector2 as Vector2$1, Vector3 as Vector3$1, Vector4 as Vector4$1, Quaternion as Quaternion$1, Matrix3 as Matrix3$1, Matrix4 as Matrix4$1, Object3D, Texture as Texture$1, OrthographicCamera } from 'three/webgpu';
2
+ import { RenderTarget, Node, ShaderNodeObject, Euler as Euler$1, Color as Color$2, ColorRepresentation as ColorRepresentation$1, Layers as Layers$1, Raycaster, Intersection as Intersection$1, Vector2 as Vector2$1, Vector3 as Vector3$1, Vector4 as Vector4$1, Quaternion as Quaternion$1, Matrix3 as Matrix3$1, Matrix4 as Matrix4$1, Object3D, Texture as Texture$1, Frustum, OrthographicCamera } from 'three/webgpu';
3
3
  import { Inspector } from 'three/addons/inspector/Inspector.js';
4
4
  import * as THREE$1 from 'three';
5
- import { Color as Color$1, ColorRepresentation } from 'three';
5
+ import { Color as Color$1, ColorRepresentation, RenderTargetOptions as RenderTargetOptions$1 } from 'three';
6
6
  import * as React$1 from 'react';
7
7
  import { ReactNode, Component, RefObject, JSX } from 'react';
8
8
  import { StoreApi } from 'zustand';
9
9
  import { UseBoundStoreWithEqualityFn } from 'zustand/traditional';
10
- import * as react_reconciler from 'C:\\dev\\react-three-fiber\\node_modules\\.pnpm\\@types+react-reconciler@0.32.3_@types+react@19.2.7\\node_modules\\@types\\react-reconciler\\index.d.ts';
11
10
  import { Options } from 'react-use-measure';
12
11
  import * as react_jsx_runtime from 'react/jsx-runtime';
13
12
 
@@ -44,11 +43,15 @@ declare const WebGLRenderer: {
44
43
  type WebGLRendererParameters = never;
45
44
  type WebGLShadowMap = never;
46
45
 
46
+ declare const WebGLRenderTarget: any;
47
+
47
48
  var THREE = /*#__PURE__*/_mergeNamespaces({
48
49
  __proto__: null,
49
50
  Inspector: Inspector,
50
51
  R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
51
52
  R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
53
+ RenderTargetCompat: RenderTarget,
54
+ WebGLRenderTarget: WebGLRenderTarget,
52
55
  WebGLRenderer: WebGLRenderer,
53
56
  WebGLRendererParameters: WebGLRendererParameters,
54
57
  WebGLShadowMap: WebGLShadowMap
@@ -189,6 +192,14 @@ interface EventHandlers {
189
192
  onPointerCancel?: (event: ThreeEvent<PointerEvent>) => void
190
193
  onWheel?: (event: ThreeEvent<WheelEvent>) => void
191
194
  onLostPointerCapture?: (event: ThreeEvent<PointerEvent>) => void
195
+
196
+ //* Visibility Events --------------------------------
197
+ /** Fires when object enters/exits camera frustum. Receives true when in view, false when out. */
198
+ onFramed?: (inView: boolean) => void
199
+ /** Fires when object occlusion state changes (WebGPU only, requires occlusionTest=true on object) */
200
+ onOccluded?: (occluded: boolean) => void
201
+ /** Fires when combined visibility changes (frustum + occlusion + visible prop) */
202
+ onVisible?: (visible: boolean) => void
192
203
  }
193
204
 
194
205
  type FilterFunction = (items: THREE$1.Intersection[], state: RootState) => THREE$1.Intersection[]
@@ -220,6 +231,17 @@ interface EventManager<TTarget> {
220
231
  interface PointerCaptureTarget {
221
232
  intersection: Intersection
222
233
  target: Element
234
+ }
235
+
236
+ //* Visibility System Types =====================================
237
+
238
+ /** Entry in the visibility registry for tracking object visibility state */
239
+ interface VisibilityEntry {
240
+ object: THREE$1.Object3D
241
+ handlers: Pick<EventHandlers, 'onFramed' | 'onOccluded' | 'onVisible'>
242
+ lastFramedState: boolean | null
243
+ lastOccludedState: boolean | null
244
+ lastVisibleState: boolean | null
223
245
  }
224
246
 
225
247
  //* Scheduler Types (useFrame) ==============================
@@ -266,9 +288,9 @@ interface AddPhaseOptions {
266
288
  // Frame State --------------------------------
267
289
 
268
290
  /**
269
- * State passed to useFrame callbacks
291
+ * Timing-only state for independent/outside mode (no RootState)
270
292
  */
271
- interface FrameNextState extends RootState {
293
+ interface FrameTimingState {
272
294
  /** High-resolution timestamp from RAF (ms) */
273
295
  time: number
274
296
  /** Time since last frame in seconds (for legacy compatibility with THREE.Clock) */
@@ -279,9 +301,26 @@ interface FrameNextState extends RootState {
279
301
  frame: number
280
302
  }
281
303
 
304
+ /**
305
+ * State passed to useFrame callbacks (extends RootState with timing)
306
+ */
307
+ interface FrameNextState extends RootState, FrameTimingState {}
308
+
282
309
  /** Alias for FrameNextState */
283
310
  type FrameState = FrameNextState
284
311
 
312
+ // Root Options --------------------------------
313
+
314
+ /**
315
+ * Options for registerRoot
316
+ */
317
+ interface RootOptions {
318
+ /** State provider for callbacks. Optional in independent mode. */
319
+ getState?: () => any
320
+ /** Error handler for job errors. Falls back to console.error if not provided. */
321
+ onError?: (error: Error) => void
322
+ }
323
+
285
324
  // Callback Types --------------------------------
286
325
 
287
326
  /**
@@ -335,13 +374,17 @@ interface SchedulerApi {
335
374
  //* Root Management --------------------------------
336
375
 
337
376
  /** Register a root (Canvas) with the scheduler. Returns unsubscribe function. */
338
- registerRoot(id: string, getState: () => RootState): () => void
377
+ registerRoot(id: string, options?: RootOptions): () => void
339
378
  /** Unregister a root */
340
379
  unregisterRoot(id: string): void
341
380
  /** Generate a unique root ID */
342
381
  generateRootId(): string
343
382
  /** Get the number of registered roots */
344
383
  getRootCount(): number
384
+ /** Check if any root is registered and ready */
385
+ readonly isReady: boolean
386
+ /** Subscribe to root-ready event. Fires immediately if already ready. Returns unsubscribe. */
387
+ onRootReady(callback: () => void): () => void
345
388
 
346
389
  //* Job Registration --------------------------------
347
390
 
@@ -400,6 +443,8 @@ interface SchedulerApi {
400
443
  readonly isRunning: boolean
401
444
  /** Get/set the frameloop mode ('always', 'demand', 'never') */
402
445
  frameloop: Frameloop
446
+ /** Independent mode - runs without Canvas, callbacks receive timing-only state */
447
+ independent: boolean
403
448
 
404
449
  //* Manual Stepping --------------------------------
405
450
 
@@ -477,6 +522,16 @@ interface InternalState {
477
522
  initialClick: [x: number, y: number]
478
523
  initialHits: THREE$1.Object3D[]
479
524
  lastEvent: React$1.RefObject<DomEvent | null>
525
+ /** Visibility event registry (onFramed, onOccluded, onVisible) */
526
+ visibilityRegistry: Map<string, VisibilityEntry>
527
+ /** Whether occlusion queries are enabled (WebGPU only) */
528
+ occlusionEnabled: boolean
529
+ /** Reference to the invisible occlusion observer mesh */
530
+ occlusionObserver: THREE$1.Mesh | null
531
+ /** Cached occlusion results from render pass - keyed by Object3D */
532
+ occlusionCache: Map<THREE$1.Object3D, boolean | null>
533
+ /** Internal helper group for R3F system objects (occlusion observer, etc.) */
534
+ helperGroup: THREE$1.Group | null
480
535
  active: boolean
481
536
  priority: number
482
537
  frames: number
@@ -514,6 +569,10 @@ interface RootState {
514
569
 
515
570
  /** Default camera */
516
571
  camera: ThreeCamera
572
+ /** Camera frustum for visibility checks - auto-updated each frame when autoUpdateFrustum is true */
573
+ frustum: THREE$1.Frustum
574
+ /** Whether to automatically update the frustum each frame (default: true) */
575
+ autoUpdateFrustum: boolean
517
576
  /** Default scene (may be overridden in portals to point to the portal container) */
518
577
  scene: THREE$1.Scene
519
578
  /** The actual root THREE.Scene - always points to the true scene, even inside portals */
@@ -557,8 +616,8 @@ interface RootState {
557
616
  advance: (timestamp: number, runGlobalEffects?: boolean) => void
558
617
  /** Shortcut to setting the event layer */
559
618
  setEvents: (events: Partial<EventManager<any>>) => void
560
- /** Shortcut to manual sizing */
561
- setSize: (width: number, height: number, top?: number, left?: number) => void
619
+ /** Shortcut to manual sizing. No args resets to props/container. Single arg creates square. */
620
+ setSize: (width?: number, height?: number, top?: number, left?: number) => void
562
621
  /** Shortcut to manual setting the pixel ratio */
563
622
  setDpr: (dpr: Dpr) => void
564
623
  /** Shortcut to setting frameloop flags */
@@ -577,6 +636,12 @@ interface RootState {
577
636
  postProcessing: any | null // THREE.PostProcessing when available
578
637
  /** Global TSL pass nodes for post-processing - use usePostProcessing() hook */
579
638
  passes: Record<string, any>
639
+ /** Internal version counter for HMR - incremented by rebuildNodes/rebuildUniforms to bust memoization */
640
+ _hmrVersion: number
641
+ /** Internal: whether setSize() has taken ownership of canvas dimensions */
642
+ _sizeImperative: boolean
643
+ /** Internal: stored size props from Canvas for reset functionality */
644
+ _sizeProps: { width?: number; height?: number } | null
580
645
  /** When the canvas was clicked but nothing was hit */
581
646
  onPointerMissed?: (event: MouseEvent) => void
582
647
  /** When a dragover event has missed any target */
@@ -715,6 +780,16 @@ interface RenderProps<TCanvas extends HTMLCanvasElement | OffscreenCanvas$1> {
715
780
  onDragOverMissed?: (event: DragEvent) => void
716
781
  /** Response for drop events that have missed any target */
717
782
  onDropMissed?: (event: DragEvent) => void
783
+ /** Whether to automatically update the frustum each frame (default: true) */
784
+ autoUpdateFrustum?: boolean
785
+ /**
786
+ * Enable WebGPU occlusion queries for onOccluded/onVisible events.
787
+ * Auto-enabled when any object uses onOccluded or onVisible handlers.
788
+ * Only works with WebGPU renderer - WebGL will log a warning.
789
+ */
790
+ occlusion?: boolean
791
+ /** Internal: stored size props from Canvas for reset functionality */
792
+ _sizeProps?: { width?: number; height?: number } | null
718
793
  }
719
794
 
720
795
  //* Reconciler Root ==============================
@@ -746,8 +821,12 @@ type InjectState = Partial<
746
821
 
747
822
  //* Reconciler Types ==============================
748
823
 
824
+ // FiberRoot is an opaque internal React type - we define it locally
825
+ // to avoid bundling @types/react-reconciler which causes absolute path issues
826
+ type FiberRoot = any
827
+
749
828
  interface Root {
750
- fiber: react_reconciler.FiberRoot
829
+ fiber: FiberRoot
751
830
  store: RootStore
752
831
  }
753
832
 
@@ -825,8 +904,7 @@ type GlobalEffectType = 'before' | 'after' | 'tail'
825
904
  //* Canvas Types ==============================
826
905
 
827
906
  interface CanvasProps
828
- extends Omit<RenderProps<HTMLCanvasElement>, 'size'>,
829
- React$1.HTMLAttributes<HTMLDivElement> {
907
+ extends Omit<RenderProps<HTMLCanvasElement>, 'size'>, React$1.HTMLAttributes<HTMLDivElement> {
830
908
  children?: React$1.ReactNode
831
909
  ref?: React$1.Ref<HTMLCanvasElement>
832
910
  /** Canvas fallback content, similar to img's alt prop */
@@ -840,6 +918,12 @@ interface CanvasProps
840
918
  eventSource?: HTMLElement | React$1.RefObject<HTMLElement>
841
919
  /** The event prefix that is cast into canvas pointer x/y events, default: "offset" */
842
920
  eventPrefix?: 'offset' | 'client' | 'page' | 'layer' | 'screen'
921
+ /** Enable/disable automatic HMR refresh for TSL nodes and uniforms, default: true in dev */
922
+ hmr?: boolean
923
+ /** Canvas resolution width in pixels. If omitted, uses container width. */
924
+ width?: number
925
+ /** Canvas resolution height in pixels. If omitted, uses container height. */
926
+ height?: number
843
927
  }
844
928
 
845
929
  //* Loader Types ==============================
@@ -868,20 +952,15 @@ type InferLoadResult<T> = T extends {
868
952
  }
869
953
  ? R
870
954
  : T extends ConstructorRepresentation<any>
871
- ? InstanceType<T> extends {
872
- load(url: any, onLoad?: (result: infer R) => void, ...args: any[]): any
873
- }
874
- ? R
955
+ ? InstanceType<T> extends {
956
+ load(url: any, onLoad?: (result: infer R) => void, ...args: any[]): any
957
+ }
958
+ ? R
959
+ : any
875
960
  : any
876
- : any
877
961
 
878
- type LoaderResult<T extends LoaderLike | ConstructorRepresentation<LoaderLike>> = InferLoadResult<
879
- LoaderInstance<T>
880
- > extends infer R
881
- ? R extends GLTFLike
882
- ? R & ObjectMap
883
- : R
884
- : never
962
+ type LoaderResult<T extends LoaderLike | ConstructorRepresentation<LoaderLike>> =
963
+ InferLoadResult<LoaderInstance<T>> extends infer R ? (R extends GLTFLike ? R & ObjectMap : R) : never
885
964
 
886
965
  type Extensions<T extends LoaderLike | ConstructorRepresentation<LoaderLike>> = (
887
966
  loader: LoaderInstance<T>,
@@ -897,6 +976,11 @@ interface WebGLShadowConfig {
897
976
  shadows?: boolean | 'basic' | 'percentage' | 'soft' | 'variance' | Partial<THREE$1.WebGLShadowMap>
898
977
  }
899
978
 
979
+ //* RenderTarget Types ==============================
980
+
981
+
982
+ type RenderTargetOptions = RenderTargetOptions$1
983
+
900
984
  //* Global Types ==============================
901
985
 
902
986
  declare global {
@@ -915,6 +999,15 @@ declare global {
915
999
  */
916
1000
  type UniformStore = Record<string, UniformNode | UniformRecord>
917
1001
 
1002
+ /**
1003
+ * Helper to safely access a uniform node from the store.
1004
+ * Use this when accessing state.uniforms to get proper typing.
1005
+ * @example
1006
+ * const uTime = uniforms.uTime as UniformNode<number>
1007
+ * const uColor = uniforms.uColor as UniformNode<import('three/webgpu').Color>
1008
+ */
1009
+ type GetUniform<T = unknown> = UniformNode<T>
1010
+
918
1011
  /**
919
1012
  * Acceptable input values for useUniforms - raw values that get converted to UniformNodes
920
1013
  * Supports: primitives, Three.js types, plain objects (converted to vectors), and UniformNodes
@@ -1013,6 +1106,10 @@ declare global {
1013
1106
  }
1014
1107
  }
1015
1108
 
1109
+ //* useFrameNext Types ==============================
1110
+
1111
+
1112
+
1016
1113
  //* Global Type Declarations ==============================
1017
1114
 
1018
1115
  declare global {
@@ -1104,8 +1201,8 @@ declare global {
1104
1201
  interface RootEntry {
1105
1202
  /** Unique identifier for this root */
1106
1203
  id: string
1107
- /** Function to get the root's current state */
1108
- getState: () => RootState
1204
+ /** Function to get the root's current state. Returns any to support independent mode. */
1205
+ getState: () => any
1109
1206
  /** Map of job IDs to Job objects */
1110
1207
  jobs: Map<string, Job>
1111
1208
  /** Cached sorted job list for execution order */
@@ -1162,8 +1259,8 @@ type MathTypes = MathRepresentation | Euler$1 | Color$2
1162
1259
  type MathType<T extends MathTypes> = T extends Color$2
1163
1260
  ? Args<typeof Color$2> | ColorRepresentation$1
1164
1261
  : T extends VectorRepresentation | Layers$1 | Euler$1
1165
- ? T | MutableOrReadonlyParameters<T['set']> | number
1166
- : T | MutableOrReadonlyParameters<T['set']>
1262
+ ? T | MutableOrReadonlyParameters<T['set']> | number
1263
+ : T | MutableOrReadonlyParameters<T['set']>
1167
1264
 
1168
1265
  type MathProps<P> = {
1169
1266
  [K in keyof P as P[K] extends MathTypes ? K : never]: P[K] extends MathTypes ? MathType<P[K]> : never
@@ -1297,7 +1394,9 @@ declare namespace useLoader {
1297
1394
  * - Demand mode support via invalidate()
1298
1395
  */
1299
1396
  declare class Scheduler {
1300
- private static instance;
1397
+ private static readonly INSTANCE_KEY;
1398
+ private static get instance();
1399
+ private static set instance(value);
1301
1400
  /**
1302
1401
  * Get the global scheduler instance (creates if doesn't exist).
1303
1402
  * Uses HMR data to preserve instance across hot reloads.
@@ -1323,19 +1422,25 @@ declare class Scheduler {
1323
1422
  private jobStateListeners;
1324
1423
  private pendingFrames;
1325
1424
  private _frameloop;
1425
+ private _independent;
1426
+ private errorHandler;
1427
+ private rootReadyCallbacks;
1326
1428
  get phases(): string[];
1327
1429
  get frameloop(): Frameloop;
1328
1430
  set frameloop(mode: Frameloop);
1329
1431
  get isRunning(): boolean;
1432
+ get isReady(): boolean;
1433
+ get independent(): boolean;
1434
+ set independent(value: boolean);
1330
1435
  constructor();
1331
1436
  /**
1332
1437
  * Register a root (Canvas) with the scheduler.
1333
1438
  * The first root to register starts the RAF loop (if frameloop='always').
1334
1439
  * @param {string} id - Unique identifier for this root
1335
- * @param {() => RootState} getState - Function to get the root's current state
1440
+ * @param {RootOptions} [options] - Optional configuration with getState and onError callbacks
1336
1441
  * @returns {() => void} Unsubscribe function to remove this root
1337
1442
  */
1338
- registerRoot(id: string, getState: () => RootState): () => void;
1443
+ registerRoot(id: string, options?: RootOptions): () => void;
1339
1444
  /**
1340
1445
  * Unregister a root from the scheduler.
1341
1446
  * Cleans up all job state listeners for this root's jobs.
@@ -1344,6 +1449,34 @@ declare class Scheduler {
1344
1449
  * @returns {void}
1345
1450
  */
1346
1451
  unregisterRoot(id: string): void;
1452
+ /**
1453
+ * Subscribe to be notified when a root becomes available.
1454
+ * Fires immediately if a root already exists.
1455
+ * @param {() => void} callback - Function called when first root registers
1456
+ * @returns {() => void} Unsubscribe function
1457
+ */
1458
+ onRootReady(callback: () => void): () => void;
1459
+ /**
1460
+ * Notify all registered root-ready callbacks.
1461
+ * Called when the first root registers.
1462
+ * @returns {void}
1463
+ * @private
1464
+ */
1465
+ private notifyRootReady;
1466
+ /**
1467
+ * Ensure a default root exists for independent mode.
1468
+ * Creates a minimal root with no state provider.
1469
+ * @returns {void}
1470
+ * @private
1471
+ */
1472
+ private ensureDefaultRoot;
1473
+ /**
1474
+ * Trigger error handling for job errors.
1475
+ * Uses the bound error handler if available, otherwise logs to console.
1476
+ * @param {Error} error - The error to handle
1477
+ * @returns {void}
1478
+ */
1479
+ triggerError(error: Error): void;
1347
1480
  /**
1348
1481
  * Add a named phase to the scheduler's execution order.
1349
1482
  * Marks all roots for rebuild to incorporate the new phase.
@@ -1552,7 +1685,7 @@ declare class Scheduler {
1552
1685
  /**
1553
1686
  * Execute all jobs for a single root in sorted order.
1554
1687
  * Rebuilds sorted job list if needed, then dispatches each job.
1555
- * Errors are caught and propagated to the root's error boundary.
1688
+ * Errors are caught and propagated via triggerError.
1556
1689
  * @param {RootEntry} root - The root entry to tick
1557
1690
  * @param {number} timestamp - RAF timestamp in milliseconds
1558
1691
  * @param {number} delta - Time since last frame in seconds
@@ -1615,6 +1748,11 @@ declare const getScheduler: () => Scheduler;
1615
1748
  /**
1616
1749
  * Frame hook with phase-based ordering, priority, and FPS throttling.
1617
1750
  *
1751
+ * Works both inside and outside Canvas context:
1752
+ * - Inside Canvas: Full RootState (gl, scene, camera, etc.)
1753
+ * - Outside Canvas (waiting mode): Waits for Canvas to mount, then gets full state
1754
+ * - Outside Canvas (independent mode): Fires immediately with timing-only state
1755
+ *
1618
1756
  * Returns a controls object for manual stepping, pausing, and resuming.
1619
1757
  *
1620
1758
  * @param callback - Function called each frame with (state, delta). Optional if you only need scheduler access.
@@ -1630,18 +1768,16 @@ declare const getScheduler: () => Scheduler;
1630
1768
  * useFrame((state, delta) => { ... }, { phase: 'physics' })
1631
1769
  *
1632
1770
  * @example
1633
- * // With controls
1634
- * const controls = useFrame(cb, { phase: 'physics', id: 'my-physics' })
1635
- * controls.step() // Step this job only
1636
- * controls.stepAll() // Step all jobs
1637
- * controls.pause() // Pause this job
1638
- * controls.resume() // Resume this job
1771
+ * // Outside Canvas - waits for Canvas to mount
1772
+ * function UI() {
1773
+ * useFrame((state, delta) => { syncUI(state.camera) });
1774
+ * return <button>...</button>;
1775
+ * }
1639
1776
  *
1640
1777
  * @example
1641
- * // Manual mode (frameloop='never')
1642
- * const { stepAll } = useFrame(cb)
1643
- * // In your animation controller:
1644
- * stepAll() // Advance all useFrame jobs
1778
+ * // Independent mode - no Canvas needed
1779
+ * getScheduler().independent = true;
1780
+ * useFrame((state, delta) => { updateGame(delta) });
1645
1781
  *
1646
1782
  * @example
1647
1783
  * // Scheduler-only access (no callback)
@@ -1775,6 +1911,39 @@ interface UseTexturesReturn {
1775
1911
  */
1776
1912
  declare function useTextures(): UseTexturesReturn;
1777
1913
 
1914
+ /**
1915
+ * Creates a render target compatible with the current renderer.
1916
+ *
1917
+ * - Legacy build: Returns WebGLRenderTarget
1918
+ * - WebGPU build: Returns RenderTarget
1919
+ * - Default build: Returns whichever matches the active renderer
1920
+ *
1921
+ * @param width - Target width (defaults to canvas width)
1922
+ * @param height - Target height (defaults to canvas height)
1923
+ * @param options - Three.js RenderTarget options
1924
+ *
1925
+ * @example
1926
+ * ```tsx
1927
+ * function PortalScene() {
1928
+ * const fbo = useRenderTarget(512, 512, { depthBuffer: true })
1929
+ *
1930
+ * useFrame(({ renderer, scene, camera }) => {
1931
+ * renderer.setRenderTarget(fbo)
1932
+ * renderer.render(scene, camera)
1933
+ * renderer.setRenderTarget(null)
1934
+ * })
1935
+ *
1936
+ * return (
1937
+ * <mesh>
1938
+ * <planeGeometry />
1939
+ * <meshBasicMaterial map={fbo.texture} />
1940
+ * </mesh>
1941
+ * )
1942
+ * }
1943
+ * ```
1944
+ */
1945
+ declare function useRenderTarget(width?: number, height?: number, options?: RenderTargetOptions): RenderTarget<THREE$1.Texture<unknown>>;
1946
+
1778
1947
  /**
1779
1948
  * Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
1780
1949
  * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
@@ -3309,6 +3478,26 @@ declare function getUuidPrefix(uuid: string): string;
3309
3478
  * @param size - Current viewport size
3310
3479
  */
3311
3480
  declare function updateCamera(camera: ThreeCamera, size: Size): void;
3481
+ /**
3482
+ * Updates a frustum from a camera's projection and world matrices.
3483
+ * If no target frustum is provided, creates and returns a new one.
3484
+ *
3485
+ * @param camera - Camera to extract frustum from
3486
+ * @param frustum - Optional existing frustum to update (creates new if not provided)
3487
+ * @returns The updated or newly created frustum
3488
+ *
3489
+ * @example
3490
+ * // Create new frustum
3491
+ * const frustum = updateFrustum(camera)
3492
+ *
3493
+ * // Update existing frustum (no allocation)
3494
+ * updateFrustum(camera, existingFrustum)
3495
+ *
3496
+ * // Use for visibility checks
3497
+ * if (frustum.containsPoint(point)) { ... }
3498
+ * if (frustum.intersectsObject(mesh)) { ... }
3499
+ */
3500
+ declare function updateFrustum(camera: ThreeCamera, frustum?: Frustum): Frustum;
3312
3501
 
3313
3502
  declare const is: {
3314
3503
  obj: (a: any) => boolean;
@@ -3346,57 +3535,163 @@ declare const hasConstructor: (object: unknown) => object is {
3346
3535
  */
3347
3536
  declare function Canvas(props: CanvasProps): react_jsx_runtime.JSX.Element;
3348
3537
 
3538
+ /**
3539
+ * ScopedStore - Type-safe wrapper for nested stores (uniforms, nodes)
3540
+ *
3541
+ * Provides TypeScript-friendly access to uniform/node stores where the runtime
3542
+ * structure is `Record<string, T | Record<string, T>>` (leaf nodes or nested scopes).
3543
+ *
3544
+ * The wrapper uses a Proxy to:
3545
+ * 1. Return `T` for property access (type assumption: assumes leaf node)
3546
+ * 2. Provide `.scope(key)` method for explicit nested access
3547
+ * 3. Support iteration methods: has(), keys(), Object.keys(), for...in
3548
+ *
3549
+ * @example
3550
+ * ```tsx
3551
+ * useLocalNodes(({ uniforms }) => ({
3552
+ * wobble: sin(uniforms.uTime.mul(2)), // No cast needed!
3553
+ * playerHealth: uniforms.scope('player').uHealth // Explicit scope access
3554
+ * }))
3555
+ * ```
3556
+ */
3557
+
3558
+ /** Keys reserved for methods (excluded from index signature) */
3559
+ type MethodKeys = 'scope' | 'has' | 'keys';
3560
+ /**
3561
+ * Type-safe wrapper interface for accessing nested store data.
3562
+ * Property access returns `T` (assumes leaf node).
3563
+ * Use `.scope(key)` for nested object access.
3564
+ *
3565
+ * Uses mapped type with key filtering to exclude method names from index signature,
3566
+ * allowing methods to have their correct return types.
3567
+ */
3568
+ type ScopedStoreType<T> = {
3569
+ /** Direct property access returns the leaf type T (method keys excluded) */
3570
+ readonly [K in string as K extends MethodKeys ? never : K]: T;
3571
+ } & {
3572
+ /** Access a nested scope by key. Returns empty wrapper if scope doesn't exist. */
3573
+ scope(key: string): ScopedStoreType<T>;
3574
+ /** Check if a key exists in the store */
3575
+ has(key: string): boolean;
3576
+ /** Get all keys in the store */
3577
+ keys(): string[];
3578
+ };
3579
+ /**
3580
+ * Create a type-safe ScopedStore wrapper around store data.
3581
+ * @param data - The raw store data (uniforms or nodes from RootState)
3582
+ * @returns A ScopedStoreType wrapper with type-safe access
3583
+ */
3584
+ declare function createScopedStore<T>(data: Record<string, any>): ScopedStoreType<T>;
3585
+ /**
3586
+ * State type passed to creator functions with ScopedStore wrappers.
3587
+ * Provides type-safe access to uniforms and nodes without manual casting.
3588
+ */
3589
+ type CreatorState = Omit<RootState, 'uniforms' | 'nodes'> & {
3590
+ /** Type-safe uniform access - property access returns UniformNode */
3591
+ uniforms: ScopedStoreType<UniformNode>;
3592
+ /** Type-safe node access - property access returns Node */
3593
+ nodes: ScopedStoreType<Node>;
3594
+ };
3595
+
3349
3596
  /** Creator function that returns uniform inputs (can be raw values or UniformNodes) */
3350
- type UniformCreator<T extends UniformInputRecord = UniformInputRecord> = (state: RootState) => T;
3351
- declare function useUniforms(): UniformRecord;
3352
- declare function useUniforms(scope: string): UniformRecord;
3353
- declare function useUniforms<T extends UniformInputRecord>(creator: UniformCreator<T>): UniformRecord<UniformNode>;
3354
- declare function useUniforms<T extends UniformInputRecord>(creator: UniformCreator<T>, scope: string): UniformRecord<UniformNode>;
3355
- declare function useUniforms<T extends UniformInputRecord>(uniforms: T): UniformRecord<UniformNode>;
3356
- declare function useUniforms<T extends UniformInputRecord>(uniforms: T, scope: string): UniformRecord<UniformNode>;
3597
+ type UniformCreator<T extends UniformInputRecord = UniformInputRecord> = (state: CreatorState) => T;
3598
+ /** Function signature for removeUniforms util */
3599
+ type RemoveUniformsFn = (names: string | string[], scope?: string) => void;
3600
+ /** Function signature for clearUniforms util */
3601
+ type ClearUniformsFn = (scope?: string) => void;
3602
+ /** Function signature for rebuildUniforms util */
3603
+ type RebuildUniformsFn = (scope?: string) => void;
3604
+ /** Return type with utils included */
3605
+ type UniformsWithUtils<T extends UniformRecord = UniformRecord> = T & {
3606
+ removeUniforms: RemoveUniformsFn;
3607
+ clearUniforms: ClearUniformsFn;
3608
+ rebuildUniforms: RebuildUniformsFn;
3609
+ };
3610
+ declare function useUniforms(): UniformsWithUtils<UniformRecord & Record<string, UniformRecord>>;
3611
+ declare function useUniforms(scope: string): UniformsWithUtils;
3612
+ declare function useUniforms<T extends UniformInputRecord>(creator: UniformCreator<T>): UniformsWithUtils<UniformRecord<UniformNode>>;
3613
+ declare function useUniforms<T extends UniformInputRecord>(creator: UniformCreator<T>, scope: string): UniformsWithUtils<UniformRecord<UniformNode>>;
3614
+ declare function useUniforms<T extends UniformInputRecord>(uniforms: T): UniformsWithUtils<UniformRecord<UniformNode>>;
3615
+ declare function useUniforms<T extends UniformInputRecord>(uniforms: T, scope: string): UniformsWithUtils<UniformRecord<UniformNode>>;
3616
+ /**
3617
+ * Global rebuildUniforms function for HMR integration.
3618
+ * Clears cached uniforms and increments _hmrVersion to trigger re-creation.
3619
+ * Call this when HMR is detected to refresh all uniform creators.
3620
+ *
3621
+ * @param store - The R3F store (from useStore or context)
3622
+ * @param scope - Optional scope to rebuild ('root' for root only, string for specific scope, undefined for all)
3623
+ */
3624
+ declare function rebuildAllUniforms(store: ReturnType<typeof useStore>, scope?: string): void;
3357
3625
  /**
3358
3626
  * Remove uniforms by name from root level or a scope
3359
- * @param scope - If provided, removes from that scope. Otherwise removes from root.
3627
+ * @deprecated Use `const { removeUniforms } = useUniforms()` instead
3360
3628
  */
3361
3629
  declare function removeUniforms(set: ReturnType<typeof useStore>['setState'], names: string[], scope?: string): void;
3362
3630
  /**
3363
3631
  * Clear all uniforms from a scope (removes the entire scope object)
3632
+ * @deprecated Use `const { clearUniforms } = useUniforms()` instead
3364
3633
  */
3365
3634
  declare function clearScope(set: ReturnType<typeof useStore>['setState'], scope: string): void;
3366
3635
  /**
3367
3636
  * Clear all root-level uniforms (preserves scopes)
3637
+ * @deprecated Use `const { clearUniforms } = useUniforms()` with `clearUniforms('root')` instead
3368
3638
  */
3369
3639
  declare function clearRootUniforms(set: ReturnType<typeof useStore>['setState']): void;
3370
3640
 
3371
3641
  /** Supported uniform value types */
3372
3642
  type UniformValue = number | boolean | Vector2$1 | Vector3$1 | Vector4$1 | Color$2 | Matrix3$1 | Matrix4$1;
3643
+ /** Widen literal types to their base types (0 → number, true → boolean) */
3644
+ type Widen<T> = T extends number ? number : T extends boolean ? boolean : T;
3373
3645
  declare function useUniform<T extends UniformValue>(name: string): UniformNode<T>;
3374
- declare function useUniform<T extends UniformValue>(name: string, value: T): UniformNode<T>;
3646
+ declare function useUniform<T extends UniformValue>(name: string, value: T): UniformNode<Widen<T>>;
3375
3647
 
3376
3648
  /** TSL node type - extends Three.js Node for material compatibility */
3377
3649
  type TSLNode = Node;
3378
3650
  type NodeRecord<T extends Node = Node> = Record<string, T>;
3379
- type NodeCreator<T extends NodeRecord> = (state: RootState) => T;
3380
- declare function useNodes(): NodeRecord;
3381
- declare function useNodes(scope: string): NodeRecord;
3382
- declare function useNodes<T extends NodeRecord>(creator: NodeCreator<T>): T;
3383
- declare function useNodes<T extends NodeRecord>(creator: NodeCreator<T>, scope: string): T;
3651
+ type NodeCreator<T extends NodeRecord> = (state: CreatorState) => T;
3652
+ /** Function signature for removeNodes util */
3653
+ type RemoveNodesFn = (names: string | string[], scope?: string) => void;
3654
+ /** Function signature for clearNodes util */
3655
+ type ClearNodesFn = (scope?: string) => void;
3656
+ /** Function signature for rebuildNodes util */
3657
+ type RebuildNodesFn = (scope?: string) => void;
3658
+ /** Return type with utils included */
3659
+ type NodesWithUtils<T extends NodeRecord = NodeRecord> = T & {
3660
+ removeNodes: RemoveNodesFn;
3661
+ clearNodes: ClearNodesFn;
3662
+ rebuildNodes: RebuildNodesFn;
3663
+ };
3664
+ declare function useNodes(): NodesWithUtils<NodeRecord & Record<string, NodeRecord>>;
3665
+ declare function useNodes(scope: string): NodesWithUtils;
3666
+ declare function useNodes<T extends NodeRecord>(creator: NodeCreator<T>): NodesWithUtils<T>;
3667
+ declare function useNodes<T extends NodeRecord>(creator: NodeCreator<T>, scope: string): NodesWithUtils<T>;
3668
+ /**
3669
+ * Global rebuildNodes function for HMR integration.
3670
+ * Clears cached nodes and increments _hmrVersion to trigger re-creation.
3671
+ * Call this when HMR is detected to refresh all node creators.
3672
+ *
3673
+ * @param store - The R3F store (from useStore or context)
3674
+ * @param scope - Optional scope to rebuild ('root' for root only, string for specific scope, undefined for all)
3675
+ */
3676
+ declare function rebuildAllNodes(store: ReturnType<typeof useStore>, scope?: string): void;
3384
3677
  /**
3385
3678
  * Remove nodes by name from root level or a scope
3386
- * @param scope - If provided, removes from that scope. Otherwise removes from root.
3679
+ * @deprecated Use `const { removeNodes } = useNodes()` instead
3387
3680
  */
3388
3681
  declare function removeNodes(set: ReturnType<typeof useStore>['setState'], names: string[], scope?: string): void;
3389
3682
  /**
3390
3683
  * Clear all nodes from a scope (removes the entire scope object)
3684
+ * @deprecated Use `const { clearNodes } = useNodes()` instead
3391
3685
  */
3392
3686
  declare function clearNodeScope(set: ReturnType<typeof useStore>['setState'], scope: string): void;
3393
3687
  /**
3394
3688
  * Clear all root-level nodes (preserves scopes)
3689
+ * @deprecated Use `const { clearNodes } = useNodes()` with `clearNodes('root')` instead
3395
3690
  */
3396
3691
  declare function clearRootNodes(set: ReturnType<typeof useStore>['setState']): void;
3397
3692
 
3398
- /** Creator receives RootState - destructure what you need. Returns any record. */
3399
- type LocalNodeCreator<T extends Record<string, unknown>> = (state: RootState) => T;
3693
+ /** Creator receives CreatorState with ScopedStore wrappers for type-safe access. Returns any record. */
3694
+ type LocalNodeCreator<T extends Record<string, unknown>> = (state: CreatorState) => T;
3400
3695
  /**
3401
3696
  * Creates local values that rebuild when uniforms, nodes, or textures change.
3402
3697
  *
@@ -3415,6 +3710,12 @@ type LocalNodeCreator<T extends Record<string, unknown>> = (state: RootState) =>
3415
3710
  * const { scaled } = useLocalNodes(({ camera, nodes }) => ({
3416
3711
  * scaled: nodes.basePos.mul(camera.zoom),
3417
3712
  * }))
3713
+ *
3714
+ * // Type-safe uniform access
3715
+ * const { colorNode } = useLocalNodes(({ uniforms }) => {
3716
+ * const uValue = uniforms.myUniform as UniformNode<number>
3717
+ * return { colorNode: mix(colorA, colorB, uValue) }
3718
+ * })
3418
3719
  * ```
3419
3720
  */
3420
3721
  declare function useLocalNodes<T extends Record<string, unknown>>(creator: LocalNodeCreator<T>): T;
@@ -3466,5 +3767,5 @@ declare function createTextureOperations(set: StoreApi<RootState>['setState']):
3466
3767
  */
3467
3768
  declare function usePostProcessing(mainCB?: PostProcessingMainCallback, setupCB?: PostProcessingSetupCallback): UsePostProcessingReturn;
3468
3769
 
3469
- export { Block, Canvas, ErrorBoundary, IsObject, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, three_d as ReactThreeFiber, Scheduler, Texture, _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, clearNodeScope, clearRootNodes, clearRootUniforms, clearScope, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, createTextureOperations, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, getInstanceProps, getRootState, getScheduler, getUuidPrefix, hasConstructor, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isObject3D, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, prepare, reconciler, removeInteractivity, removeNodes, removeUniforms, resolve, unmountComponentAtNode, updateCamera, useBridge, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes, usePostProcessing, useStore, useTexture, useTextures, useThree, useUniform, useUniforms };
3470
- export type { Act, AddPhaseOptions, Args, ArgsProp, AttachFnType, AttachType, BaseRendererProps, Bridge, Camera, CameraProps, CanvasProps, Catalogue, Color, ComputeFunction, ConstructorRepresentation, DefaultGLProps, DefaultRendererProps, Disposable, DomEvent, Dpr, ElementProps, EquConfig, Euler, EventHandlers, EventManager, EventProps, Events, Extensions, FilterFunction, FrameCallback, FrameControls, FrameNextCallback, FrameNextControls, FrameNextState, FrameState, Frameloop, GLProps, GLTFLike, GlobalEffectType, GlobalRenderCallback, HostConfig, InferLoadResult, InjectState, InputLike, Instance, InstanceProps, InternalState, Intersection, IntersectionEvent, IsAllOptional, IsOptional, Layers, LoaderInstance, LoaderLike, LoaderResult, LocalNodeCreator, MappedTextureType, MathProps, MathRepresentation, MathType, MathTypes, Matrix3, Matrix4, Mutable, MutableOrReadonlyParameters, NodeCreator, NodeRecord, NonFunctionKeys, ObjectMap, OffscreenCanvas$1 as OffscreenCanvas, Overwrite, Performance, PointerCaptureTarget, Properties, Quaternion, RaycastableRepresentation, ReactProps, ReconcilerRoot, RenderCallback, RenderProps, Renderer, RendererFactory, RendererProps, Root, RootState, RootStore, SchedulerApi, SetBlock, Size, Subscription, TSLNode, TextureEntry, TextureOperations, ThreeCamera, ThreeElement, ThreeElements, ThreeElementsImpl, ThreeEvent, ThreeExports, ThreeToJSXElements, UnblockProps, UniformCreator, UniformValue, UseFrameNextOptions, UseFrameOptions, UseTextureOptions, UseTexturesReturn, Vector2, Vector3, Vector4, VectorRepresentation, Viewport, WebGLDefaultProps, WebGLProps, WebGLShadowConfig, XRManager };
3770
+ export { Block, Canvas, ErrorBoundary, IsObject, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, three_d as ReactThreeFiber, Scheduler, Texture, _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, clearNodeScope, clearRootNodes, clearRootUniforms, clearScope, context, createEvents, createPointerEvents, createPortal, createRoot, createScopedStore, createStore, createTextureOperations, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, getInstanceProps, getRootState, getScheduler, getUuidPrefix, hasConstructor, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isObject3D, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, prepare, rebuildAllNodes, rebuildAllUniforms, reconciler, removeInteractivity, removeNodes, removeUniforms, resolve, unmountComponentAtNode, updateCamera, updateFrustum, useBridge, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes, usePostProcessing, useRenderTarget, useStore, useTexture, useTextures, useThree, useUniform, useUniforms };
3771
+ export type { Act, AddPhaseOptions, Args, ArgsProp, AttachFnType, AttachType, BaseRendererProps, Bridge, Camera, CameraProps, CanvasProps, Catalogue, ClearNodesFn, ClearUniformsFn, Color, ComputeFunction, ConstructorRepresentation, CreatorState, DefaultGLProps, DefaultRendererProps, Disposable, DomEvent, Dpr, ElementProps, EquConfig, Euler, EventHandlers, EventManager, EventProps, Events, Extensions, FiberRoot, FilterFunction, FrameCallback, FrameControls, FrameNextCallback, FrameNextControls, FrameNextState, FrameState, FrameTimingState, Frameloop, GLProps, GLTFLike, GlobalEffectType, GlobalRenderCallback, HostConfig, InferLoadResult, InjectState, InputLike, Instance, InstanceProps, InternalState, Intersection, IntersectionEvent, IsAllOptional, IsOptional, Layers, LoaderInstance, LoaderLike, LoaderResult, LocalNodeCreator, MappedTextureType, MathProps, MathRepresentation, MathType, MathTypes, Matrix3, Matrix4, Mutable, MutableOrReadonlyParameters, NodeCreator, NodeRecord, NodesWithUtils, NonFunctionKeys, ObjectMap, OffscreenCanvas$1 as OffscreenCanvas, Overwrite, Performance, PointerCaptureTarget, Properties, Quaternion, RaycastableRepresentation, ReactProps, RebuildNodesFn, RebuildUniformsFn, ReconcilerRoot, RemoveNodesFn, RemoveUniformsFn, RenderCallback, RenderProps, RenderTargetOptions, Renderer, RendererFactory, RendererProps, Root, RootOptions, RootState, RootStore, SchedulerApi, ScopedStoreType, SetBlock, Size, Subscription, TSLNode, TextureEntry, TextureOperations, ThreeCamera, ThreeElement, ThreeElements, ThreeElementsImpl, ThreeEvent, ThreeExports, ThreeToJSXElements, UnblockProps, UniformCreator, UniformValue, UniformsWithUtils, UseFrameNextOptions, UseFrameOptions, UseTextureOptions, UseTexturesReturn, Vector2, Vector3, Vector4, VectorRepresentation, Viewport, VisibilityEntry, WebGLDefaultProps, WebGLProps, WebGLShadowConfig, XRManager };