@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/index.cjs
CHANGED
|
@@ -56,10 +56,13 @@ const R3F_BUILD_WEBGPU = true;
|
|
|
56
56
|
|
|
57
57
|
const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
58
58
|
__proto__: null,
|
|
59
|
+
CubeRenderTarget: webgpu.CubeRenderTarget,
|
|
60
|
+
CubeRenderTargetCompat: webgpu.CubeRenderTarget,
|
|
59
61
|
Inspector: Inspector_js.Inspector,
|
|
60
62
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
61
63
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
62
64
|
RenderTargetCompat: webgpu.RenderTarget,
|
|
65
|
+
WebGLCubeRenderTarget: three.WebGLCubeRenderTarget,
|
|
63
66
|
WebGLRenderTarget: three.WebGLRenderTarget,
|
|
64
67
|
WebGLRenderer: three.WebGLRenderer
|
|
65
68
|
}, [webgpu__namespace]);
|
|
@@ -333,15 +336,16 @@ function EnvironmentPortal({
|
|
|
333
336
|
preset = void 0,
|
|
334
337
|
extensions
|
|
335
338
|
}) {
|
|
336
|
-
const
|
|
339
|
+
const renderer = fiber.useThree((state) => state.renderer);
|
|
340
|
+
const isLegacy = fiber.useThree((state) => state.isLegacy);
|
|
337
341
|
const defaultScene = fiber.useThree((state) => state.scene);
|
|
338
342
|
const camera = React__namespace.useRef(null);
|
|
339
343
|
const [virtualScene] = React__namespace.useState(() => new webgpu.Scene());
|
|
340
344
|
const fbo = React__namespace.useMemo(() => {
|
|
341
|
-
const fbo2 = new
|
|
345
|
+
const fbo2 = isLegacy ? new three.WebGLCubeRenderTarget(resolution) : new webgpu.CubeRenderTarget(resolution);
|
|
342
346
|
fbo2.texture.type = webgpu.HalfFloatType;
|
|
343
347
|
return fbo2;
|
|
344
|
-
}, [resolution]);
|
|
348
|
+
}, [resolution, isLegacy]);
|
|
345
349
|
React__namespace.useEffect(() => {
|
|
346
350
|
return () => {
|
|
347
351
|
fbo.dispose();
|
|
@@ -349,10 +353,10 @@ function EnvironmentPortal({
|
|
|
349
353
|
}, [fbo]);
|
|
350
354
|
React__namespace.useLayoutEffect(() => {
|
|
351
355
|
if (frames === 1) {
|
|
352
|
-
const autoClear =
|
|
353
|
-
|
|
354
|
-
camera.current.update(
|
|
355
|
-
|
|
356
|
+
const autoClear = renderer.autoClear;
|
|
357
|
+
renderer.autoClear = true;
|
|
358
|
+
camera.current.update(renderer, virtualScene);
|
|
359
|
+
renderer.autoClear = autoClear;
|
|
356
360
|
}
|
|
357
361
|
return setEnvProps(background, scene, defaultScene, fbo.texture, {
|
|
358
362
|
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
@@ -369,7 +373,7 @@ function EnvironmentPortal({
|
|
|
369
373
|
defaultScene,
|
|
370
374
|
background,
|
|
371
375
|
frames,
|
|
372
|
-
|
|
376
|
+
renderer,
|
|
373
377
|
blur,
|
|
374
378
|
backgroundBlurriness,
|
|
375
379
|
backgroundIntensity,
|
|
@@ -380,10 +384,10 @@ function EnvironmentPortal({
|
|
|
380
384
|
let count = 1;
|
|
381
385
|
fiber.useFrame(() => {
|
|
382
386
|
if (frames === Infinity || count < frames) {
|
|
383
|
-
const autoClear =
|
|
384
|
-
|
|
385
|
-
camera.current.update(
|
|
386
|
-
|
|
387
|
+
const autoClear = renderer.autoClear;
|
|
388
|
+
renderer.autoClear = true;
|
|
389
|
+
camera.current.update(renderer, virtualScene);
|
|
390
|
+
renderer.autoClear = autoClear;
|
|
387
391
|
count++;
|
|
388
392
|
}
|
|
389
393
|
});
|
|
@@ -626,8 +630,7 @@ function prepare(target, root, type, props) {
|
|
|
626
630
|
object,
|
|
627
631
|
eventCount: 0,
|
|
628
632
|
handlers: {},
|
|
629
|
-
isHidden: false
|
|
630
|
-
deferredRefs: []
|
|
633
|
+
isHidden: false
|
|
631
634
|
};
|
|
632
635
|
if (object) object.__r3f = instance;
|
|
633
636
|
}
|
|
@@ -784,6 +787,17 @@ function unregisterVisibility(store, object) {
|
|
|
784
787
|
internal.visibilityRegistry.delete(object.uuid);
|
|
785
788
|
internal.occlusionCache.delete(object);
|
|
786
789
|
}
|
|
790
|
+
function updateVisibilityHandlers(store, object, handlers) {
|
|
791
|
+
const { internal } = store.getState();
|
|
792
|
+
const entry = internal.visibilityRegistry.get(object.uuid);
|
|
793
|
+
if (!entry) return false;
|
|
794
|
+
entry.handlers = handlers;
|
|
795
|
+
if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
|
|
796
|
+
object.occlusionTest = true;
|
|
797
|
+
enableOcclusion(store);
|
|
798
|
+
}
|
|
799
|
+
return true;
|
|
800
|
+
}
|
|
787
801
|
function checkVisibility(state) {
|
|
788
802
|
const { internal, camera } = state;
|
|
789
803
|
const registry = internal.visibilityRegistry;
|
|
@@ -971,10 +985,7 @@ function applyProps(object, props) {
|
|
|
971
985
|
continue;
|
|
972
986
|
}
|
|
973
987
|
if (value === void 0) continue;
|
|
974
|
-
if (isFromRef(value))
|
|
975
|
-
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
976
|
-
continue;
|
|
977
|
-
}
|
|
988
|
+
if (isFromRef(value)) continue;
|
|
978
989
|
if (isOnce(value)) {
|
|
979
990
|
if (instance?.appliedOnce?.has(prop)) continue;
|
|
980
991
|
if (instance) {
|
|
@@ -1010,6 +1021,19 @@ function applyProps(object, props) {
|
|
|
1010
1021
|
} else if (isVectorLike(target) && is.num(value)) {
|
|
1011
1022
|
if ("setScalar" in target && typeof target.setScalar === "function") target.setScalar(value);
|
|
1012
1023
|
else target.set(value);
|
|
1024
|
+
} else if (root instanceof webgpu.ShaderMaterial && key === "uniforms" && is.obj(value)) {
|
|
1025
|
+
if (!is.obj(root.uniforms)) root.uniforms = {};
|
|
1026
|
+
const uniforms = root.uniforms;
|
|
1027
|
+
const nextUniforms = value;
|
|
1028
|
+
for (const name in nextUniforms) {
|
|
1029
|
+
const uniform = nextUniforms[name];
|
|
1030
|
+
const targetUniform = uniforms[name];
|
|
1031
|
+
if (targetUniform) Object.assign(targetUniform, uniform);
|
|
1032
|
+
else {
|
|
1033
|
+
const nextUniform = uniform instanceof webgpu.Uniform ? uniform.clone() : new webgpu.Uniform(uniform.value);
|
|
1034
|
+
uniforms[name] = nextUniform;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1013
1037
|
} else {
|
|
1014
1038
|
root[key] = value;
|
|
1015
1039
|
if (key.endsWith("Node") && root.isMaterial) {
|
|
@@ -1028,6 +1052,9 @@ function applyProps(object, props) {
|
|
|
1028
1052
|
if (instance.eventCount && object2.raycast !== null) {
|
|
1029
1053
|
rootState.internal.interaction.push(object2);
|
|
1030
1054
|
}
|
|
1055
|
+
}
|
|
1056
|
+
if (instance?.parent && rootState?.internal && instance.object?.isObject3D) {
|
|
1057
|
+
const object2 = instance.object;
|
|
1031
1058
|
const root = findInitialRoot(instance);
|
|
1032
1059
|
const visibilityHandlers = {
|
|
1033
1060
|
onFramed: instance.handlers.onFramed,
|
|
@@ -1035,7 +1062,9 @@ function applyProps(object, props) {
|
|
|
1035
1062
|
onVisible: instance.handlers.onVisible
|
|
1036
1063
|
};
|
|
1037
1064
|
if (hasVisibilityHandlers(visibilityHandlers)) {
|
|
1038
|
-
|
|
1065
|
+
if (!updateVisibilityHandlers(root, object2, visibilityHandlers)) {
|
|
1066
|
+
registerVisibility(root, object2, visibilityHandlers);
|
|
1067
|
+
}
|
|
1039
1068
|
} else {
|
|
1040
1069
|
unregisterVisibility(root, object2);
|
|
1041
1070
|
}
|
|
@@ -1563,6 +1592,7 @@ function createPointerEvents(store) {
|
|
|
1563
1592
|
set((state) => ({ events: { ...state.events, connected: void 0 } }));
|
|
1564
1593
|
}
|
|
1565
1594
|
},
|
|
1595
|
+
// PREVIEW (A8): the XR pointer registration API may change before stable.
|
|
1566
1596
|
registerPointer: (config) => {
|
|
1567
1597
|
const pointerId = nextXRPointerId++;
|
|
1568
1598
|
xrPointers.set(pointerId, config);
|
|
@@ -1649,6 +1679,13 @@ function notifyAlpha({ message, link }) {
|
|
|
1649
1679
|
}
|
|
1650
1680
|
}
|
|
1651
1681
|
|
|
1682
|
+
const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
|
|
1683
|
+
function isInternalRendererAccess(stack, callerDepth = 2) {
|
|
1684
|
+
if (!stack) return false;
|
|
1685
|
+
const caller = stack.split("\n")[callerDepth] ?? "";
|
|
1686
|
+
return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1652
1689
|
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
1653
1690
|
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React__namespace.createContext(null));
|
|
1654
1691
|
const createStore = (invalidate, advance) => {
|
|
@@ -1781,6 +1818,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1781
1818
|
}),
|
|
1782
1819
|
setFrameloop: (frameloop = "always") => {
|
|
1783
1820
|
set(() => ({ frameloop }));
|
|
1821
|
+
scheduler.getScheduler().frameloop = frameloop;
|
|
1784
1822
|
},
|
|
1785
1823
|
setError: (error) => set(() => ({ error })),
|
|
1786
1824
|
error: null,
|
|
@@ -1848,8 +1886,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1848
1886
|
const currentState = rootStore.getState();
|
|
1849
1887
|
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1850
1888
|
const stack = new Error().stack || "";
|
|
1851
|
-
|
|
1852
|
-
if (!isInternalAccess) {
|
|
1889
|
+
if (!isInternalRendererAccess(stack)) {
|
|
1853
1890
|
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1854
1891
|
notifyDepreciated({
|
|
1855
1892
|
heading: "Accessing state.gl in WebGPU mode",
|
|
@@ -1962,19 +1999,25 @@ function loadingFn(extensions, onProgress) {
|
|
|
1962
1999
|
);
|
|
1963
2000
|
};
|
|
1964
2001
|
}
|
|
1965
|
-
function useLoader(loader, input, extensions, onProgress) {
|
|
1966
|
-
const
|
|
2002
|
+
function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
2003
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
2004
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
1967
2005
|
const fn = loadingFn(extensions, onProgress);
|
|
1968
|
-
const results =
|
|
2006
|
+
const results = cacheKeys.map(
|
|
2007
|
+
(key, index) => suspendReact.suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
2008
|
+
);
|
|
1969
2009
|
return Array.isArray(input) ? results : results[0];
|
|
1970
2010
|
}
|
|
1971
|
-
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
1972
|
-
const
|
|
1973
|
-
|
|
2011
|
+
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
2012
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
2013
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
2014
|
+
cacheKeys.forEach(
|
|
2015
|
+
(key, index) => suspendReact.preload(() => loadingFn(extensions, onProgress)(loader, inputs[index]), [loader, key])
|
|
2016
|
+
);
|
|
1974
2017
|
};
|
|
1975
|
-
useLoader.clear = function(loader, input) {
|
|
1976
|
-
const
|
|
1977
|
-
|
|
2018
|
+
useLoader.clear = function(loader, input, cacheKey) {
|
|
2019
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
2020
|
+
cacheKeys.forEach((key) => suspendReact.clear([loader, key]));
|
|
1978
2021
|
};
|
|
1979
2022
|
useLoader.loader = getLoader;
|
|
1980
2023
|
|
|
@@ -2396,7 +2439,7 @@ function advance(timestamp) {
|
|
|
2396
2439
|
scheduler.getScheduler().step(timestamp);
|
|
2397
2440
|
}
|
|
2398
2441
|
|
|
2399
|
-
const version = "10.0.0-alpha.
|
|
2442
|
+
const version = "10.0.0-alpha.3";
|
|
2400
2443
|
const packageData = {
|
|
2401
2444
|
version: version};
|
|
2402
2445
|
|
|
@@ -13835,6 +13878,7 @@ function swapInstances() {
|
|
|
13835
13878
|
}
|
|
13836
13879
|
}
|
|
13837
13880
|
if (instance.isHidden) unhideInstance(instance);
|
|
13881
|
+
if (isObject3D(instance.object)) removeInteractivity(findInitialRoot(instance), instance.object);
|
|
13838
13882
|
if (instance.object.__r3f) delete instance.object.__r3f;
|
|
13839
13883
|
if (instance.type !== "primitive") disposeOnIdle(instance.object);
|
|
13840
13884
|
}
|
|
@@ -13847,6 +13891,8 @@ function swapInstances() {
|
|
|
13847
13891
|
instance.object.__r3f = instance;
|
|
13848
13892
|
setFiberRef(fiber, instance.object);
|
|
13849
13893
|
delete instance.appliedOnce;
|
|
13894
|
+
instance.eventCount = 0;
|
|
13895
|
+
instance.handlers = {};
|
|
13850
13896
|
applyProps(instance.object, instance.props);
|
|
13851
13897
|
if (instance.props.attach) {
|
|
13852
13898
|
attach(parent, instance);
|
|
@@ -14062,11 +14108,15 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14062
14108
|
cloneMutableTextInstance(textInstance) {
|
|
14063
14109
|
return textInstance;
|
|
14064
14110
|
},
|
|
14111
|
+
// React 19.2 added these for root-level view transitions. They only run for hosts that opt into
|
|
14112
|
+
// view transitions by returning a container from cloneRootViewTransitionContainer; R3F renders
|
|
14113
|
+
// into a WebGL/WebGPU canvas, where cloning the root has no meaning, so we never opt in and
|
|
14114
|
+
// React never calls them. They stay as no-ops rather than throws: the host config is shared by
|
|
14115
|
+
// every root, and a throw here would turn a React-internal probe into a hard crash for users.
|
|
14116
|
+
// Guarded by a test asserting a full render + unmount never reaches them.
|
|
14065
14117
|
cloneRootViewTransitionContainer(_rootContainer) {
|
|
14066
|
-
throw new Error("Not implemented.");
|
|
14067
14118
|
},
|
|
14068
14119
|
removeRootViewTransitionClone(_rootContainer, _clone) {
|
|
14069
|
-
throw new Error("Not implemented.");
|
|
14070
14120
|
},
|
|
14071
14121
|
// https://github.com/facebook/react/pull/32465
|
|
14072
14122
|
createFragmentInstance: (_fiber) => null,
|
|
@@ -14151,6 +14201,7 @@ function createRoot(canvas) {
|
|
|
14151
14201
|
const lastConfiguredProps = {};
|
|
14152
14202
|
let configured = false;
|
|
14153
14203
|
let pending = null;
|
|
14204
|
+
let rendererSetup = null;
|
|
14154
14205
|
return {
|
|
14155
14206
|
async configure(props = {}) {
|
|
14156
14207
|
let resolve;
|
|
@@ -14181,7 +14232,7 @@ function createRoot(canvas) {
|
|
|
14181
14232
|
forceEven
|
|
14182
14233
|
} = props;
|
|
14183
14234
|
const textureColorSpace = is.obj(glConfig) && !is.fun(glConfig) && !isRenderer(glConfig) && glConfig.textureColorSpace || is.obj(rendererConfig) && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && rendererConfig.textureColorSpace || webgpu.SRGBColorSpace;
|
|
14184
|
-
|
|
14235
|
+
let state = store.getState();
|
|
14185
14236
|
const defaultGLProps = {
|
|
14186
14237
|
canvas,
|
|
14187
14238
|
powerPreference: "high-performance",
|
|
@@ -14209,56 +14260,68 @@ function createRoot(canvas) {
|
|
|
14209
14260
|
"The `primaryCanvas` prop for multi-canvas rendering cannot be used with WebGL. Remove the `gl` prop or use WebGPU."
|
|
14210
14261
|
);
|
|
14211
14262
|
}
|
|
14212
|
-
if (
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14216
|
-
|
|
14217
|
-
|
|
14218
|
-
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
14222
|
-
|
|
14223
|
-
|
|
14224
|
-
|
|
14225
|
-
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
|
|
14230
|
-
|
|
14231
|
-
|
|
14232
|
-
|
|
14233
|
-
|
|
14234
|
-
|
|
14235
|
-
|
|
14236
|
-
|
|
14237
|
-
|
|
14238
|
-
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
|
|
14242
|
-
|
|
14243
|
-
|
|
14244
|
-
|
|
14245
|
-
|
|
14246
|
-
|
|
14247
|
-
|
|
14248
|
-
|
|
14249
|
-
|
|
14250
|
-
|
|
14251
|
-
|
|
14252
|
-
|
|
14253
|
-
|
|
14254
|
-
|
|
14255
|
-
|
|
14256
|
-
|
|
14257
|
-
|
|
14258
|
-
|
|
14263
|
+
if (!state.internal.actualRenderer) {
|
|
14264
|
+
if (!rendererSetup) {
|
|
14265
|
+
rendererSetup = (async () => {
|
|
14266
|
+
if (wantsGL) {
|
|
14267
|
+
renderer = await resolveRenderer(glConfig, defaultGLProps, three.WebGLRenderer);
|
|
14268
|
+
state.internal.actualRenderer = renderer;
|
|
14269
|
+
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
14270
|
+
} else if (!wantsGL && primaryCanvas) {
|
|
14271
|
+
const primary = await waitForPrimary(primaryCanvas);
|
|
14272
|
+
renderer = primary.renderer;
|
|
14273
|
+
state.internal.actualRenderer = renderer;
|
|
14274
|
+
const canvasTarget = new webgpu.CanvasTarget(canvas);
|
|
14275
|
+
primary.store.setState((prev) => ({
|
|
14276
|
+
internal: { ...prev.internal, isMultiCanvas: true }
|
|
14277
|
+
}));
|
|
14278
|
+
state.set((prev) => ({
|
|
14279
|
+
webGPUSupported: primary.store.getState().webGPUSupported,
|
|
14280
|
+
renderer,
|
|
14281
|
+
primaryStore: primary.store,
|
|
14282
|
+
internal: {
|
|
14283
|
+
...prev.internal,
|
|
14284
|
+
canvasTarget,
|
|
14285
|
+
isMultiCanvas: true,
|
|
14286
|
+
isSecondary: true,
|
|
14287
|
+
targetId: primaryCanvas
|
|
14288
|
+
}
|
|
14289
|
+
}));
|
|
14290
|
+
} else if (!wantsGL) {
|
|
14291
|
+
renderer = await resolveRenderer(rendererConfig, defaultGPUProps, webgpu.WebGPURenderer);
|
|
14292
|
+
if (!renderer.hasInitialized?.()) {
|
|
14293
|
+
const size2 = computeInitialSize(canvas, propsSize);
|
|
14294
|
+
if (size2.width > 0 && size2.height > 0) {
|
|
14295
|
+
const pixelRatio = calculateDpr(dpr);
|
|
14296
|
+
canvas.width = size2.width * pixelRatio;
|
|
14297
|
+
canvas.height = size2.height * pixelRatio;
|
|
14298
|
+
}
|
|
14299
|
+
await renderer.init();
|
|
14300
|
+
}
|
|
14301
|
+
const backend = renderer.backend;
|
|
14302
|
+
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
14303
|
+
state.internal.actualRenderer = renderer;
|
|
14304
|
+
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
14305
|
+
if (canvasId && !state.internal.isSecondary) {
|
|
14306
|
+
const canvasTarget = new webgpu.CanvasTarget(canvas);
|
|
14307
|
+
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
14308
|
+
state.set((prev) => ({
|
|
14309
|
+
internal: {
|
|
14310
|
+
...prev.internal,
|
|
14311
|
+
canvasTarget,
|
|
14312
|
+
unregisterPrimary
|
|
14313
|
+
}
|
|
14314
|
+
}));
|
|
14315
|
+
}
|
|
14259
14316
|
}
|
|
14260
|
-
}))
|
|
14317
|
+
})().catch((err) => {
|
|
14318
|
+
rendererSetup = null;
|
|
14319
|
+
throw err;
|
|
14320
|
+
});
|
|
14261
14321
|
}
|
|
14322
|
+
await rendererSetup;
|
|
14323
|
+
state = store.getState();
|
|
14324
|
+
renderer = state.internal.actualRenderer;
|
|
14262
14325
|
}
|
|
14263
14326
|
let raycaster = state.raycaster;
|
|
14264
14327
|
if (!raycaster) state.set({ raycaster: raycaster = new webgpu.Raycaster() });
|
|
@@ -14608,7 +14671,8 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14608
14671
|
dispose(state.scene);
|
|
14609
14672
|
_roots.delete(canvas);
|
|
14610
14673
|
if (callback) callback(canvas);
|
|
14611
|
-
} catch {
|
|
14674
|
+
} catch (error) {
|
|
14675
|
+
console.warn("[R3F] Error while unmounting root; teardown may be incomplete:", error);
|
|
14612
14676
|
}
|
|
14613
14677
|
}, 500);
|
|
14614
14678
|
}
|
|
@@ -14671,6 +14735,7 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
14671
14735
|
viewport = rootState.viewport.getCurrentViewport(camera, new webgpu.Vector3(), resolvedSize);
|
|
14672
14736
|
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14673
14737
|
}
|
|
14738
|
+
const set = injectState.set;
|
|
14674
14739
|
return {
|
|
14675
14740
|
// The intersect consists of the previous root state
|
|
14676
14741
|
...rootState,
|
|
@@ -14689,7 +14754,7 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
14689
14754
|
size: resolvedSize,
|
|
14690
14755
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14691
14756
|
// Layers are allowed to override events
|
|
14692
|
-
setEvents: (events2) =>
|
|
14757
|
+
setEvents: (events2) => set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
14693
14758
|
// Container for child attachment - the portalScene (injected or container itself)
|
|
14694
14759
|
internal: { ...rootState.internal, ...injectState.internal, container: portalScene }
|
|
14695
14760
|
};
|
|
@@ -14748,14 +14813,49 @@ function parseBackground(background) {
|
|
|
14748
14813
|
return null;
|
|
14749
14814
|
}
|
|
14750
14815
|
|
|
14816
|
+
function parseRendererConfig(rendererProp) {
|
|
14817
|
+
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
14818
|
+
if (isRendererConfig) {
|
|
14819
|
+
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
14820
|
+
return {
|
|
14821
|
+
primaryCanvas: pc,
|
|
14822
|
+
scheduler: sc,
|
|
14823
|
+
renderer: Object.keys(rest).length > 0 ? rest : rendererProp
|
|
14824
|
+
};
|
|
14825
|
+
}
|
|
14826
|
+
return { primaryCanvas: void 0, scheduler: void 0, renderer: rendererProp };
|
|
14827
|
+
}
|
|
14828
|
+
|
|
14829
|
+
const RESOURCE_KINDS = ["nodes", "uniforms", "buffers", "gpuStorage"];
|
|
14830
|
+
const registries = /* @__PURE__ */ new WeakMap();
|
|
14831
|
+
function getKindRegistry(store, kind) {
|
|
14832
|
+
let registry = registries.get(store);
|
|
14833
|
+
if (!registry) {
|
|
14834
|
+
registry = {
|
|
14835
|
+
nodes: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14836
|
+
uniforms: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14837
|
+
buffers: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14838
|
+
gpuStorage: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() }
|
|
14839
|
+
};
|
|
14840
|
+
registries.set(store, registry);
|
|
14841
|
+
}
|
|
14842
|
+
return registry[kind];
|
|
14843
|
+
}
|
|
14844
|
+
function invalidateResource(store, kind, scopeKey) {
|
|
14845
|
+
const registry = getKindRegistry(store, kind);
|
|
14846
|
+
{
|
|
14847
|
+
registry.valid.clear();
|
|
14848
|
+
registry.staged.clear();
|
|
14849
|
+
}
|
|
14850
|
+
}
|
|
14851
|
+
function invalidateAllResources(store) {
|
|
14852
|
+
for (const kind of RESOURCE_KINDS) invalidateResource(store, kind);
|
|
14853
|
+
}
|
|
14854
|
+
|
|
14751
14855
|
function clearHmrCaches(store) {
|
|
14752
|
-
store.
|
|
14753
|
-
|
|
14754
|
-
|
|
14755
|
-
buffers: {},
|
|
14756
|
-
gpuStorage: {},
|
|
14757
|
-
_hmrVersion: state._hmrVersion + 1
|
|
14758
|
-
}));
|
|
14856
|
+
const primary = store.getState().primaryStore ?? store;
|
|
14857
|
+
invalidateAllResources(primary);
|
|
14858
|
+
primary.setState((state) => ({ _hmrVersion: state._hmrVersion + 1 }));
|
|
14759
14859
|
}
|
|
14760
14860
|
|
|
14761
14861
|
function CanvasImpl({
|
|
@@ -14791,18 +14891,7 @@ function CanvasImpl({
|
|
|
14791
14891
|
forceEven,
|
|
14792
14892
|
...props
|
|
14793
14893
|
}) {
|
|
14794
|
-
const
|
|
14795
|
-
let primaryCanvas;
|
|
14796
|
-
let scheduler;
|
|
14797
|
-
let renderer;
|
|
14798
|
-
if (isRendererConfig) {
|
|
14799
|
-
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
14800
|
-
primaryCanvas = pc;
|
|
14801
|
-
scheduler = sc;
|
|
14802
|
-
renderer = Object.keys(rest).length > 0 ? rest : rendererProp;
|
|
14803
|
-
} else {
|
|
14804
|
-
renderer = rendererProp;
|
|
14805
|
-
}
|
|
14894
|
+
const { primaryCanvas, scheduler, renderer } = parseRendererConfig(rendererProp);
|
|
14806
14895
|
React__namespace.useMemo(() => extend(THREE), []);
|
|
14807
14896
|
const Bridge = useBridge();
|
|
14808
14897
|
const backgroundProps = React__namespace.useMemo(() => parseBackground(background), [background]);
|
|
@@ -14847,6 +14936,7 @@ function CanvasImpl({
|
|
|
14847
14936
|
const handleDropMissed = useMutableCallback(onDropMissed);
|
|
14848
14937
|
const [block, setBlock] = React__namespace.useState(false);
|
|
14849
14938
|
const [error, setError] = React__namespace.useState(false);
|
|
14939
|
+
const [fallbackVisible, setFallbackVisible] = React__namespace.useState(false);
|
|
14850
14940
|
if (block) throw block;
|
|
14851
14941
|
if (error) throw error;
|
|
14852
14942
|
const root = React__namespace.useRef(null);
|
|
@@ -14854,6 +14944,7 @@ function CanvasImpl({
|
|
|
14854
14944
|
const unsubscribeErrorRef = React__namespace.useRef(null);
|
|
14855
14945
|
useIsomorphicLayoutEffect(() => {
|
|
14856
14946
|
effectActiveRef.current = true;
|
|
14947
|
+
if (fallbackVisible) return;
|
|
14857
14948
|
const canvas = canvasRef.current;
|
|
14858
14949
|
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
14859
14950
|
if (!root.current) {
|
|
@@ -14874,7 +14965,7 @@ function CanvasImpl({
|
|
|
14874
14965
|
}
|
|
14875
14966
|
async function run() {
|
|
14876
14967
|
if (!effectActiveRef.current || !root.current) return;
|
|
14877
|
-
await root.current.configure({
|
|
14968
|
+
const configured = await root.current.configure({
|
|
14878
14969
|
id,
|
|
14879
14970
|
primaryCanvas,
|
|
14880
14971
|
scheduler,
|
|
@@ -14915,8 +15006,20 @@ function CanvasImpl({
|
|
|
14915
15006
|
}
|
|
14916
15007
|
onCreated?.(state);
|
|
14917
15008
|
}
|
|
14918
|
-
})
|
|
14919
|
-
|
|
15009
|
+
}).then(
|
|
15010
|
+
() => true,
|
|
15011
|
+
// Renderer setup failed (e.g. no WebGL/WebGPU support). The `fallback` prop lives
|
|
15012
|
+
// inside <canvas>, which browsers don't display, so surface it as visible DOM
|
|
15013
|
+
// instead; with no fallback, rethrow to an external error boundary. (#3757)
|
|
15014
|
+
(setupError) => {
|
|
15015
|
+
if (effectActiveRef.current) {
|
|
15016
|
+
if (fallback != null) setFallbackVisible(true);
|
|
15017
|
+
else setError(setupError);
|
|
15018
|
+
}
|
|
15019
|
+
return false;
|
|
15020
|
+
}
|
|
15021
|
+
);
|
|
15022
|
+
if (!configured || !effectActiveRef.current || !root.current) return;
|
|
14920
15023
|
root.current.render(
|
|
14921
15024
|
/* @__PURE__ */ jsxRuntime.jsx(Bridge, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(Block, { set: setBlock }), children: [
|
|
14922
15025
|
backgroundProps && /* @__PURE__ */ jsxRuntime.jsx(Environment, { ...backgroundProps }),
|
|
@@ -14979,7 +15082,11 @@ function CanvasImpl({
|
|
|
14979
15082
|
...style
|
|
14980
15083
|
},
|
|
14981
15084
|
...props,
|
|
14982
|
-
children:
|
|
15085
|
+
children: fallbackVisible ? (
|
|
15086
|
+
// Renderer setup failed: render the fallback as visible DOM. Inside <canvas> (below)
|
|
15087
|
+
// it exists in the tree but browsers never paint it, which is the whole bug (#3757).
|
|
15088
|
+
fallback
|
|
15089
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
14983
15090
|
"canvas",
|
|
14984
15091
|
{
|
|
14985
15092
|
ref: canvasRef,
|