@react-three/fiber 10.0.0-canary.2c50459 → 10.0.0-canary.4a21acb
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/index.cjs +214 -107
- package/dist/index.d.cts +49 -25
- package/dist/index.d.mts +49 -25
- package/dist/index.d.ts +49 -25
- package/dist/index.mjs +216 -109
- package/dist/legacy.cjs +169 -62
- package/dist/legacy.d.cts +49 -24
- package/dist/legacy.d.mts +49 -24
- package/dist/legacy.d.ts +49 -24
- package/dist/legacy.mjs +170 -63
- package/dist/webgpu/index.cjs +501 -635
- package/dist/webgpu/index.d.cts +83 -29
- package/dist/webgpu/index.d.mts +83 -29
- package/dist/webgpu/index.d.ts +83 -29
- package/dist/webgpu/index.mjs +503 -637
- package/package.json +3 -3
- package/readme.md +0 -1
package/dist/legacy.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as three from 'three';
|
|
2
|
-
import { WebGLRenderTarget, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, Scene,
|
|
2
|
+
import { WebGLCubeRenderTarget, WebGLRenderTarget, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, Scene, HalfFloatType, Color, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, ShaderMaterial, Uniform, SRGBColorSpace, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1, Raycaster, OrthographicCamera, PerspectiveCamera, PCFShadowMap, VSMShadowMap, BasicShadowMap, ACESFilmicToneMapping, WebGLRenderer } from 'three';
|
|
3
3
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import React__default, { useLayoutEffect, useRef, useMemo, useEffect, useContext, useImperativeHandle, useCallback, useState } from 'react';
|
|
@@ -42,9 +42,12 @@ const WebGPURenderer = class WebGPURenderer2 {
|
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
const RenderTarget = null;
|
|
45
|
+
const CubeRenderTarget = null;
|
|
45
46
|
|
|
46
47
|
const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
47
48
|
__proto__: null,
|
|
49
|
+
CubeRenderTarget: CubeRenderTarget,
|
|
50
|
+
CubeRenderTargetCompat: WebGLCubeRenderTarget,
|
|
48
51
|
Inspector: Inspector,
|
|
49
52
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
50
53
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
@@ -322,15 +325,16 @@ function EnvironmentPortal({
|
|
|
322
325
|
preset = void 0,
|
|
323
326
|
extensions
|
|
324
327
|
}) {
|
|
325
|
-
const
|
|
328
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
329
|
+
const isLegacy = useThree$1((state) => state.isLegacy);
|
|
326
330
|
const defaultScene = useThree$1((state) => state.scene);
|
|
327
331
|
const camera = React.useRef(null);
|
|
328
332
|
const [virtualScene] = React.useState(() => new Scene());
|
|
329
333
|
const fbo = React.useMemo(() => {
|
|
330
|
-
const fbo2 = new WebGLCubeRenderTarget(resolution);
|
|
334
|
+
const fbo2 = isLegacy ? new WebGLCubeRenderTarget(resolution) : new CubeRenderTarget(resolution);
|
|
331
335
|
fbo2.texture.type = HalfFloatType;
|
|
332
336
|
return fbo2;
|
|
333
|
-
}, [resolution]);
|
|
337
|
+
}, [resolution, isLegacy]);
|
|
334
338
|
React.useEffect(() => {
|
|
335
339
|
return () => {
|
|
336
340
|
fbo.dispose();
|
|
@@ -338,10 +342,10 @@ function EnvironmentPortal({
|
|
|
338
342
|
}, [fbo]);
|
|
339
343
|
React.useLayoutEffect(() => {
|
|
340
344
|
if (frames === 1) {
|
|
341
|
-
const autoClear =
|
|
342
|
-
|
|
343
|
-
camera.current.update(
|
|
344
|
-
|
|
345
|
+
const autoClear = renderer.autoClear;
|
|
346
|
+
renderer.autoClear = true;
|
|
347
|
+
camera.current.update(renderer, virtualScene);
|
|
348
|
+
renderer.autoClear = autoClear;
|
|
345
349
|
}
|
|
346
350
|
return setEnvProps(background, scene, defaultScene, fbo.texture, {
|
|
347
351
|
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
@@ -358,7 +362,7 @@ function EnvironmentPortal({
|
|
|
358
362
|
defaultScene,
|
|
359
363
|
background,
|
|
360
364
|
frames,
|
|
361
|
-
|
|
365
|
+
renderer,
|
|
362
366
|
blur,
|
|
363
367
|
backgroundBlurriness,
|
|
364
368
|
backgroundIntensity,
|
|
@@ -369,10 +373,10 @@ function EnvironmentPortal({
|
|
|
369
373
|
let count = 1;
|
|
370
374
|
useFrame$1(() => {
|
|
371
375
|
if (frames === Infinity || count < frames) {
|
|
372
|
-
const autoClear =
|
|
373
|
-
|
|
374
|
-
camera.current.update(
|
|
375
|
-
|
|
376
|
+
const autoClear = renderer.autoClear;
|
|
377
|
+
renderer.autoClear = true;
|
|
378
|
+
camera.current.update(renderer, virtualScene);
|
|
379
|
+
renderer.autoClear = autoClear;
|
|
376
380
|
count++;
|
|
377
381
|
}
|
|
378
382
|
});
|
|
@@ -615,8 +619,7 @@ function prepare(target, root, type, props) {
|
|
|
615
619
|
object,
|
|
616
620
|
eventCount: 0,
|
|
617
621
|
handlers: {},
|
|
618
|
-
isHidden: false
|
|
619
|
-
deferredRefs: []
|
|
622
|
+
isHidden: false
|
|
620
623
|
};
|
|
621
624
|
if (object) object.__r3f = instance;
|
|
622
625
|
}
|
|
@@ -773,6 +776,17 @@ function unregisterVisibility(store, object) {
|
|
|
773
776
|
internal.visibilityRegistry.delete(object.uuid);
|
|
774
777
|
internal.occlusionCache.delete(object);
|
|
775
778
|
}
|
|
779
|
+
function updateVisibilityHandlers(store, object, handlers) {
|
|
780
|
+
const { internal } = store.getState();
|
|
781
|
+
const entry = internal.visibilityRegistry.get(object.uuid);
|
|
782
|
+
if (!entry) return false;
|
|
783
|
+
entry.handlers = handlers;
|
|
784
|
+
if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
|
|
785
|
+
object.occlusionTest = true;
|
|
786
|
+
enableOcclusion(store);
|
|
787
|
+
}
|
|
788
|
+
return true;
|
|
789
|
+
}
|
|
776
790
|
function checkVisibility(state) {
|
|
777
791
|
const { internal, camera } = state;
|
|
778
792
|
const registry = internal.visibilityRegistry;
|
|
@@ -960,10 +974,7 @@ function applyProps(object, props) {
|
|
|
960
974
|
continue;
|
|
961
975
|
}
|
|
962
976
|
if (value === void 0) continue;
|
|
963
|
-
if (isFromRef(value))
|
|
964
|
-
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
965
|
-
continue;
|
|
966
|
-
}
|
|
977
|
+
if (isFromRef(value)) continue;
|
|
967
978
|
if (isOnce(value)) {
|
|
968
979
|
if (instance?.appliedOnce?.has(prop)) continue;
|
|
969
980
|
if (instance) {
|
|
@@ -999,6 +1010,19 @@ function applyProps(object, props) {
|
|
|
999
1010
|
} else if (isVectorLike(target) && is.num(value)) {
|
|
1000
1011
|
if ("setScalar" in target && typeof target.setScalar === "function") target.setScalar(value);
|
|
1001
1012
|
else target.set(value);
|
|
1013
|
+
} else if (root instanceof ShaderMaterial && key === "uniforms" && is.obj(value)) {
|
|
1014
|
+
if (!is.obj(root.uniforms)) root.uniforms = {};
|
|
1015
|
+
const uniforms = root.uniforms;
|
|
1016
|
+
const nextUniforms = value;
|
|
1017
|
+
for (const name in nextUniforms) {
|
|
1018
|
+
const uniform = nextUniforms[name];
|
|
1019
|
+
const targetUniform = uniforms[name];
|
|
1020
|
+
if (targetUniform) Object.assign(targetUniform, uniform);
|
|
1021
|
+
else {
|
|
1022
|
+
const nextUniform = uniform instanceof Uniform ? uniform.clone() : new Uniform(uniform.value);
|
|
1023
|
+
uniforms[name] = nextUniform;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1002
1026
|
} else {
|
|
1003
1027
|
root[key] = value;
|
|
1004
1028
|
if (key.endsWith("Node") && root.isMaterial) {
|
|
@@ -1017,6 +1041,9 @@ function applyProps(object, props) {
|
|
|
1017
1041
|
if (instance.eventCount && object2.raycast !== null) {
|
|
1018
1042
|
rootState.internal.interaction.push(object2);
|
|
1019
1043
|
}
|
|
1044
|
+
}
|
|
1045
|
+
if (instance?.parent && rootState?.internal && instance.object?.isObject3D) {
|
|
1046
|
+
const object2 = instance.object;
|
|
1020
1047
|
const root = findInitialRoot(instance);
|
|
1021
1048
|
const visibilityHandlers = {
|
|
1022
1049
|
onFramed: instance.handlers.onFramed,
|
|
@@ -1024,7 +1051,9 @@ function applyProps(object, props) {
|
|
|
1024
1051
|
onVisible: instance.handlers.onVisible
|
|
1025
1052
|
};
|
|
1026
1053
|
if (hasVisibilityHandlers(visibilityHandlers)) {
|
|
1027
|
-
|
|
1054
|
+
if (!updateVisibilityHandlers(root, object2, visibilityHandlers)) {
|
|
1055
|
+
registerVisibility(root, object2, visibilityHandlers);
|
|
1056
|
+
}
|
|
1028
1057
|
} else {
|
|
1029
1058
|
unregisterVisibility(root, object2);
|
|
1030
1059
|
}
|
|
@@ -1552,6 +1581,7 @@ function createPointerEvents(store) {
|
|
|
1552
1581
|
set((state) => ({ events: { ...state.events, connected: void 0 } }));
|
|
1553
1582
|
}
|
|
1554
1583
|
},
|
|
1584
|
+
// PREVIEW (A8): the XR pointer registration API may change before stable.
|
|
1555
1585
|
registerPointer: (config) => {
|
|
1556
1586
|
const pointerId = nextXRPointerId++;
|
|
1557
1587
|
xrPointers.set(pointerId, config);
|
|
@@ -1638,6 +1668,13 @@ function notifyAlpha({ message, link }) {
|
|
|
1638
1668
|
}
|
|
1639
1669
|
}
|
|
1640
1670
|
|
|
1671
|
+
const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
|
|
1672
|
+
function isInternalRendererAccess(stack, callerDepth = 2) {
|
|
1673
|
+
if (!stack) return false;
|
|
1674
|
+
const caller = stack.split("\n")[callerDepth] ?? "";
|
|
1675
|
+
return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1641
1678
|
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
1642
1679
|
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React.createContext(null));
|
|
1643
1680
|
const createStore = (invalidate, advance) => {
|
|
@@ -1770,6 +1807,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1770
1807
|
}),
|
|
1771
1808
|
setFrameloop: (frameloop = "always") => {
|
|
1772
1809
|
set(() => ({ frameloop }));
|
|
1810
|
+
getScheduler().frameloop = frameloop;
|
|
1773
1811
|
},
|
|
1774
1812
|
setError: (error) => set(() => ({ error })),
|
|
1775
1813
|
error: null,
|
|
@@ -1837,8 +1875,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1837
1875
|
const currentState = rootStore.getState();
|
|
1838
1876
|
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1839
1877
|
const stack = new Error().stack || "";
|
|
1840
|
-
|
|
1841
|
-
if (!isInternalAccess) {
|
|
1878
|
+
if (!isInternalRendererAccess(stack)) {
|
|
1842
1879
|
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1843
1880
|
notifyDepreciated({
|
|
1844
1881
|
heading: "Accessing state.gl in WebGPU mode",
|
|
@@ -1951,19 +1988,25 @@ function loadingFn(extensions, onProgress) {
|
|
|
1951
1988
|
);
|
|
1952
1989
|
};
|
|
1953
1990
|
}
|
|
1954
|
-
function useLoader(loader, input, extensions, onProgress) {
|
|
1955
|
-
const
|
|
1991
|
+
function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
1992
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
1993
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
1956
1994
|
const fn = loadingFn(extensions, onProgress);
|
|
1957
|
-
const results =
|
|
1995
|
+
const results = cacheKeys.map(
|
|
1996
|
+
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1997
|
+
);
|
|
1958
1998
|
return Array.isArray(input) ? results : results[0];
|
|
1959
1999
|
}
|
|
1960
|
-
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
1961
|
-
const
|
|
1962
|
-
|
|
2000
|
+
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
2001
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
2002
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
2003
|
+
cacheKeys.forEach(
|
|
2004
|
+
(key, index) => preload(() => loadingFn(extensions, onProgress)(loader, inputs[index]), [loader, key])
|
|
2005
|
+
);
|
|
1963
2006
|
};
|
|
1964
|
-
useLoader.clear = function(loader, input) {
|
|
1965
|
-
const
|
|
1966
|
-
|
|
2007
|
+
useLoader.clear = function(loader, input, cacheKey) {
|
|
2008
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
2009
|
+
cacheKeys.forEach((key) => clear([loader, key]));
|
|
1967
2010
|
};
|
|
1968
2011
|
useLoader.loader = getLoader;
|
|
1969
2012
|
|
|
@@ -2383,7 +2426,7 @@ function advance(timestamp) {
|
|
|
2383
2426
|
getScheduler().step(timestamp);
|
|
2384
2427
|
}
|
|
2385
2428
|
|
|
2386
|
-
const version = "10.0.0-alpha.
|
|
2429
|
+
const version = "10.0.0-alpha.3";
|
|
2387
2430
|
const packageData = {
|
|
2388
2431
|
version: version};
|
|
2389
2432
|
|
|
@@ -13822,6 +13865,7 @@ function swapInstances() {
|
|
|
13822
13865
|
}
|
|
13823
13866
|
}
|
|
13824
13867
|
if (instance.isHidden) unhideInstance(instance);
|
|
13868
|
+
if (isObject3D(instance.object)) removeInteractivity(findInitialRoot(instance), instance.object);
|
|
13825
13869
|
if (instance.object.__r3f) delete instance.object.__r3f;
|
|
13826
13870
|
if (instance.type !== "primitive") disposeOnIdle(instance.object);
|
|
13827
13871
|
}
|
|
@@ -13834,6 +13878,8 @@ function swapInstances() {
|
|
|
13834
13878
|
instance.object.__r3f = instance;
|
|
13835
13879
|
setFiberRef(fiber, instance.object);
|
|
13836
13880
|
delete instance.appliedOnce;
|
|
13881
|
+
instance.eventCount = 0;
|
|
13882
|
+
instance.handlers = {};
|
|
13837
13883
|
applyProps(instance.object, instance.props);
|
|
13838
13884
|
if (instance.props.attach) {
|
|
13839
13885
|
attach(parent, instance);
|
|
@@ -14049,11 +14095,15 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14049
14095
|
cloneMutableTextInstance(textInstance) {
|
|
14050
14096
|
return textInstance;
|
|
14051
14097
|
},
|
|
14098
|
+
// React 19.2 added these for root-level view transitions. They only run for hosts that opt into
|
|
14099
|
+
// view transitions by returning a container from cloneRootViewTransitionContainer; R3F renders
|
|
14100
|
+
// into a WebGL/WebGPU canvas, where cloning the root has no meaning, so we never opt in and
|
|
14101
|
+
// React never calls them. They stay as no-ops rather than throws: the host config is shared by
|
|
14102
|
+
// every root, and a throw here would turn a React-internal probe into a hard crash for users.
|
|
14103
|
+
// Guarded by a test asserting a full render + unmount never reaches them.
|
|
14052
14104
|
cloneRootViewTransitionContainer(_rootContainer) {
|
|
14053
|
-
throw new Error("Not implemented.");
|
|
14054
14105
|
},
|
|
14055
14106
|
removeRootViewTransitionClone(_rootContainer, _clone) {
|
|
14056
|
-
throw new Error("Not implemented.");
|
|
14057
14107
|
},
|
|
14058
14108
|
// https://github.com/facebook/react/pull/32465
|
|
14059
14109
|
createFragmentInstance: (_fiber) => null,
|
|
@@ -14138,6 +14188,7 @@ function createRoot(canvas) {
|
|
|
14138
14188
|
const lastConfiguredProps = {};
|
|
14139
14189
|
let configured = false;
|
|
14140
14190
|
let pending = null;
|
|
14191
|
+
let rendererSetup = null;
|
|
14141
14192
|
return {
|
|
14142
14193
|
async configure(props = {}) {
|
|
14143
14194
|
let resolve;
|
|
@@ -14168,7 +14219,7 @@ function createRoot(canvas) {
|
|
|
14168
14219
|
forceEven
|
|
14169
14220
|
} = props;
|
|
14170
14221
|
const textureColorSpace = is.obj(glConfig) && !is.fun(glConfig) && !isRenderer(glConfig) && glConfig.textureColorSpace || is.obj(rendererConfig) && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && rendererConfig.textureColorSpace || SRGBColorSpace;
|
|
14171
|
-
|
|
14222
|
+
let state = store.getState();
|
|
14172
14223
|
const defaultGLProps = {
|
|
14173
14224
|
canvas,
|
|
14174
14225
|
powerPreference: "high-performance",
|
|
@@ -14196,9 +14247,21 @@ function createRoot(canvas) {
|
|
|
14196
14247
|
);
|
|
14197
14248
|
}
|
|
14198
14249
|
if (!state.internal.actualRenderer) {
|
|
14199
|
-
|
|
14200
|
-
|
|
14201
|
-
|
|
14250
|
+
if (!rendererSetup) {
|
|
14251
|
+
rendererSetup = (async () => {
|
|
14252
|
+
{
|
|
14253
|
+
renderer = await resolveRenderer(glConfig, defaultGLProps, WebGLRenderer);
|
|
14254
|
+
state.internal.actualRenderer = renderer;
|
|
14255
|
+
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
14256
|
+
}
|
|
14257
|
+
})().catch((err) => {
|
|
14258
|
+
rendererSetup = null;
|
|
14259
|
+
throw err;
|
|
14260
|
+
});
|
|
14261
|
+
}
|
|
14262
|
+
await rendererSetup;
|
|
14263
|
+
state = store.getState();
|
|
14264
|
+
renderer = state.internal.actualRenderer;
|
|
14202
14265
|
}
|
|
14203
14266
|
let raycaster = state.raycaster;
|
|
14204
14267
|
if (!raycaster) state.set({ raycaster: raycaster = new Raycaster() });
|
|
@@ -14548,7 +14611,8 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14548
14611
|
dispose(state.scene);
|
|
14549
14612
|
_roots.delete(canvas);
|
|
14550
14613
|
if (callback) callback(canvas);
|
|
14551
|
-
} catch {
|
|
14614
|
+
} catch (error) {
|
|
14615
|
+
console.warn("[R3F] Error while unmounting root; teardown may be incomplete:", error);
|
|
14552
14616
|
}
|
|
14553
14617
|
}, 500);
|
|
14554
14618
|
}
|
|
@@ -14611,6 +14675,7 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
14611
14675
|
viewport = rootState.viewport.getCurrentViewport(camera, new Vector3(), resolvedSize);
|
|
14612
14676
|
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14613
14677
|
}
|
|
14678
|
+
const set = injectState.set;
|
|
14614
14679
|
return {
|
|
14615
14680
|
// The intersect consists of the previous root state
|
|
14616
14681
|
...rootState,
|
|
@@ -14629,7 +14694,7 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
14629
14694
|
size: resolvedSize,
|
|
14630
14695
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14631
14696
|
// Layers are allowed to override events
|
|
14632
|
-
setEvents: (events2) =>
|
|
14697
|
+
setEvents: (events2) => set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
14633
14698
|
// Container for child attachment - the portalScene (injected or container itself)
|
|
14634
14699
|
internal: { ...rootState.internal, ...injectState.internal, container: portalScene }
|
|
14635
14700
|
};
|
|
@@ -14688,14 +14753,49 @@ function parseBackground(background) {
|
|
|
14688
14753
|
return null;
|
|
14689
14754
|
}
|
|
14690
14755
|
|
|
14756
|
+
function parseRendererConfig(rendererProp) {
|
|
14757
|
+
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
14758
|
+
if (isRendererConfig) {
|
|
14759
|
+
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
14760
|
+
return {
|
|
14761
|
+
primaryCanvas: pc,
|
|
14762
|
+
scheduler: sc,
|
|
14763
|
+
renderer: Object.keys(rest).length > 0 ? rest : rendererProp
|
|
14764
|
+
};
|
|
14765
|
+
}
|
|
14766
|
+
return { primaryCanvas: void 0, scheduler: void 0, renderer: rendererProp };
|
|
14767
|
+
}
|
|
14768
|
+
|
|
14769
|
+
const RESOURCE_KINDS = ["nodes", "uniforms", "buffers", "gpuStorage"];
|
|
14770
|
+
const registries = /* @__PURE__ */ new WeakMap();
|
|
14771
|
+
function getKindRegistry(store, kind) {
|
|
14772
|
+
let registry = registries.get(store);
|
|
14773
|
+
if (!registry) {
|
|
14774
|
+
registry = {
|
|
14775
|
+
nodes: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14776
|
+
uniforms: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14777
|
+
buffers: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14778
|
+
gpuStorage: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() }
|
|
14779
|
+
};
|
|
14780
|
+
registries.set(store, registry);
|
|
14781
|
+
}
|
|
14782
|
+
return registry[kind];
|
|
14783
|
+
}
|
|
14784
|
+
function invalidateResource(store, kind, scopeKey) {
|
|
14785
|
+
const registry = getKindRegistry(store, kind);
|
|
14786
|
+
{
|
|
14787
|
+
registry.valid.clear();
|
|
14788
|
+
registry.staged.clear();
|
|
14789
|
+
}
|
|
14790
|
+
}
|
|
14791
|
+
function invalidateAllResources(store) {
|
|
14792
|
+
for (const kind of RESOURCE_KINDS) invalidateResource(store, kind);
|
|
14793
|
+
}
|
|
14794
|
+
|
|
14691
14795
|
function clearHmrCaches(store) {
|
|
14692
|
-
store.
|
|
14693
|
-
|
|
14694
|
-
|
|
14695
|
-
buffers: {},
|
|
14696
|
-
gpuStorage: {},
|
|
14697
|
-
_hmrVersion: state._hmrVersion + 1
|
|
14698
|
-
}));
|
|
14796
|
+
const primary = store.getState().primaryStore ?? store;
|
|
14797
|
+
invalidateAllResources(primary);
|
|
14798
|
+
primary.setState((state) => ({ _hmrVersion: state._hmrVersion + 1 }));
|
|
14699
14799
|
}
|
|
14700
14800
|
|
|
14701
14801
|
function CanvasImpl({
|
|
@@ -14731,18 +14831,7 @@ function CanvasImpl({
|
|
|
14731
14831
|
forceEven,
|
|
14732
14832
|
...props
|
|
14733
14833
|
}) {
|
|
14734
|
-
const
|
|
14735
|
-
let primaryCanvas;
|
|
14736
|
-
let scheduler;
|
|
14737
|
-
let renderer;
|
|
14738
|
-
if (isRendererConfig) {
|
|
14739
|
-
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
14740
|
-
primaryCanvas = pc;
|
|
14741
|
-
scheduler = sc;
|
|
14742
|
-
renderer = Object.keys(rest).length > 0 ? rest : rendererProp;
|
|
14743
|
-
} else {
|
|
14744
|
-
renderer = rendererProp;
|
|
14745
|
-
}
|
|
14834
|
+
const { primaryCanvas, scheduler, renderer } = parseRendererConfig(rendererProp);
|
|
14746
14835
|
React.useMemo(() => extend(THREE), []);
|
|
14747
14836
|
const Bridge = useBridge();
|
|
14748
14837
|
const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
|
|
@@ -14787,6 +14876,7 @@ function CanvasImpl({
|
|
|
14787
14876
|
const handleDropMissed = useMutableCallback(onDropMissed);
|
|
14788
14877
|
const [block, setBlock] = React.useState(false);
|
|
14789
14878
|
const [error, setError] = React.useState(false);
|
|
14879
|
+
const [fallbackVisible, setFallbackVisible] = React.useState(false);
|
|
14790
14880
|
if (block) throw block;
|
|
14791
14881
|
if (error) throw error;
|
|
14792
14882
|
const root = React.useRef(null);
|
|
@@ -14794,6 +14884,7 @@ function CanvasImpl({
|
|
|
14794
14884
|
const unsubscribeErrorRef = React.useRef(null);
|
|
14795
14885
|
useIsomorphicLayoutEffect(() => {
|
|
14796
14886
|
effectActiveRef.current = true;
|
|
14887
|
+
if (fallbackVisible) return;
|
|
14797
14888
|
const canvas = canvasRef.current;
|
|
14798
14889
|
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
14799
14890
|
if (!root.current) {
|
|
@@ -14814,7 +14905,7 @@ function CanvasImpl({
|
|
|
14814
14905
|
}
|
|
14815
14906
|
async function run() {
|
|
14816
14907
|
if (!effectActiveRef.current || !root.current) return;
|
|
14817
|
-
await root.current.configure({
|
|
14908
|
+
const configured = await root.current.configure({
|
|
14818
14909
|
id,
|
|
14819
14910
|
primaryCanvas,
|
|
14820
14911
|
scheduler,
|
|
@@ -14855,8 +14946,20 @@ function CanvasImpl({
|
|
|
14855
14946
|
}
|
|
14856
14947
|
onCreated?.(state);
|
|
14857
14948
|
}
|
|
14858
|
-
})
|
|
14859
|
-
|
|
14949
|
+
}).then(
|
|
14950
|
+
() => true,
|
|
14951
|
+
// Renderer setup failed (e.g. no WebGL/WebGPU support). The `fallback` prop lives
|
|
14952
|
+
// inside <canvas>, which browsers don't display, so surface it as visible DOM
|
|
14953
|
+
// instead; with no fallback, rethrow to an external error boundary. (#3757)
|
|
14954
|
+
(setupError) => {
|
|
14955
|
+
if (effectActiveRef.current) {
|
|
14956
|
+
if (fallback != null) setFallbackVisible(true);
|
|
14957
|
+
else setError(setupError);
|
|
14958
|
+
}
|
|
14959
|
+
return false;
|
|
14960
|
+
}
|
|
14961
|
+
);
|
|
14962
|
+
if (!configured || !effectActiveRef.current || !root.current) return;
|
|
14860
14963
|
root.current.render(
|
|
14861
14964
|
/* @__PURE__ */ jsx(Bridge, { children: /* @__PURE__ */ jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxs(React.Suspense, { fallback: /* @__PURE__ */ jsx(Block, { set: setBlock }), children: [
|
|
14862
14965
|
backgroundProps && /* @__PURE__ */ jsx(Environment, { ...backgroundProps }),
|
|
@@ -14919,7 +15022,11 @@ function CanvasImpl({
|
|
|
14919
15022
|
...style
|
|
14920
15023
|
},
|
|
14921
15024
|
...props,
|
|
14922
|
-
children:
|
|
15025
|
+
children: fallbackVisible ? (
|
|
15026
|
+
// Renderer setup failed: render the fallback as visible DOM. Inside <canvas> (below)
|
|
15027
|
+
// it exists in the tree but browsers never paint it, which is the whole bug (#3757).
|
|
15028
|
+
fallback
|
|
15029
|
+
) : /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(
|
|
14923
15030
|
"canvas",
|
|
14924
15031
|
{
|
|
14925
15032
|
ref: canvasRef,
|