@react-three/fiber 10.0.0-canary.b0fafc8 → 10.0.0-canary.d6fdf72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/legacy.d.ts CHANGED
@@ -3,7 +3,7 @@ import { WebGLRenderTarget, Color as Color$1, ColorRepresentation, Euler as Eule
3
3
  import * as React$1 from 'react';
4
4
  import { ReactNode, Component, RefObject, JSX } from 'react';
5
5
  import * as three_webgpu from 'three/webgpu';
6
- import { WebGPURenderer as WebGPURenderer$1, CanvasTarget, Node, ShaderNodeObject } from 'three/webgpu';
6
+ import { WebGPURenderer as WebGPURenderer$1, Node, StorageTexture, Data3DTexture, CanvasTarget, ShaderNodeObject } from 'three/webgpu';
7
7
  import { StoreApi } from 'zustand';
8
8
  import { UseBoundStoreWithEqualityFn } from 'zustand/traditional';
9
9
  import { Options } from 'react-use-measure';
@@ -148,6 +148,8 @@ interface IntersectionEvent<TSourceEvent> extends Intersection {
148
148
  unprojectedPoint: THREE$1.Vector3
149
149
  /** Normalized event coordinates */
150
150
  pointer: THREE$1.Vector2
151
+ /** pointerId of the original event for multiple pointer events */
152
+ pointerId: number
151
153
  /** Delta between first click and this event */
152
154
  delta: number
153
155
  /** The ray that pierced it */
@@ -224,6 +226,18 @@ interface EventHandlers {
224
226
  type FilterFunction = (items: THREE$1.Intersection[], state: RootState) => THREE$1.Intersection[]
225
227
  type ComputeFunction = (event: DomEvent, root: RootState, previous?: RootState) => void
226
228
 
229
+ /** Configuration for XR pointer registration (controllers/hands) */
230
+ interface XRPointerConfig {
231
+ /** Ray origin (updated each frame by XR system) */
232
+ ray: THREE$1.Ray
233
+ /** Optional: custom compute function for this pointer */
234
+ compute?: (state: RootState) => void
235
+ /** Pointer type identifier */
236
+ type: 'controller' | 'hand' | 'gaze'
237
+ /** Which hand (for controller/hand types) */
238
+ handedness?: 'left' | 'right'
239
+ }
240
+
227
241
  interface EventManager<TTarget> {
228
242
  /** Determines if the event layer is active */
229
243
  enabled: boolean
@@ -243,8 +257,21 @@ interface EventManager<TTarget> {
243
257
  disconnect?: () => void
244
258
  /** Triggers a onPointerMove with the last known event. This can be useful to enable raycasting without
245
259
  * explicit user interaction, for instance when the camera moves a hoverable object underneath the cursor.
260
+ * @param pointerId - Optional pointer ID to update specific pointer only
246
261
  */
247
- update?: () => void
262
+ update?: (pointerId?: number) => void
263
+ /** Defer pointer move raycasting to frame start (default: true) */
264
+ frameTimedRaycasts?: boolean
265
+ /** Always fire raycaster immediately on scroll events (default: true) */
266
+ alwaysFireOnScroll?: boolean
267
+ /** Automatically re-raycast every frame to detect hover changes from moving objects/camera (default: false) */
268
+ updateOnFrame?: boolean
269
+ /** Flush deferred pointer raycasts. Called by scheduler at frame start (input phase). */
270
+ flush?: () => void
271
+ /** Register an XR pointer (controller/hand). Returns assigned pointerId */
272
+ registerPointer?: (config: XRPointerConfig) => number
273
+ /** Unregister an XR pointer */
274
+ unregisterPointer?: (pointerId: number) => void
248
275
  }
249
276
 
250
277
  interface PointerCaptureTarget {
@@ -486,6 +513,68 @@ interface SchedulerApi {
486
513
  subscribeJobState(id: string, listener: () => void): () => void
487
514
  }
488
515
 
516
+ //* Buffer Types (useBuffers) ========================================
517
+
518
+ /**
519
+ * Buffer-like types for GPU compute and storage operations.
520
+ * Includes raw CPU arrays, Three.js buffer attributes, and TSL buffer nodes.
521
+ *
522
+ * @example
523
+ * ```tsx
524
+ * const { positions, velocities } = useBuffers(() => ({
525
+ * positions: instancedArray(count, 'vec3'), // StorageBufferNode
526
+ * velocities: new Float32Array(count * 3), // TypedArray
527
+ * }), 'particles')
528
+ * ```
529
+ */
530
+ type BufferLike =
531
+ | Float32Array
532
+ | Uint32Array
533
+ | Int32Array
534
+ | Float64Array
535
+ | Uint8Array
536
+ | Int8Array
537
+ | Uint16Array
538
+ | Int16Array
539
+ | THREE$1.BufferAttribute // Base class for all buffer attributes
540
+ | Node // TSL buffer nodes (instancedArray, storage)
541
+
542
+ /** Flat record of buffer-like values (no nested scopes) */
543
+ type BufferRecord = Record<string, BufferLike>
544
+
545
+ /**
546
+ * Buffer store that can contain both root-level buffers and scoped buffer objects.
547
+ * Structure: { positions: Float32Array, particles: { vel: StorageBufferNode } }
548
+ */
549
+ type BufferStore = Record<string, BufferLike | BufferRecord>
550
+
551
+ //* Storage Types (useGPUStorage) ========================================
552
+
553
+ /**
554
+ * GPU storage types for texture-based storage operations.
555
+ * Includes Three.js storage textures and TSL storage texture nodes.
556
+ *
557
+ * @example
558
+ * ```tsx
559
+ * const { heightMap } = useGPUStorage(() => ({
560
+ * heightMap: new StorageTexture(512, 512),
561
+ * }), 'terrain')
562
+ * ```
563
+ */
564
+ type StorageLike =
565
+ | StorageTexture // GPU storage texture
566
+ | Data3DTexture // 3D texture (can be used as storage)
567
+ | Node // TSL storage texture nodes (storageTexture)
568
+
569
+ /** Flat record of storage-like values (no nested scopes) */
570
+ type StorageRecord = Record<string, StorageLike>
571
+
572
+ /**
573
+ * Storage store that can contain both root-level storage and scoped storage objects.
574
+ * Structure: { heightMap: StorageTexture, terrain: { normal: StorageTextureNode } }
575
+ */
576
+ type StorageStore = Record<string, StorageLike | StorageRecord>
577
+
489
578
  //* Renderer Types ========================================
490
579
 
491
580
  /** Default renderer type - union of WebGL and WebGPU renderers */
@@ -499,6 +588,18 @@ type Subscription = {
499
588
  store: RootStore
500
589
  }
501
590
 
591
+ /** Per-pointer state for multi-touch and XR support */
592
+ type PointerState = {
593
+ /** Objects currently hovered by this pointer */
594
+ hovered: Map<string, ThreeEvent<DomEvent>>
595
+ /** Objects capturing this pointer */
596
+ captured: Map<THREE$1.Object3D, PointerCaptureTarget>
597
+ /** Initial click position [x, y] */
598
+ initialClick: [x: number, y: number]
599
+ /** Objects hit on initial click */
600
+ initialHits: THREE$1.Object3D[]
601
+ }
602
+
502
603
  type Dpr = number | [min: number, max: number]
503
604
 
504
605
  interface Size {
@@ -540,12 +641,21 @@ interface Performance {
540
641
 
541
642
  interface InternalState {
542
643
  interaction: THREE$1.Object3D[]
543
- hovered: Map<string, ThreeEvent<DomEvent>>
544
644
  subscribers: Subscription[]
645
+ /** Per-pointer state (hover, capture, click tracking) - replaces hovered, capturedMap, initialClick, initialHits */
646
+ pointerMap: Map<number, PointerState>
647
+ /** Pointers needing raycast this frame (used with frameTimedRaycasts) */
648
+ pointerDirty: Map<number, DomEvent>
649
+ /** Last event received (for events.update() compatibility) */
650
+ lastEvent: React$1.RefObject<DomEvent | null>
651
+ /** @deprecated Use pointerMap.get(pointerId).hovered instead */
652
+ hovered: Map<string, ThreeEvent<DomEvent>>
653
+ /** @deprecated Use pointerMap.get(pointerId).captured instead */
545
654
  capturedMap: Map<number, Map<THREE$1.Object3D, PointerCaptureTarget>>
655
+ /** @deprecated Use pointerMap.get(pointerId).initialClick instead */
546
656
  initialClick: [x: number, y: number]
657
+ /** @deprecated Use pointerMap.get(pointerId).initialHits instead */
547
658
  initialHits: THREE$1.Object3D[]
548
- lastEvent: React$1.RefObject<DomEvent | null>
549
659
  /** Visibility event registry (onFramed, onOccluded, onVisible) */
550
660
  visibilityRegistry: Map<string, VisibilityEntry>
551
661
  /** Whether occlusion queries are enabled (WebGPU only) */
@@ -686,11 +796,17 @@ interface RootState {
686
796
  uniforms: UniformStore
687
797
  /** Global TSL nodes - root-level nodes + scoped sub-objects. Use useNodes() hook */
688
798
  nodes: Record<string, any>
689
- /** Global TSL texture nodes - use useTextures() hook for operations */
690
- textures: Map<string, any>
691
- /** WebGPU PostProcessing instance - use usePostProcessing() hook */
692
- postProcessing: any | null // THREE.PostProcessing when available
693
- /** Global TSL pass nodes for post-processing - use usePostProcessing() hook */
799
+ /** Global TSL buffer nodes - root-level buffers + scoped sub-objects. Use useBuffers() hook */
800
+ buffers: BufferStore
801
+ /** Global GPU storage (textures, etc.) - root-level storage + scoped sub-objects. Use useGPUStorage() hook */
802
+ gpuStorage: StorageStore
803
+ /** Global Texture registry (key Texture, usually keyed by URL) - use useTextures() hook for access + lifecycle */
804
+ textures: Map<string, THREE$1.Texture>
805
+ /** Internal: refcount per texture key, driven by mounted useTexture consumers (registry enrollment is on by default) */
806
+ _textureRefs: Map<string, number>
807
+ /** WebGPU RenderPipeline instance - use useRenderPipeline() hook */
808
+ renderPipeline: any | null // THREE.PostProcessing (will be THREE.RenderPipeline in future Three.js release)
809
+ /** Global TSL pass nodes for render pipeline - use useRenderPipeline() hook */
694
810
  passes: Record<string, any>
695
811
  /** Internal version counter for HMR - incremented by rebuildNodes/rebuildUniforms to bust memoization */
696
812
  _hmrVersion: number
@@ -740,6 +856,20 @@ interface Renderer {
740
856
  render: (scene: THREE$1.Scene, camera: THREE$1.Camera) => any
741
857
  }
742
858
 
859
+ //* Color Management Config ==============================
860
+
861
+ /**
862
+ * Color management configuration shared by both WebGL and WebGPU renderers.
863
+ */
864
+ interface ColorManagementConfig {
865
+ /**
866
+ * Color space assigned to 8-bit input textures (color maps).
867
+ * Defaults to sRGB. Most textures are authored in sRGB.
868
+ * @default THREE.SRGBColorSpace
869
+ */
870
+ textureColorSpace?: THREE$1.ColorSpace
871
+ }
872
+
743
873
  //* WebGL Renderer Props ==============================
744
874
 
745
875
  type DefaultGLProps = Omit<THREE$1.WebGLRendererParameters, 'canvas'> & {
@@ -750,7 +880,7 @@ type GLProps =
750
880
  | Renderer
751
881
  | ((defaultProps: DefaultGLProps) => Renderer)
752
882
  | ((defaultProps: DefaultGLProps) => Promise<Renderer>)
753
- | Partial<Properties<THREE$1.WebGLRenderer> | THREE$1.WebGLRendererParameters>
883
+ | (Partial<Properties<THREE$1.WebGLRenderer> | THREE$1.WebGLRendererParameters> & ColorManagementConfig)
754
884
 
755
885
  //* WebGPU Renderer Props ==============================
756
886
 
@@ -776,9 +906,9 @@ interface CanvasSchedulerConfig {
776
906
  }
777
907
 
778
908
  /**
779
- * Extended renderer configuration for multi-canvas support.
909
+ * Extended renderer configuration for multi-canvas support and color management.
780
910
  */
781
- interface RendererConfigExtended {
911
+ interface RendererConfigExtended extends ColorManagementConfig {
782
912
  /** Share renderer from another canvas (WebGPU only) */
783
913
  primaryCanvas?: string
784
914
  /** Canvas-level scheduler options */
@@ -843,8 +973,6 @@ interface RenderProps<TCanvas extends HTMLCanvasElement | OffscreenCanvas$1> {
843
973
  * @see https://threejs.org/docs/#api/en/renderers/WebGLRenderer.shadowMap
844
974
  */
845
975
  shadows?: boolean | 'basic' | 'percentage' | 'soft' | 'variance' | Partial<THREE$1.WebGLShadowMap>
846
- /** Color space assigned to 8-bit input textures (color maps). Defaults to sRGB. Most textures are authored in sRGB. */
847
- textureColorSpace?: THREE$1.ColorSpace
848
976
  /** Creates an orthographic camera */
849
977
  orthographic?: boolean
850
978
  /**
@@ -1097,7 +1225,7 @@ interface CanvasProps
1097
1225
  */
1098
1226
  resize?: Options
1099
1227
  /** The target where events are being subscribed to, default: the div that wraps canvas */
1100
- eventSource?: HTMLElement | React$1.RefObject<HTMLElement>
1228
+ eventSource?: HTMLElement | React$1.RefObject<HTMLElement | null>
1101
1229
  /** The event prefix that is cast into canvas pointer x/y events, default: "offset" */
1102
1230
  eventPrefix?: 'offset' | 'client' | 'page' | 'layer' | 'screen'
1103
1231
  /** Enable/disable automatic HMR refresh for TSL nodes and uniforms, default: true in dev */
@@ -1311,6 +1439,7 @@ declare global {
1311
1439
  | three_webgpu.Euler
1312
1440
  | three_webgpu.Quaternion
1313
1441
  | { x: number; y?: number; z?: number; w?: number } // Plain objects converted to vectors
1442
+ | { r: number; g: number; b: number; a?: number } // Plain objects converted to Color
1314
1443
  | Node // TSL nodes like color(), vec3(), float() for type casting
1315
1444
  | UniformNode
1316
1445
 
@@ -1356,34 +1485,34 @@ declare module 'three/tsl' {
1356
1485
  }
1357
1486
 
1358
1487
  /**
1359
- * PostProcessing Types for usePostProcessing hook (WebGPU only)
1488
+ * RenderPipeline Types for useRenderPipeline hook (WebGPU only)
1360
1489
  */
1361
1490
 
1362
1491
 
1363
1492
 
1364
1493
  declare global {
1365
- /** Pass record - stores TSL pass nodes for post-processing */
1494
+ /** Pass record - stores TSL pass nodes for render pipeline */
1366
1495
  type PassRecord = Record<string, any>
1367
1496
 
1368
1497
  /** Setup callback - runs first to configure MRT, create additional passes */
1369
- type PostProcessingSetupCallback = (state: RootState) => PassRecord | void
1498
+ type RenderPipelineSetupCallback = (state: RootState) => PassRecord | void
1370
1499
 
1371
1500
  /** Main callback - runs second to configure outputNode, create effect passes */
1372
- type PostProcessingMainCallback = (state: RootState) => PassRecord | void
1501
+ type RenderPipelineMainCallback = (state: RootState) => PassRecord | void
1373
1502
 
1374
- /** Return type for usePostProcessing hook */
1375
- interface UsePostProcessingReturn {
1503
+ /** Return type for useRenderPipeline hook */
1504
+ interface UseRenderPipelineReturn {
1376
1505
  /** Current passes from state */
1377
1506
  passes: PassRecord
1378
- /** PostProcessing instance (null if not initialized) */
1379
- postProcessing: any | null // THREE.PostProcessing
1507
+ /** RenderPipeline instance (null if not initialized) */
1508
+ renderPipeline: any | null // THREE.PostProcessing (will be THREE.RenderPipeline in future Three.js release)
1380
1509
  /** Clear all passes from state */
1381
1510
  clearPasses: () => void
1382
- /** Reset PostProcessing entirely (clears PP + passes) */
1511
+ /** Reset RenderPipeline entirely (clears PP + passes) */
1383
1512
  reset: () => void
1384
1513
  /** Re-run setup/main callbacks with current closure values */
1385
1514
  rebuild: () => void
1386
- /** True when PostProcessing is configured and ready */
1515
+ /** True when RenderPipeline is configured and ready */
1387
1516
  isReady: boolean
1388
1517
  }
1389
1518
  }
@@ -2003,6 +2132,8 @@ declare function Environment(props: EnvironmentProps): react_jsx_runtime.JSX.Ele
2003
2132
  declare function removeInteractivity(store: RootStore, object: Object3D): void;
2004
2133
  declare function createEvents(store: RootStore): {
2005
2134
  handlePointer: (name: string) => (event: DomEvent) => void;
2135
+ flushDeferredPointers: () => void;
2136
+ processDeferredPointer: (event: DomEvent, pointerId: number) => void;
2006
2137
  };
2007
2138
  /** Default R3F event manager for web */
2008
2139
  declare function createPointerEvents(store: RootStore): EventManager<HTMLElement>;
@@ -2443,11 +2574,16 @@ type UseTextureOptions<Url extends string[] | string | Record<string, string>> =
2443
2574
  /** Callback when texture(s) finish loading */
2444
2575
  onLoad?: (texture: MappedTextureType<Url>) => void;
2445
2576
  /**
2446
- * Cache the texture in R3F's global state for access via useTextures().
2447
- * When true:
2577
+ * Register the texture(s) in R3F's global texture registry for access via useTextures().
2578
+ * When true (the default):
2448
2579
  * - Textures persist until explicitly disposed
2449
- * - Returns existing cached textures if available (preserving modifications like colorSpace)
2450
- * @default false
2580
+ * - On mount, returns existing registered textures if available (preserving modifications like colorSpace)
2581
+ *
2582
+ * Reads are taken once at mount — a mounted `useTexture` does not re-render when the registry
2583
+ * changes. To react to registry swaps, use `useTextures(s => s.get(key))` instead.
2584
+ *
2585
+ * Pass `false` to opt out of registry enrollment entirely.
2586
+ * @default true
2451
2587
  */
2452
2588
  cache?: boolean;
2453
2589
  };
@@ -2471,15 +2607,18 @@ type UseTextureOptions<Url extends string[] | string | Record<string, string>> =
2471
2607
  * normal: '/normal.png'
2472
2608
  * })
2473
2609
  *
2474
- * // With caching - returns same texture object across components
2475
- * // Modifications (colorSpace, wrapS, etc.) are preserved
2476
- * const diffuse = useTexture('/diffuse.png', { cache: true })
2610
+ * // Textures are registered in the global registry by default — the same texture
2611
+ * // object is shared across components and modifications (colorSpace, wrapS, etc.) are preserved
2612
+ * const diffuse = useTexture('/diffuse.png')
2477
2613
  * diffuse.colorSpace = THREE.SRGBColorSpace
2478
2614
  *
2479
2615
  * // Another component gets the SAME texture with colorSpace already set
2480
- * const sameDiffuse = useTexture('/diffuse.png', { cache: true })
2616
+ * const sameDiffuse = useTexture('/diffuse.png')
2617
+ *
2618
+ * // Opt out of registry enrollment for a one-off texture
2619
+ * const scratch = useTexture('/scratch.png', { cache: false })
2481
2620
  *
2482
- * // Access cache directly
2621
+ * // Access the registry directly
2483
2622
  * const { get } = useTextures()
2484
2623
  * const cached = get('/diffuse.png')
2485
2624
  * ```
@@ -2496,63 +2635,80 @@ declare const Texture: ({ children, input, onLoad, cache, }: {
2496
2635
  cache?: boolean;
2497
2636
  }) => react_jsx_runtime.JSX.Element;
2498
2637
 
2499
- type TextureEntry = Texture$1 | {
2500
- value: Texture$1;
2501
- [key: string]: any;
2638
+ /** Accepted shapes for a registry read: a single key, a list of keys, or a name→key map. */
2639
+ type TextureInput = string | string[] | Record<string, string>;
2640
+ /** Result of a `get()` read, mirroring the input shape. */
2641
+ type TextureResult<Input extends TextureInput> = Input extends string ? Texture$1 | undefined : Input extends string[] ? (Texture$1 | undefined)[] : {
2642
+ [K in keyof Input]: Texture$1 | undefined;
2502
2643
  };
2644
+ /** Options for `dispose()`. */
2645
+ interface DisposeOptions {
2646
+ /** Dispose even if the texture still has active references (default false). */
2647
+ force?: boolean;
2648
+ }
2503
2649
  interface UseTexturesReturn {
2504
- /** Map of all textures currently in cache */
2505
- textures: Map<string, TextureEntry>;
2506
- /** Get a specific texture by key (usually URL) */
2507
- get: (key: string) => TextureEntry | undefined;
2508
- /** Check if a texture exists in cache */
2509
- has: (key: string) => boolean;
2510
- /** Add a texture to the cache */
2511
- add: (key: string, value: TextureEntry) => void;
2512
- /** Add multiple textures to the cache */
2513
- addMultiple: (items: Map<string, TextureEntry> | Record<string, TextureEntry>) => void;
2514
- /** Remove a texture from cache (does NOT dispose GPU resources) */
2515
- remove: (key: string) => void;
2516
- /** Remove multiple textures from cache */
2517
- removeMultiple: (keys: string[]) => void;
2518
- /** Dispose a texture's GPU resources and remove from cache */
2519
- dispose: (key: string) => void;
2520
- /** Dispose multiple textures */
2521
- disposeMultiple: (keys: string[]) => void;
2522
- /** Dispose ALL cached textures - use with caution */
2523
- disposeAll: () => void;
2650
+ /** The live registry Map (key Texture). Treat as read-only. */
2651
+ readonly all: Map<string, Texture$1>;
2652
+ /** Read one texture, an array of textures, or a name→texture record (mirrors the input shape). */
2653
+ get<Input extends TextureInput>(input: Input): TextureResult<Input>;
2654
+ /** Check whether a key exists in the registry. */
2655
+ has(key: string): boolean;
2656
+ /**
2657
+ * Register a texture (or a record of textures) that has no URL — e.g. a render
2658
+ * target or procedural texture. URL-loaded textures are registered automatically
2659
+ * by `useTexture` (registry enrollment is on by default).
2660
+ */
2661
+ add(key: string, texture: Texture$1): void;
2662
+ add(record: Record<string, Texture$1>): void;
2663
+ /**
2664
+ * Dispose a texture's GPU resources and remove it from the registry.
2665
+ * Refcount-aware: if the key is still in use by a mounted `useTexture` consumer it is
2666
+ * skipped (with a warning) unless `{ force: true }` is passed.
2667
+ * @returns true if disposed, false if skipped.
2668
+ */
2669
+ dispose(key: string, options?: DisposeOptions): boolean;
2670
+ /** Dispose every texture in the registry and clear it. Use on scene teardown. */
2671
+ disposeAll(): void;
2524
2672
  }
2525
2673
  /**
2526
- * Hook for managing the global texture cache in R3F state.
2674
+ * Reactive Texture registry load once with `useTexture`, reach the textures from anywhere.
2527
2675
  *
2528
- * Textures are stored in a Map with URL/path keys for efficient lookup.
2529
- * Useful for sharing texture references across materials and components.
2676
+ * This is a registry of plain `Texture` objects (not TSL nodes), so the same texture can feed
2677
+ * a material map, a heightmap sampler, or anything else. It does **not** load — pair it with
2678
+ * `useTexture` for loading (registry enrollment is on by default); `useTextures` is for access and lifecycle.
2679
+ *
2680
+ * The returned handle is **reactive**: the calling component re-renders when the registry
2681
+ * changes. Pass a selector to scope the subscription to a single read.
2530
2682
  *
2531
2683
  * @example
2532
2684
  * ```tsx
2533
- * const { textures, add, get, remove, has, dispose } = useTextures()
2685
+ * // Load + register once (anywhere in the tree) registered by default
2686
+ * useTexture({ map: '/diffuse.jpg', normalMap: '/normal.jpg' })
2534
2687
  *
2535
- * // Check if texture is already cached
2536
- * if (!has('/textures/diffuse.png')) {
2537
- * // Load with useTexture and cache: true, or manually add
2538
- * const tex = useTexture('/textures/diffuse.png', { cache: true })
2539
- * }
2688
+ * // Reach them from another component — record form lands straight into a material
2689
+ * const { map, normalMap } = useTextures().get({ map: '/diffuse.jpg', normalMap: '/normal.jpg' })
2690
+ * return <meshStandardMaterial map={map} normalMap={normalMap} />
2540
2691
  *
2541
- * // Access cached texture from anywhere
2542
- * const diffuse = get('/textures/diffuse.png')
2543
- * if (diffuse) material.map = diffuse
2692
+ * // A set of heightmaps at once
2693
+ * const [a, b, c] = useTextures().get(['/h0.png', '/h1.png', '/h2.png'])
2544
2694
  *
2545
- * // Remove from cache only (texture still in GPU memory)
2546
- * remove('/textures/old.png')
2695
+ * // Register a non-URL texture (render target / procedural)
2696
+ * useTextures().add('rt-main', renderTarget.texture)
2547
2697
  *
2548
- * // Fully dispose (frees GPU memory + removes from cache)
2549
- * dispose('/textures/unused.png')
2550
- *
2551
- * // Nuclear option - dispose everything
2552
- * disposeAll()
2698
+ * // Deliberate GPU cleanup (refcount-aware; force to override)
2699
+ * useTextures().dispose('/diffuse.jpg')
2700
+ * useTextures().disposeAll() // scene teardown
2553
2701
  * ```
2702
+ *
2703
+ * @remarks
2704
+ * **Future expansion:** an imperative async loader (e.g. `await useTextures().load('/x.jpg')`) is
2705
+ * intentionally not included yet. It would let non-React code (loading screens, dynamic streaming)
2706
+ * populate the registry without Suspense, at the cost of putting loading back into this hook. It
2707
+ * will be added only if a concrete consumer needs imperative loading; for now, loading lives in
2708
+ * `useTexture`.
2554
2709
  */
2555
2710
  declare function useTextures(): UseTexturesReturn;
2711
+ declare function useTextures<T>(selector: (registry: UseTexturesReturn) => T): T;
2556
2712
 
2557
2713
  /**
2558
2714
  * Creates a render target compatible with the current renderer.
@@ -2582,9 +2738,9 @@ declare function useTextures(): UseTexturesReturn;
2582
2738
  * const fbo = useRenderTarget(512, 256, { samples: 4 })
2583
2739
  * ```
2584
2740
  */
2585
- declare function useRenderTarget(options?: RenderTargetOptions): RenderTarget | WebGLRenderTarget;
2586
- declare function useRenderTarget(size: number, options?: RenderTargetOptions): RenderTarget | WebGLRenderTarget;
2587
- declare function useRenderTarget(width: number, height: number, options?: RenderTargetOptions): RenderTarget | WebGLRenderTarget;
2741
+ declare function useRenderTarget(options?: RenderTargetOptions): WebGLRenderTarget;
2742
+ declare function useRenderTarget(size: number, options?: RenderTargetOptions): WebGLRenderTarget;
2743
+ declare function useRenderTarget(width: number, height: number, options?: RenderTargetOptions): WebGLRenderTarget;
2588
2744
 
2589
2745
  /**
2590
2746
  * Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
@@ -4249,4 +4405,4 @@ declare function isOnce(value: unknown): value is {
4249
4405
  declare function Canvas(props: CanvasProps): react_jsx_runtime.JSX.Element;
4250
4406
 
4251
4407
  export { Block, Canvas, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, ErrorBoundary, FROM_REF, IsObject, ONCE, Portal, 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, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, fromRef, getInstanceProps, getPrimary, getPrimaryIds, getRootState, getScheduler, getUuidPrefix, hasConstructor, hasPrimary, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isFromRef, isObject3D, isOnce, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, once, prepare, presetsObj, reconciler, registerPrimary, removeInteractivity, resolve, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useEnvironment, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useMutableCallback, useRenderTarget, useStore, useTexture, useTextures, useThree, waitForPrimary };
4252
- export type { Act, AddPhaseOptions, Args, ArgsProp, AttachFnType, AttachType, BackgroundConfig, BackgroundProp, BaseRendererProps, Bridge, Camera, CameraProps, CanvasProps, CanvasSchedulerConfig, Catalogue, Color, ComputeFunction, ConstructorRepresentation, DefaultGLProps, DefaultRendererProps, Disposable, DomEvent, Dpr, ElementProps, EnvironmentLoaderProps, EnvironmentProps, EquConfig, Euler, EventHandlers, EventManager, EventProps, Events, Extensions, FiberRoot, FilterFunction, FrameCallback, FrameControls, FrameNextCallback, FrameNextControls, FrameNextState, FrameState, FrameTimingState, Frameloop, GLProps, GLTFLike, GeometryProps, GeometryTransformProps, GlobalEffectType, GlobalRenderCallback, HostConfig, InferLoadResult, InjectState, InputLike, Instance, InstanceProps, LegacyInternalState as InternalState, Intersection, IntersectionEvent, IsAllOptional, IsOptional, Layers, LegacyInternalState, LegacyRenderer, LegacyRootState, LoaderInstance, LoaderLike, LoaderResult, MappedTextureType, MathProps, MathRepresentation, MathType, MathTypes, Matrix3, Matrix4, Mutable, MutableOrReadonlyParameters, NodeProps, NonFunctionKeys, ObjectMap, OffscreenCanvas$1 as OffscreenCanvas, Overwrite, Performance, PointerCaptureTarget, PresetsType, PrimaryCanvasEntry, Properties, Quaternion, LegacyRenderer as R3FRenderer, RaycastableRepresentation, ReactProps, ReconcilerRoot, RenderCallback, RenderProps, RenderTargetOptions, Renderer, RendererConfigExtended, RendererFactory, RendererProps, Root, RootOptions, LegacyRootState as RootState, RootStore, SchedulerApi, SetBlock, Size, Subscription, TSLNodeInput, TextureEntry, ThreeCamera, ThreeElement, ThreeElements, ThreeElementsImpl, ThreeEvent, ThreeExports, ThreeToJSXElements, UnblockProps, UseFrameNextOptions, UseFrameOptions, UseTextureOptions, UseTexturesReturn, Vector2, Vector3, Vector4, VectorRepresentation, Viewport, VisibilityEntry, WebGLDefaultProps, WebGLProps, WebGLShadowConfig, XRManager };
4408
+ export type { Act, AddPhaseOptions, Args, ArgsProp, AttachFnType, AttachType, BackgroundConfig, BackgroundProp, BaseRendererProps, Bridge, BufferLike, BufferRecord, BufferStore, Camera, CameraProps, CanvasProps, CanvasSchedulerConfig, Catalogue, Color, ColorManagementConfig, ComputeFunction, ConstructorRepresentation, DefaultGLProps, DefaultRendererProps, Disposable, DisposeOptions, DomEvent, Dpr, ElementProps, EnvironmentLoaderProps, EnvironmentProps, EquConfig, Euler, EventHandlers, EventManager, EventProps, Events, Extensions, FiberRoot, FilterFunction, FrameCallback, FrameControls, FrameNextCallback, FrameNextControls, FrameNextState, FrameState, FrameTimingState, Frameloop, GLProps, GLTFLike, GeometryProps, GeometryTransformProps, GlobalEffectType, GlobalRenderCallback, HostConfig, InferLoadResult, InjectState, InputLike, Instance, InstanceProps, LegacyInternalState as InternalState, Intersection, IntersectionEvent, IsAllOptional, IsOptional, Layers, LegacyInternalState, LegacyRenderer, LegacyRootState, LoaderInstance, LoaderLike, LoaderResult, MappedTextureType, MathProps, MathRepresentation, MathType, MathTypes, Matrix3, Matrix4, Mutable, MutableOrReadonlyParameters, NodeProps, NonFunctionKeys, ObjectMap, OffscreenCanvas$1 as OffscreenCanvas, Overwrite, Performance, PointerCaptureTarget, PointerState, PresetsType, PrimaryCanvasEntry, Properties, Quaternion, LegacyRenderer as R3FRenderer, RaycastableRepresentation, ReactProps, ReconcilerRoot, RenderCallback, RenderProps, RenderTargetOptions, Renderer, RendererConfigExtended, RendererFactory, RendererProps, Root, RootOptions, LegacyRootState as RootState, RootStore, SchedulerApi, SetBlock, Size, StorageLike, StorageRecord, StorageStore, Subscription, TSLNodeInput, TextureInput, TextureResult, ThreeCamera, ThreeElement, ThreeElements, ThreeElementsImpl, ThreeEvent, ThreeExports, ThreeToJSXElements, UnblockProps, UseFrameNextOptions, UseFrameOptions, UseTextureOptions, UseTexturesReturn, Vector2, Vector3, Vector4, VectorRepresentation, Viewport, VisibilityEntry, WebGLDefaultProps, WebGLProps, WebGLShadowConfig, XRManager, XRPointerConfig };