@react-three/fiber 10.0.0-canary.ba354c7 → 10.0.0-canary.c385e9f
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 +105 -53
- package/dist/index.d.cts +173 -24
- package/dist/index.d.mts +173 -24
- package/dist/index.d.ts +173 -24
- package/dist/index.mjs +105 -53
- package/dist/legacy.cjs +104 -57
- package/dist/legacy.d.cts +172 -27
- package/dist/legacy.d.mts +172 -27
- package/dist/legacy.d.ts +172 -27
- package/dist/legacy.mjs +104 -57
- package/dist/webgpu/index.cjs +168 -90
- package/dist/webgpu/index.d.cts +197 -88
- package/dist/webgpu/index.d.mts +197 -88
- package/dist/webgpu/index.d.ts +197 -88
- package/dist/webgpu/index.mjs +168 -90
- package/package.json +2 -2
package/dist/legacy.mjs
CHANGED
|
@@ -30,11 +30,9 @@ function _mergeNamespaces(n, m) {
|
|
|
30
30
|
|
|
31
31
|
const R3F_BUILD_LEGACY = true;
|
|
32
32
|
const R3F_BUILD_WEBGPU = false;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
};
|
|
33
|
+
async function loadInspector() {
|
|
34
|
+
throw new Error("Inspector is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
35
|
+
}
|
|
38
36
|
const WebGPURenderer = class WebGPURenderer2 {
|
|
39
37
|
constructor() {
|
|
40
38
|
throw new Error("WebGPURenderer is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
@@ -47,12 +45,12 @@ const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
|
47
45
|
__proto__: null,
|
|
48
46
|
CubeRenderTarget: CubeRenderTarget,
|
|
49
47
|
CubeRenderTargetCompat: WebGLCubeRenderTarget,
|
|
50
|
-
Inspector: Inspector,
|
|
51
48
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
52
49
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
53
50
|
RenderTarget: RenderTarget,
|
|
54
51
|
RenderTargetCompat: WebGLRenderTarget,
|
|
55
|
-
WebGPURenderer: WebGPURenderer
|
|
52
|
+
WebGPURenderer: WebGPURenderer,
|
|
53
|
+
loadInspector: loadInspector
|
|
56
54
|
}, [three]);
|
|
57
55
|
|
|
58
56
|
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
@@ -911,7 +909,7 @@ const createStore = (invalidate, advance) => {
|
|
|
911
909
|
size: newSize,
|
|
912
910
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
913
911
|
}));
|
|
914
|
-
|
|
912
|
+
get().invalidate();
|
|
915
913
|
}
|
|
916
914
|
}
|
|
917
915
|
return;
|
|
@@ -926,15 +924,16 @@ const createStore = (invalidate, advance) => {
|
|
|
926
924
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
927
925
|
_sizeImperative: true
|
|
928
926
|
}));
|
|
929
|
-
|
|
927
|
+
get().invalidate();
|
|
930
928
|
},
|
|
931
929
|
setDpr: (dpr) => set((state2) => {
|
|
932
930
|
const resolved = calculateDpr(dpr);
|
|
933
931
|
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
934
932
|
}),
|
|
935
933
|
setFrameloop: (frameloop = "always") => {
|
|
934
|
+
const rootId = get().internal.rootId;
|
|
935
|
+
if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
|
|
936
936
|
set(() => ({ frameloop }));
|
|
937
|
-
getScheduler().frameloop = frameloop;
|
|
938
937
|
},
|
|
939
938
|
setError: (error) => set(() => ({ error })),
|
|
940
939
|
error: null,
|
|
@@ -1050,17 +1049,10 @@ const createStore = (invalidate, advance) => {
|
|
|
1050
1049
|
oldSize = size;
|
|
1051
1050
|
oldDpr = viewport.dpr;
|
|
1052
1051
|
updateCamera(camera, size);
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1058
|
-
actualRenderer.setSize(size.width, size.height, false);
|
|
1059
|
-
if (canvasTarget) {
|
|
1060
|
-
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1061
|
-
canvasTarget.setSize(size.width, size.height, false);
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1052
|
+
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
1053
|
+
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
1054
|
+
resizeTarget.setSize(size.width, size.height, false);
|
|
1055
|
+
internal.canvasTargetSizeDirty = true;
|
|
1064
1056
|
}
|
|
1065
1057
|
if (camera !== oldCamera) {
|
|
1066
1058
|
oldCamera = camera;
|
|
@@ -1122,7 +1114,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
|
1122
1114
|
const results = cacheKeys.map(
|
|
1123
1115
|
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1124
1116
|
);
|
|
1125
|
-
|
|
1117
|
+
const stableRef = useRef(null);
|
|
1118
|
+
const previous = stableRef.current;
|
|
1119
|
+
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
1120
|
+
stableRef.current = stable;
|
|
1121
|
+
return Array.isArray(input) ? stable : stable[0];
|
|
1126
1122
|
}
|
|
1127
1123
|
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
1128
1124
|
const inputs = Array.isArray(input) ? input : [input];
|
|
@@ -1242,6 +1238,13 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1242
1238
|
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1243
1239
|
*/
|
|
1244
1240
|
scheduler: scheduler2,
|
|
1241
|
+
/**
|
|
1242
|
+
* The root that currently owns this job. Resolve on access because ambient
|
|
1243
|
+
* jobs can be adopted by a Canvas after the controls object is created.
|
|
1244
|
+
*/
|
|
1245
|
+
get rootId() {
|
|
1246
|
+
return getScheduler().getJobRootId(id);
|
|
1247
|
+
},
|
|
1245
1248
|
/**
|
|
1246
1249
|
* Manually step this job only.
|
|
1247
1250
|
* Bypasses FPS limiting - always runs.
|
|
@@ -1258,6 +1261,14 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1258
1261
|
stepAll: (timestamp) => {
|
|
1259
1262
|
getScheduler().step(timestamp);
|
|
1260
1263
|
},
|
|
1264
|
+
/**
|
|
1265
|
+
* Request frames for this job's owning root without waking sibling roots.
|
|
1266
|
+
*/
|
|
1267
|
+
invalidate: (frames, stackFrames) => {
|
|
1268
|
+
const scheduler3 = getScheduler();
|
|
1269
|
+
const rootId = scheduler3.getJobRootId(id);
|
|
1270
|
+
if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
|
|
1271
|
+
},
|
|
1261
1272
|
/**
|
|
1262
1273
|
* Pause this job (set enabled=false).
|
|
1263
1274
|
* Job remains registered but won't run.
|
|
@@ -1287,6 +1298,11 @@ function getUrls(input) {
|
|
|
1287
1298
|
if (Array.isArray(input)) return input;
|
|
1288
1299
|
return Object.values(input);
|
|
1289
1300
|
}
|
|
1301
|
+
function inputSignature(input) {
|
|
1302
|
+
if (typeof input === "string") return input;
|
|
1303
|
+
if (Array.isArray(input)) return input.join("\0");
|
|
1304
|
+
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
1305
|
+
}
|
|
1290
1306
|
function allUrlsCached(urls, textureCache) {
|
|
1291
1307
|
return urls.every((url) => textureCache.has(url));
|
|
1292
1308
|
}
|
|
@@ -1312,18 +1328,19 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1312
1328
|
const onLoadRef = useRef(onLoad);
|
|
1313
1329
|
onLoadRef.current = onLoad;
|
|
1314
1330
|
const onLoadCalledForRef = useRef(null);
|
|
1315
|
-
const
|
|
1331
|
+
const inputKey = useMemo(() => inputSignature(input), [input]);
|
|
1332
|
+
const stableInput = useMemo(() => input, [inputKey]);
|
|
1333
|
+
const urls = useMemo(() => getUrls(stableInput), [stableInput]);
|
|
1316
1334
|
const cachedResult = useMemo(() => {
|
|
1317
1335
|
if (!cache) return null;
|
|
1318
1336
|
const textures = store.getState().textures;
|
|
1319
1337
|
if (!allUrlsCached(urls, textures)) return null;
|
|
1320
|
-
return buildFromCache(
|
|
1321
|
-
}, [cache, urls,
|
|
1338
|
+
return buildFromCache(stableInput, textures);
|
|
1339
|
+
}, [cache, urls, stableInput, store]);
|
|
1322
1340
|
const loadedTextures = useLoader(
|
|
1323
1341
|
TextureLoader,
|
|
1324
|
-
IsObject(
|
|
1342
|
+
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
1325
1343
|
);
|
|
1326
|
-
const inputKey = urls.join("\0");
|
|
1327
1344
|
useLayoutEffect(() => {
|
|
1328
1345
|
if (cachedResult) return;
|
|
1329
1346
|
if (onLoadCalledForRef.current === inputKey) return;
|
|
@@ -1350,28 +1367,28 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1350
1367
|
}, [renderer, loadedTextures, cachedResult]);
|
|
1351
1368
|
const mappedTextures = useMemo(() => {
|
|
1352
1369
|
if (cachedResult) return cachedResult;
|
|
1353
|
-
if (IsObject(
|
|
1370
|
+
if (IsObject(stableInput)) {
|
|
1354
1371
|
const keyed = {};
|
|
1355
1372
|
const textureArray = loadedTextures;
|
|
1356
1373
|
let i = 0;
|
|
1357
|
-
for (const key in
|
|
1374
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1358
1375
|
return keyed;
|
|
1359
1376
|
} else {
|
|
1360
1377
|
return loadedTextures;
|
|
1361
1378
|
}
|
|
1362
|
-
}, [
|
|
1379
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
1363
1380
|
useEffect(() => {
|
|
1364
1381
|
if (!cache) return;
|
|
1365
1382
|
const urlTextureMap = [];
|
|
1366
|
-
if (typeof
|
|
1367
|
-
urlTextureMap.push([
|
|
1368
|
-
} else if (Array.isArray(
|
|
1383
|
+
if (typeof stableInput === "string") {
|
|
1384
|
+
urlTextureMap.push([stableInput, mappedTextures]);
|
|
1385
|
+
} else if (Array.isArray(stableInput)) {
|
|
1369
1386
|
const textureArray = mappedTextures;
|
|
1370
|
-
|
|
1371
|
-
} else if (IsObject(
|
|
1387
|
+
stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1388
|
+
} else if (IsObject(stableInput)) {
|
|
1372
1389
|
const textureRecord = mappedTextures;
|
|
1373
|
-
for (const key in
|
|
1374
|
-
const url =
|
|
1390
|
+
for (const key in stableInput) {
|
|
1391
|
+
const url = stableInput[key];
|
|
1375
1392
|
urlTextureMap.push([url, textureRecord[key]]);
|
|
1376
1393
|
}
|
|
1377
1394
|
}
|
|
@@ -1400,7 +1417,7 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1400
1417
|
}
|
|
1401
1418
|
return { _textureRefs: refs };
|
|
1402
1419
|
});
|
|
1403
|
-
}, [cache,
|
|
1420
|
+
}, [cache, stableInput, mappedTextures, store]);
|
|
1404
1421
|
return mappedTextures;
|
|
1405
1422
|
}
|
|
1406
1423
|
useTexture.preload = (url) => useLoader.preload(TextureLoader, url);
|
|
@@ -1669,13 +1686,19 @@ function addTail(callback) {
|
|
|
1669
1686
|
return getScheduler().onIdle(callback);
|
|
1670
1687
|
}
|
|
1671
1688
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1672
|
-
|
|
1689
|
+
const rootId = state?.internal?.rootId;
|
|
1690
|
+
const scheduler = getScheduler();
|
|
1691
|
+
if (rootId) scheduler.invalidateRoot(rootId, frames, stackFrames);
|
|
1692
|
+
else scheduler.invalidate(frames, stackFrames);
|
|
1673
1693
|
}
|
|
1674
|
-
function advance(timestamp) {
|
|
1675
|
-
|
|
1694
|
+
function advance(timestamp, runGlobalEffects, state) {
|
|
1695
|
+
const rootId = state?.internal?.rootId;
|
|
1696
|
+
const scheduler = getScheduler();
|
|
1697
|
+
if (rootId) scheduler.stepRoot(rootId, timestamp);
|
|
1698
|
+
else scheduler.step(timestamp);
|
|
1676
1699
|
}
|
|
1677
1700
|
|
|
1678
|
-
const version = "10.0.0-alpha.
|
|
1701
|
+
const version = "10.0.0-alpha.4";
|
|
1679
1702
|
const packageData = {
|
|
1680
1703
|
version: version};
|
|
1681
1704
|
|
|
@@ -14287,7 +14310,7 @@ function createRoot(canvas) {
|
|
|
14287
14310
|
const handleXRFrame = (timestamp, _frame) => {
|
|
14288
14311
|
const state2 = store.getState();
|
|
14289
14312
|
if (state2.frameloop === "never") return;
|
|
14290
|
-
advance(timestamp);
|
|
14313
|
+
advance(timestamp, true, state2);
|
|
14291
14314
|
};
|
|
14292
14315
|
const actualRenderer = state.internal.actualRenderer;
|
|
14293
14316
|
const handleSessionChange = () => {
|
|
@@ -14295,7 +14318,7 @@ function createRoot(canvas) {
|
|
|
14295
14318
|
const renderer2 = state2.internal.actualRenderer;
|
|
14296
14319
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
14297
14320
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
14298
|
-
if (!renderer2.xr.isPresenting) invalidate();
|
|
14321
|
+
if (!renderer2.xr.isPresenting) invalidate(state2);
|
|
14299
14322
|
};
|
|
14300
14323
|
const xr = {
|
|
14301
14324
|
connect() {
|
|
@@ -14377,7 +14400,11 @@ function createRoot(canvas) {
|
|
|
14377
14400
|
const newRootId = canvasId || scheduler.generateRootId();
|
|
14378
14401
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14379
14402
|
getState: () => store.getState(),
|
|
14380
|
-
onError: (err) => store.getState().setError(err)
|
|
14403
|
+
onError: (err) => store.getState().setError(err),
|
|
14404
|
+
frameloop: store.getState().frameloop,
|
|
14405
|
+
before: schedulerConfig?.before,
|
|
14406
|
+
after: schedulerConfig?.after,
|
|
14407
|
+
order: schedulerConfig?.order
|
|
14381
14408
|
});
|
|
14382
14409
|
const unregisterCanvasTarget = scheduler.register(
|
|
14383
14410
|
() => {
|
|
@@ -14385,6 +14412,10 @@ function createRoot(canvas) {
|
|
|
14385
14412
|
if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
|
|
14386
14413
|
const renderer2 = state2.internal.actualRenderer;
|
|
14387
14414
|
renderer2.setCanvasTarget(state2.internal.canvasTarget);
|
|
14415
|
+
if (state2.internal.canvasTargetSizeDirty) {
|
|
14416
|
+
state2.internal.canvasTargetSizeDirty = false;
|
|
14417
|
+
renderer2.backend?.updateSize?.();
|
|
14418
|
+
}
|
|
14388
14419
|
}
|
|
14389
14420
|
},
|
|
14390
14421
|
{
|
|
@@ -14453,8 +14484,7 @@ function createRoot(canvas) {
|
|
|
14453
14484
|
phase: "render",
|
|
14454
14485
|
system: true,
|
|
14455
14486
|
// Internal flag: this is a system job, not user-controlled
|
|
14456
|
-
//
|
|
14457
|
-
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
14487
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
14458
14488
|
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14459
14489
|
}
|
|
14460
14490
|
);
|
|
@@ -14473,8 +14503,21 @@ function createRoot(canvas) {
|
|
|
14473
14503
|
scheduler
|
|
14474
14504
|
}
|
|
14475
14505
|
}));
|
|
14506
|
+
} else {
|
|
14507
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
|
|
14508
|
+
if (constraintsChanged) {
|
|
14509
|
+
scheduler.setRootConstraints(rootId, {
|
|
14510
|
+
before: schedulerConfig?.before,
|
|
14511
|
+
after: schedulerConfig?.after
|
|
14512
|
+
});
|
|
14513
|
+
}
|
|
14514
|
+
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
14515
|
+
scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
14516
|
+
}
|
|
14476
14517
|
}
|
|
14477
|
-
|
|
14518
|
+
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
14519
|
+
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
14520
|
+
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
14478
14521
|
onCreated = onCreatedCallback;
|
|
14479
14522
|
configured = true;
|
|
14480
14523
|
resolve();
|
|
@@ -14516,14 +14559,19 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14516
14559
|
const fiber = root?.fiber;
|
|
14517
14560
|
if (fiber) {
|
|
14518
14561
|
const state = root?.store.getState();
|
|
14519
|
-
if (state)
|
|
14562
|
+
if (state) {
|
|
14563
|
+
state.internal.active = false;
|
|
14564
|
+
const unregisterRoot = state.internal.unregisterRoot;
|
|
14565
|
+
if (unregisterRoot) {
|
|
14566
|
+
unregisterRoot();
|
|
14567
|
+
state.internal.unregisterRoot = void 0;
|
|
14568
|
+
}
|
|
14569
|
+
}
|
|
14520
14570
|
reconciler.updateContainer(null, fiber, null, () => {
|
|
14521
14571
|
if (state) {
|
|
14522
14572
|
setTimeout(() => {
|
|
14523
14573
|
try {
|
|
14524
14574
|
const renderer = state.internal.actualRenderer;
|
|
14525
|
-
const unregisterRoot = state.internal.unregisterRoot;
|
|
14526
|
-
if (unregisterRoot) unregisterRoot();
|
|
14527
14575
|
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
14528
14576
|
if (unregisterPrimary) unregisterPrimary();
|
|
14529
14577
|
const canvasTarget = state.internal.canvasTarget;
|
|
@@ -14971,9 +15019,9 @@ function CanvasImpl({
|
|
|
14971
15019
|
React.useMemo(() => extend(THREE), []);
|
|
14972
15020
|
const Bridge = useBridge();
|
|
14973
15021
|
const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
|
|
14974
|
-
const
|
|
15022
|
+
const [hasInitialSize, setHasInitialSize] = React.useState(false);
|
|
14975
15023
|
const measureConfig = React.useMemo(() => {
|
|
14976
|
-
if (!
|
|
15024
|
+
if (!hasInitialSize) {
|
|
14977
15025
|
return {
|
|
14978
15026
|
...resize,
|
|
14979
15027
|
scroll: resize?.scroll ?? true,
|
|
@@ -14985,7 +15033,7 @@ function CanvasImpl({
|
|
|
14985
15033
|
debounce: { scroll: 50, resize: 0 },
|
|
14986
15034
|
...resize
|
|
14987
15035
|
};
|
|
14988
|
-
}, [
|
|
15036
|
+
}, [hasInitialSize, resize]);
|
|
14989
15037
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
14990
15038
|
const effectiveSize = React.useMemo(() => {
|
|
14991
15039
|
let w = width ?? containerRect.width;
|
|
@@ -15001,9 +15049,7 @@ function CanvasImpl({
|
|
|
15001
15049
|
left: containerRect.left
|
|
15002
15050
|
};
|
|
15003
15051
|
}, [width, height, containerRect, forceEven]);
|
|
15004
|
-
if (!
|
|
15005
|
-
hasInitialSizeRef.current = true;
|
|
15006
|
-
}
|
|
15052
|
+
if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
|
|
15007
15053
|
const canvasRef = React.useRef(null);
|
|
15008
15054
|
const divRef = React.useRef(null);
|
|
15009
15055
|
React.useImperativeHandle(ref, () => canvasRef.current);
|
|
@@ -15117,6 +15163,7 @@ function CanvasImpl({
|
|
|
15117
15163
|
const canvas = canvasRef.current;
|
|
15118
15164
|
if (canvas) {
|
|
15119
15165
|
return () => {
|
|
15166
|
+
if (canvas.isConnected) return;
|
|
15120
15167
|
unmountComponentAtNode(canvas);
|
|
15121
15168
|
root.current = null;
|
|
15122
15169
|
};
|