@react-three/fiber 10.0.0-alpha.3 → 10.0.0-alpha.4
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 +101 -47
- package/dist/index.d.cts +46 -12
- package/dist/index.d.mts +46 -12
- package/dist/index.d.ts +46 -12
- package/dist/index.mjs +101 -47
- package/dist/legacy.cjs +100 -51
- package/dist/legacy.d.cts +45 -15
- package/dist/legacy.d.mts +45 -15
- package/dist/legacy.d.ts +45 -15
- package/dist/legacy.mjs +100 -51
- package/dist/webgpu/index.cjs +154 -75
- package/dist/webgpu/index.d.cts +67 -61
- package/dist/webgpu/index.d.mts +67 -61
- package/dist/webgpu/index.d.ts +67 -61
- package/dist/webgpu/index.mjs +154 -75
- package/package.json +2 -2
package/dist/webgpu/index.cjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const webgpu = require('three/webgpu');
|
|
4
|
-
const Inspector_js = require('three/addons/inspector/Inspector.js');
|
|
5
4
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
5
|
const React = require('react');
|
|
7
6
|
const useMeasure = require('react-use-measure');
|
|
@@ -54,6 +53,10 @@ const Tb__default = /*#__PURE__*/_interopDefaultCompat(Tb);
|
|
|
54
53
|
|
|
55
54
|
const R3F_BUILD_LEGACY = false;
|
|
56
55
|
const R3F_BUILD_WEBGPU = true;
|
|
56
|
+
async function loadInspector() {
|
|
57
|
+
const { Inspector } = await import('three/addons/inspector/Inspector.js');
|
|
58
|
+
return Inspector;
|
|
59
|
+
}
|
|
57
60
|
const WebGLRenderer = class WebGLRenderer2 {
|
|
58
61
|
constructor() {
|
|
59
62
|
throw new Error(
|
|
@@ -67,13 +70,13 @@ const WebGLCubeRenderTarget = null;
|
|
|
67
70
|
const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
68
71
|
__proto__: null,
|
|
69
72
|
CubeRenderTargetCompat: webgpu.CubeRenderTarget,
|
|
70
|
-
Inspector: Inspector_js.Inspector,
|
|
71
73
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
72
74
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
73
75
|
RenderTargetCompat: webgpu.RenderTarget,
|
|
74
76
|
WebGLCubeRenderTarget: WebGLCubeRenderTarget,
|
|
75
77
|
WebGLRenderTarget: WebGLRenderTarget,
|
|
76
|
-
WebGLRenderer: WebGLRenderer
|
|
78
|
+
WebGLRenderer: WebGLRenderer,
|
|
79
|
+
loadInspector: loadInspector
|
|
77
80
|
}, [webgpu__namespace]);
|
|
78
81
|
|
|
79
82
|
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
@@ -932,7 +935,7 @@ const createStore = (invalidate, advance) => {
|
|
|
932
935
|
size: newSize,
|
|
933
936
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
934
937
|
}));
|
|
935
|
-
|
|
938
|
+
get().invalidate();
|
|
936
939
|
}
|
|
937
940
|
}
|
|
938
941
|
return;
|
|
@@ -947,15 +950,16 @@ const createStore = (invalidate, advance) => {
|
|
|
947
950
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
948
951
|
_sizeImperative: true
|
|
949
952
|
}));
|
|
950
|
-
|
|
953
|
+
get().invalidate();
|
|
951
954
|
},
|
|
952
955
|
setDpr: (dpr) => set((state2) => {
|
|
953
956
|
const resolved = calculateDpr(dpr);
|
|
954
957
|
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
955
958
|
}),
|
|
956
959
|
setFrameloop: (frameloop = "always") => {
|
|
960
|
+
const rootId = get().internal.rootId;
|
|
961
|
+
if (rootId) scheduler.getScheduler().setRootFrameloop(rootId, frameloop);
|
|
957
962
|
set(() => ({ frameloop }));
|
|
958
|
-
scheduler.getScheduler().frameloop = frameloop;
|
|
959
963
|
},
|
|
960
964
|
setError: (error) => set(() => ({ error })),
|
|
961
965
|
error: null,
|
|
@@ -1071,17 +1075,10 @@ const createStore = (invalidate, advance) => {
|
|
|
1071
1075
|
oldSize = size;
|
|
1072
1076
|
oldDpr = viewport.dpr;
|
|
1073
1077
|
updateCamera(camera, size);
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1079
|
-
actualRenderer.setSize(size.width, size.height, false);
|
|
1080
|
-
if (canvasTarget) {
|
|
1081
|
-
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1082
|
-
canvasTarget.setSize(size.width, size.height, false);
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1078
|
+
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
1079
|
+
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
1080
|
+
resizeTarget.setSize(size.width, size.height, false);
|
|
1081
|
+
internal.canvasTargetSizeDirty = true;
|
|
1085
1082
|
}
|
|
1086
1083
|
if (camera !== oldCamera) {
|
|
1087
1084
|
oldCamera = camera;
|
|
@@ -1143,7 +1140,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
|
1143
1140
|
const results = cacheKeys.map(
|
|
1144
1141
|
(key, index) => suspendReact.suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1145
1142
|
);
|
|
1146
|
-
|
|
1143
|
+
const stableRef = React.useRef(null);
|
|
1144
|
+
const previous = stableRef.current;
|
|
1145
|
+
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
1146
|
+
stableRef.current = stable;
|
|
1147
|
+
return Array.isArray(input) ? stable : stable[0];
|
|
1147
1148
|
}
|
|
1148
1149
|
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
1149
1150
|
const inputs = Array.isArray(input) ? input : [input];
|
|
@@ -1158,7 +1159,7 @@ useLoader.clear = function(loader, input, cacheKey) {
|
|
|
1158
1159
|
};
|
|
1159
1160
|
useLoader.loader = getLoader$1;
|
|
1160
1161
|
|
|
1161
|
-
function useFrame(callback, priorityOrOptions) {
|
|
1162
|
+
function useFrame$1(callback, priorityOrOptions) {
|
|
1162
1163
|
const store = React__namespace.useContext(context);
|
|
1163
1164
|
const isInsideCanvas = store !== null;
|
|
1164
1165
|
const scheduler$1 = scheduler.getScheduler();
|
|
@@ -1263,6 +1264,13 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1263
1264
|
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1264
1265
|
*/
|
|
1265
1266
|
scheduler: scheduler2,
|
|
1267
|
+
/**
|
|
1268
|
+
* The root that currently owns this job. Resolve on access because ambient
|
|
1269
|
+
* jobs can be adopted by a Canvas after the controls object is created.
|
|
1270
|
+
*/
|
|
1271
|
+
get rootId() {
|
|
1272
|
+
return scheduler.getScheduler().getJobRootId(id);
|
|
1273
|
+
},
|
|
1266
1274
|
/**
|
|
1267
1275
|
* Manually step this job only.
|
|
1268
1276
|
* Bypasses FPS limiting - always runs.
|
|
@@ -1279,6 +1287,14 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1279
1287
|
stepAll: (timestamp) => {
|
|
1280
1288
|
scheduler.getScheduler().step(timestamp);
|
|
1281
1289
|
},
|
|
1290
|
+
/**
|
|
1291
|
+
* Request frames for this job's owning root without waking sibling roots.
|
|
1292
|
+
*/
|
|
1293
|
+
invalidate: (frames, stackFrames) => {
|
|
1294
|
+
const scheduler3 = scheduler.getScheduler();
|
|
1295
|
+
const rootId = scheduler3.getJobRootId(id);
|
|
1296
|
+
if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
|
|
1297
|
+
},
|
|
1282
1298
|
/**
|
|
1283
1299
|
* Pause this job (set enabled=false).
|
|
1284
1300
|
* Job remains registered but won't run.
|
|
@@ -1308,6 +1324,11 @@ function getUrls(input) {
|
|
|
1308
1324
|
if (Array.isArray(input)) return input;
|
|
1309
1325
|
return Object.values(input);
|
|
1310
1326
|
}
|
|
1327
|
+
function inputSignature(input) {
|
|
1328
|
+
if (typeof input === "string") return input;
|
|
1329
|
+
if (Array.isArray(input)) return input.join("\0");
|
|
1330
|
+
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
1331
|
+
}
|
|
1311
1332
|
function allUrlsCached(urls, textureCache) {
|
|
1312
1333
|
return urls.every((url) => textureCache.has(url));
|
|
1313
1334
|
}
|
|
@@ -1326,25 +1347,26 @@ function buildFromCache(input, textureCache) {
|
|
|
1326
1347
|
}
|
|
1327
1348
|
}
|
|
1328
1349
|
function useTexture(input, optionsOrOnLoad) {
|
|
1329
|
-
const renderer = useThree((state) => state.internal.actualRenderer);
|
|
1350
|
+
const renderer = useThree$1((state) => state.internal.actualRenderer);
|
|
1330
1351
|
const store = useStore();
|
|
1331
1352
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
1332
1353
|
const { onLoad, cache = true } = options;
|
|
1333
1354
|
const onLoadRef = React.useRef(onLoad);
|
|
1334
1355
|
onLoadRef.current = onLoad;
|
|
1335
1356
|
const onLoadCalledForRef = React.useRef(null);
|
|
1336
|
-
const
|
|
1357
|
+
const inputKey = React.useMemo(() => inputSignature(input), [input]);
|
|
1358
|
+
const stableInput = React.useMemo(() => input, [inputKey]);
|
|
1359
|
+
const urls = React.useMemo(() => getUrls(stableInput), [stableInput]);
|
|
1337
1360
|
const cachedResult = React.useMemo(() => {
|
|
1338
1361
|
if (!cache) return null;
|
|
1339
1362
|
const textures = store.getState().textures;
|
|
1340
1363
|
if (!allUrlsCached(urls, textures)) return null;
|
|
1341
|
-
return buildFromCache(
|
|
1342
|
-
}, [cache, urls,
|
|
1364
|
+
return buildFromCache(stableInput, textures);
|
|
1365
|
+
}, [cache, urls, stableInput, store]);
|
|
1343
1366
|
const loadedTextures = useLoader(
|
|
1344
1367
|
webgpu.TextureLoader,
|
|
1345
|
-
IsObject(
|
|
1368
|
+
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
1346
1369
|
);
|
|
1347
|
-
const inputKey = urls.join("\0");
|
|
1348
1370
|
React.useLayoutEffect(() => {
|
|
1349
1371
|
if (cachedResult) return;
|
|
1350
1372
|
if (onLoadCalledForRef.current === inputKey) return;
|
|
@@ -1371,28 +1393,28 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1371
1393
|
}, [renderer, loadedTextures, cachedResult]);
|
|
1372
1394
|
const mappedTextures = React.useMemo(() => {
|
|
1373
1395
|
if (cachedResult) return cachedResult;
|
|
1374
|
-
if (IsObject(
|
|
1396
|
+
if (IsObject(stableInput)) {
|
|
1375
1397
|
const keyed = {};
|
|
1376
1398
|
const textureArray = loadedTextures;
|
|
1377
1399
|
let i = 0;
|
|
1378
|
-
for (const key in
|
|
1400
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1379
1401
|
return keyed;
|
|
1380
1402
|
} else {
|
|
1381
1403
|
return loadedTextures;
|
|
1382
1404
|
}
|
|
1383
|
-
}, [
|
|
1405
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
1384
1406
|
React.useEffect(() => {
|
|
1385
1407
|
if (!cache) return;
|
|
1386
1408
|
const urlTextureMap = [];
|
|
1387
|
-
if (typeof
|
|
1388
|
-
urlTextureMap.push([
|
|
1389
|
-
} else if (Array.isArray(
|
|
1409
|
+
if (typeof stableInput === "string") {
|
|
1410
|
+
urlTextureMap.push([stableInput, mappedTextures]);
|
|
1411
|
+
} else if (Array.isArray(stableInput)) {
|
|
1390
1412
|
const textureArray = mappedTextures;
|
|
1391
|
-
|
|
1392
|
-
} else if (IsObject(
|
|
1413
|
+
stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1414
|
+
} else if (IsObject(stableInput)) {
|
|
1393
1415
|
const textureRecord = mappedTextures;
|
|
1394
|
-
for (const key in
|
|
1395
|
-
const url =
|
|
1416
|
+
for (const key in stableInput) {
|
|
1417
|
+
const url = stableInput[key];
|
|
1396
1418
|
urlTextureMap.push([url, textureRecord[key]]);
|
|
1397
1419
|
}
|
|
1398
1420
|
}
|
|
@@ -1421,7 +1443,7 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1421
1443
|
}
|
|
1422
1444
|
return { _textureRefs: refs };
|
|
1423
1445
|
});
|
|
1424
|
-
}, [cache,
|
|
1446
|
+
}, [cache, stableInput, mappedTextures, store]);
|
|
1425
1447
|
return mappedTextures;
|
|
1426
1448
|
}
|
|
1427
1449
|
useTexture.preload = (url) => useLoader.preload(webgpu.TextureLoader, url);
|
|
@@ -1492,13 +1514,13 @@ function useTextures(selector) {
|
|
|
1492
1514
|
};
|
|
1493
1515
|
}, [store]);
|
|
1494
1516
|
const subscribe = selector ? () => selector(registry) : (state) => state.textures;
|
|
1495
|
-
const selected = useThree(subscribe);
|
|
1517
|
+
const selected = useThree$1(subscribe);
|
|
1496
1518
|
return selector ? selected : registry;
|
|
1497
1519
|
}
|
|
1498
1520
|
|
|
1499
1521
|
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
1500
|
-
const isLegacy = useThree((s) => s.isLegacy);
|
|
1501
|
-
const size = useThree((s) => s.size);
|
|
1522
|
+
const isLegacy = useThree$1((s) => s.isLegacy);
|
|
1523
|
+
const size = useThree$1((s) => s.size);
|
|
1502
1524
|
let width;
|
|
1503
1525
|
let height;
|
|
1504
1526
|
let opts;
|
|
@@ -1555,7 +1577,7 @@ function useEnvironment({
|
|
|
1555
1577
|
const { extension, isCubemap } = getExtension(files);
|
|
1556
1578
|
const loader = getLoader(extension);
|
|
1557
1579
|
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1558
|
-
const renderer = useThree((state) => state.renderer);
|
|
1580
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
1559
1581
|
React.useLayoutEffect(() => {
|
|
1560
1582
|
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
1561
1583
|
function clearGainmapTexture() {
|
|
@@ -1648,7 +1670,7 @@ function useStore() {
|
|
|
1648
1670
|
if (!store) throw new Error("R3F: Hooks can only be used within the Canvas component!");
|
|
1649
1671
|
return store;
|
|
1650
1672
|
}
|
|
1651
|
-
function useThree(selector = (state) => state, equalityFn) {
|
|
1673
|
+
function useThree$1(selector = (state) => state, equalityFn) {
|
|
1652
1674
|
return useStore()(selector, equalityFn);
|
|
1653
1675
|
}
|
|
1654
1676
|
function useInstanceHandle(ref) {
|
|
@@ -1690,13 +1712,19 @@ function addTail(callback) {
|
|
|
1690
1712
|
return scheduler.getScheduler().onIdle(callback);
|
|
1691
1713
|
}
|
|
1692
1714
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1693
|
-
|
|
1715
|
+
const rootId = state?.internal?.rootId;
|
|
1716
|
+
const scheduler$1 = scheduler.getScheduler();
|
|
1717
|
+
if (rootId) scheduler$1.invalidateRoot(rootId, frames, stackFrames);
|
|
1718
|
+
else scheduler$1.invalidate(frames, stackFrames);
|
|
1694
1719
|
}
|
|
1695
|
-
function advance(timestamp) {
|
|
1696
|
-
|
|
1720
|
+
function advance(timestamp, runGlobalEffects, state) {
|
|
1721
|
+
const rootId = state?.internal?.rootId;
|
|
1722
|
+
const scheduler$1 = scheduler.getScheduler();
|
|
1723
|
+
if (rootId) scheduler$1.stepRoot(rootId, timestamp);
|
|
1724
|
+
else scheduler$1.step(timestamp);
|
|
1697
1725
|
}
|
|
1698
1726
|
|
|
1699
|
-
const version = "10.0.0-alpha.
|
|
1727
|
+
const version = "10.0.0-alpha.4";
|
|
1700
1728
|
const packageData = {
|
|
1701
1729
|
version: version};
|
|
1702
1730
|
|
|
@@ -14337,7 +14365,7 @@ function createRoot(canvas) {
|
|
|
14337
14365
|
const handleXRFrame = (timestamp, _frame) => {
|
|
14338
14366
|
const state2 = store.getState();
|
|
14339
14367
|
if (state2.frameloop === "never") return;
|
|
14340
|
-
advance(timestamp);
|
|
14368
|
+
advance(timestamp, true, state2);
|
|
14341
14369
|
};
|
|
14342
14370
|
const actualRenderer = state.internal.actualRenderer;
|
|
14343
14371
|
const handleSessionChange = () => {
|
|
@@ -14345,7 +14373,7 @@ function createRoot(canvas) {
|
|
|
14345
14373
|
const renderer2 = state2.internal.actualRenderer;
|
|
14346
14374
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
14347
14375
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
14348
|
-
if (!renderer2.xr.isPresenting) invalidate();
|
|
14376
|
+
if (!renderer2.xr.isPresenting) invalidate(state2);
|
|
14349
14377
|
};
|
|
14350
14378
|
const xr = {
|
|
14351
14379
|
connect() {
|
|
@@ -14427,7 +14455,11 @@ function createRoot(canvas) {
|
|
|
14427
14455
|
const newRootId = canvasId || scheduler$1.generateRootId();
|
|
14428
14456
|
const unregisterRoot = scheduler$1.registerRoot(newRootId, {
|
|
14429
14457
|
getState: () => store.getState(),
|
|
14430
|
-
onError: (err) => store.getState().setError(err)
|
|
14458
|
+
onError: (err) => store.getState().setError(err),
|
|
14459
|
+
frameloop: store.getState().frameloop,
|
|
14460
|
+
before: schedulerConfig?.before,
|
|
14461
|
+
after: schedulerConfig?.after,
|
|
14462
|
+
order: schedulerConfig?.order
|
|
14431
14463
|
});
|
|
14432
14464
|
const unregisterCanvasTarget = scheduler$1.register(
|
|
14433
14465
|
() => {
|
|
@@ -14435,6 +14467,10 @@ function createRoot(canvas) {
|
|
|
14435
14467
|
if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
|
|
14436
14468
|
const renderer2 = state2.internal.actualRenderer;
|
|
14437
14469
|
renderer2.setCanvasTarget(state2.internal.canvasTarget);
|
|
14470
|
+
if (state2.internal.canvasTargetSizeDirty) {
|
|
14471
|
+
state2.internal.canvasTargetSizeDirty = false;
|
|
14472
|
+
renderer2.backend?.updateSize?.();
|
|
14473
|
+
}
|
|
14438
14474
|
}
|
|
14439
14475
|
},
|
|
14440
14476
|
{
|
|
@@ -14503,8 +14539,7 @@ function createRoot(canvas) {
|
|
|
14503
14539
|
phase: "render",
|
|
14504
14540
|
system: true,
|
|
14505
14541
|
// Internal flag: this is a system job, not user-controlled
|
|
14506
|
-
//
|
|
14507
|
-
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
14542
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
14508
14543
|
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14509
14544
|
}
|
|
14510
14545
|
);
|
|
@@ -14523,8 +14558,21 @@ function createRoot(canvas) {
|
|
|
14523
14558
|
scheduler: scheduler$1
|
|
14524
14559
|
}
|
|
14525
14560
|
}));
|
|
14561
|
+
} else {
|
|
14562
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
|
|
14563
|
+
if (constraintsChanged) {
|
|
14564
|
+
scheduler$1.setRootConstraints(rootId, {
|
|
14565
|
+
before: schedulerConfig?.before,
|
|
14566
|
+
after: schedulerConfig?.after
|
|
14567
|
+
});
|
|
14568
|
+
}
|
|
14569
|
+
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
14570
|
+
scheduler$1.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
14571
|
+
}
|
|
14526
14572
|
}
|
|
14527
|
-
|
|
14573
|
+
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
14574
|
+
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
14575
|
+
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
14528
14576
|
onCreated = onCreatedCallback;
|
|
14529
14577
|
configured = true;
|
|
14530
14578
|
resolve();
|
|
@@ -14566,14 +14614,19 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14566
14614
|
const fiber = root?.fiber;
|
|
14567
14615
|
if (fiber) {
|
|
14568
14616
|
const state = root?.store.getState();
|
|
14569
|
-
if (state)
|
|
14617
|
+
if (state) {
|
|
14618
|
+
state.internal.active = false;
|
|
14619
|
+
const unregisterRoot = state.internal.unregisterRoot;
|
|
14620
|
+
if (unregisterRoot) {
|
|
14621
|
+
unregisterRoot();
|
|
14622
|
+
state.internal.unregisterRoot = void 0;
|
|
14623
|
+
}
|
|
14624
|
+
}
|
|
14570
14625
|
reconciler.updateContainer(null, fiber, null, () => {
|
|
14571
14626
|
if (state) {
|
|
14572
14627
|
setTimeout(() => {
|
|
14573
14628
|
try {
|
|
14574
14629
|
const renderer = state.internal.actualRenderer;
|
|
14575
|
-
const unregisterRoot = state.internal.unregisterRoot;
|
|
14576
|
-
if (unregisterRoot) unregisterRoot();
|
|
14577
14630
|
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
14578
14631
|
if (unregisterPrimary) unregisterPrimary();
|
|
14579
14632
|
const canvasTarget = state.internal.canvasTarget;
|
|
@@ -14739,7 +14792,7 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
|
|
|
14739
14792
|
};
|
|
14740
14793
|
}
|
|
14741
14794
|
function EnvironmentMap({ scene, background = false, map, ...config }) {
|
|
14742
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14795
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14743
14796
|
React__namespace.useLayoutEffect(() => {
|
|
14744
14797
|
if (map) return setEnvProps(background, scene, defaultScene, map, config);
|
|
14745
14798
|
});
|
|
@@ -14757,7 +14810,7 @@ function EnvironmentCube({
|
|
|
14757
14810
|
...rest
|
|
14758
14811
|
}) {
|
|
14759
14812
|
const texture = useEnvironment(rest);
|
|
14760
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14813
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14761
14814
|
React__namespace.useLayoutEffect(() => {
|
|
14762
14815
|
return setEnvProps(background, scene, defaultScene, texture, {
|
|
14763
14816
|
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
@@ -14794,9 +14847,9 @@ function EnvironmentPortal({
|
|
|
14794
14847
|
preset = void 0,
|
|
14795
14848
|
extensions
|
|
14796
14849
|
}) {
|
|
14797
|
-
const renderer = useThree((state) => state.renderer);
|
|
14798
|
-
const isLegacy = useThree((state) => state.isLegacy);
|
|
14799
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14850
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
14851
|
+
const isLegacy = useThree$1((state) => state.isLegacy);
|
|
14852
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14800
14853
|
const camera = React__namespace.useRef(null);
|
|
14801
14854
|
const [virtualScene] = React__namespace.useState(() => new webgpu.Scene());
|
|
14802
14855
|
const fbo = React__namespace.useMemo(() => {
|
|
@@ -14840,7 +14893,7 @@ function EnvironmentPortal({
|
|
|
14840
14893
|
environmentRotation
|
|
14841
14894
|
]);
|
|
14842
14895
|
let count = 1;
|
|
14843
|
-
useFrame(() => {
|
|
14896
|
+
useFrame$1(() => {
|
|
14844
14897
|
if (frames === Infinity || count < frames) {
|
|
14845
14898
|
const autoClear = renderer.autoClear;
|
|
14846
14899
|
renderer.autoClear = true;
|
|
@@ -14880,7 +14933,7 @@ function EnvironmentGround(props) {
|
|
|
14880
14933
|
] });
|
|
14881
14934
|
}
|
|
14882
14935
|
function EnvironmentColor({ color, scene }) {
|
|
14883
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14936
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14884
14937
|
React__namespace.useLayoutEffect(() => {
|
|
14885
14938
|
if (color === void 0) return;
|
|
14886
14939
|
const target = resolveScene(scene || defaultScene);
|
|
@@ -15264,6 +15317,7 @@ function CanvasImpl({
|
|
|
15264
15317
|
const canvas = canvasRef.current;
|
|
15265
15318
|
if (canvas) {
|
|
15266
15319
|
return () => {
|
|
15320
|
+
if (canvas.isConnected) return;
|
|
15267
15321
|
unmountComponentAtNode(canvas);
|
|
15268
15322
|
root.current = null;
|
|
15269
15323
|
};
|
|
@@ -15474,6 +15528,11 @@ function createTextureOperations(set) {
|
|
|
15474
15528
|
removeMultiple: (keys) => removeTextures(set, keys)
|
|
15475
15529
|
};
|
|
15476
15530
|
}
|
|
15531
|
+
function scopedNodeName(scope, name) {
|
|
15532
|
+
const raw = scope ? `${scope}_${name}` : name;
|
|
15533
|
+
const safe = raw.replace(/[^A-Za-z0-9_]/g, "_");
|
|
15534
|
+
return /^[A-Za-z_]/.test(safe) ? safe : `_${safe}`;
|
|
15535
|
+
}
|
|
15477
15536
|
function extractTSLValue(value) {
|
|
15478
15537
|
if (value === null || value === void 0) return value;
|
|
15479
15538
|
if (typeof value !== "object") return value;
|
|
@@ -15672,8 +15731,7 @@ function createUniform(inName, node, scope) {
|
|
|
15672
15731
|
const inValue = vectorize(node);
|
|
15673
15732
|
const newUniform = tsl.uniform(inValue);
|
|
15674
15733
|
if (typeof newUniform.setName === "function") {
|
|
15675
|
-
|
|
15676
|
-
newUniform.setName(name);
|
|
15734
|
+
newUniform.setName(scopedNodeName(scope, inName));
|
|
15677
15735
|
}
|
|
15678
15736
|
return newUniform;
|
|
15679
15737
|
}
|
|
@@ -15772,7 +15830,7 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15772
15830
|
return creatorOrScope(createLazyCreatorState(store.getState(), store));
|
|
15773
15831
|
},
|
|
15774
15832
|
prepare: (name, node) => {
|
|
15775
|
-
node.setName?.(scope
|
|
15833
|
+
node.setName?.(scopedNodeName(scope, name));
|
|
15776
15834
|
return node;
|
|
15777
15835
|
}
|
|
15778
15836
|
});
|
|
@@ -15881,7 +15939,7 @@ function useBuffers(creatorOrScope, scope) {
|
|
|
15881
15939
|
},
|
|
15882
15940
|
prepare: (name, buffer) => {
|
|
15883
15941
|
if ("setName" in buffer && typeof buffer.setName === "function") {
|
|
15884
|
-
buffer.setName(scope
|
|
15942
|
+
buffer.setName(scopedNodeName(scope, name));
|
|
15885
15943
|
}
|
|
15886
15944
|
return buffer;
|
|
15887
15945
|
}
|
|
@@ -15952,7 +16010,7 @@ function useGPUStorage(creatorOrScope, scope) {
|
|
|
15952
16010
|
return creatorOrScope(createLazyCreatorState(store.getState(), store));
|
|
15953
16011
|
},
|
|
15954
16012
|
prepare: (name, storage) => {
|
|
15955
|
-
const label = scope
|
|
16013
|
+
const label = scopedNodeName(scope, name);
|
|
15956
16014
|
if ("setName" in storage && typeof storage.setName === "function") {
|
|
15957
16015
|
storage.setName(label);
|
|
15958
16016
|
}
|
|
@@ -15983,9 +16041,10 @@ function rebuildAllStorage(store, scope) {
|
|
|
15983
16041
|
|
|
15984
16042
|
function useRenderPipeline(mainCB, setupCB) {
|
|
15985
16043
|
const store = useStore();
|
|
15986
|
-
const { scene, camera, renderer, isLegacy } = useThree();
|
|
16044
|
+
const { scene, camera, renderer, isLegacy } = useThree$1();
|
|
15987
16045
|
const callbacksRanRef = React.useRef(false);
|
|
15988
16046
|
const scenePassCacheRef = React.useRef(null);
|
|
16047
|
+
const forceScenePassRebuildRef = React.useRef(false);
|
|
15989
16048
|
const mainCBRef = React.useRef(mainCB);
|
|
15990
16049
|
const setupCBRef = React.useRef(setupCB);
|
|
15991
16050
|
mainCBRef.current = mainCB;
|
|
@@ -15993,7 +16052,7 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
15993
16052
|
const [rebuildVersion, setRebuildVersion] = React.useState(0);
|
|
15994
16053
|
React.useEffect(() => {
|
|
15995
16054
|
callbacksRanRef.current = false;
|
|
15996
|
-
|
|
16055
|
+
forceScenePassRebuildRef.current = true;
|
|
15997
16056
|
}, []);
|
|
15998
16057
|
const clearPasses = React.useCallback(() => {
|
|
15999
16058
|
store.setState({ passes: {} });
|
|
@@ -16003,12 +16062,14 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16003
16062
|
renderPipeline: null,
|
|
16004
16063
|
passes: {}
|
|
16005
16064
|
});
|
|
16065
|
+
scenePassCacheRef.current?.scenePass?.dispose?.();
|
|
16006
16066
|
callbacksRanRef.current = false;
|
|
16007
16067
|
scenePassCacheRef.current = null;
|
|
16068
|
+
forceScenePassRebuildRef.current = false;
|
|
16008
16069
|
}, [store]);
|
|
16009
16070
|
const rebuild = React.useCallback(() => {
|
|
16010
16071
|
callbacksRanRef.current = false;
|
|
16011
|
-
|
|
16072
|
+
forceScenePassRebuildRef.current = true;
|
|
16012
16073
|
setRebuildVersion((v) => v + 1);
|
|
16013
16074
|
}, []);
|
|
16014
16075
|
React.useLayoutEffect(() => {
|
|
@@ -16026,21 +16087,31 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16026
16087
|
pipeline = new webgpu.RenderPipeline(renderer);
|
|
16027
16088
|
justCreatedPipeline = true;
|
|
16028
16089
|
}
|
|
16029
|
-
const cacheValid = scenePassCacheRef.current && scenePassCacheRef.current.sceneUuid === scene.uuid && scenePassCacheRef.current.cameraUuid === camera.uuid;
|
|
16090
|
+
const cacheValid = !forceScenePassRebuildRef.current && scenePassCacheRef.current && scenePassCacheRef.current.sceneUuid === scene.uuid && scenePassCacheRef.current.cameraUuid === camera.uuid;
|
|
16091
|
+
let outgoingScenePass = null;
|
|
16030
16092
|
let scenePass;
|
|
16031
16093
|
if (cacheValid) {
|
|
16032
16094
|
scenePass = scenePassCacheRef.current.scenePass;
|
|
16033
16095
|
} else {
|
|
16096
|
+
outgoingScenePass = scenePassCacheRef.current?.scenePass ?? null;
|
|
16034
16097
|
scenePass = tsl.pass(scene, camera);
|
|
16035
16098
|
scenePassCacheRef.current = { sceneUuid: scene.uuid, cameraUuid: camera.uuid, scenePass };
|
|
16099
|
+
forceScenePassRebuildRef.current = false;
|
|
16036
16100
|
}
|
|
16037
16101
|
currentPasses.scenePass = scenePass;
|
|
16038
|
-
|
|
16102
|
+
let outputNodeChanged = false;
|
|
16103
|
+
if (!pipeline.outputNode || justCreatedPipeline || pipeline.outputNode === outgoingScenePass) {
|
|
16104
|
+
pipeline.outputNode = scenePass;
|
|
16105
|
+
outputNodeChanged = true;
|
|
16106
|
+
}
|
|
16039
16107
|
set({ renderPipeline: pipeline, passes: currentPasses });
|
|
16040
16108
|
const shouldRunCallbacks = justCreatedPipeline || !callbacksRanRef.current || !cacheValid;
|
|
16041
16109
|
if (shouldRunCallbacks) {
|
|
16042
16110
|
if (setupCBRef.current) {
|
|
16043
|
-
const freshState = store.getState()
|
|
16111
|
+
const freshState = Object.assign({}, store.getState(), {
|
|
16112
|
+
renderPipeline: pipeline,
|
|
16113
|
+
passes: currentPasses
|
|
16114
|
+
});
|
|
16044
16115
|
const setupResult = setupCBRef.current(freshState);
|
|
16045
16116
|
if (setupResult && typeof setupResult === "object") {
|
|
16046
16117
|
currentPasses = { ...currentPasses, ...setupResult };
|
|
@@ -16048,21 +16119,27 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16048
16119
|
}
|
|
16049
16120
|
}
|
|
16050
16121
|
if (mainCBRef.current) {
|
|
16051
|
-
const freshState = store.getState()
|
|
16122
|
+
const freshState = Object.assign({}, store.getState(), {
|
|
16123
|
+
renderPipeline: pipeline,
|
|
16124
|
+
passes: currentPasses
|
|
16125
|
+
});
|
|
16052
16126
|
const mainResult = mainCBRef.current(freshState);
|
|
16053
16127
|
if (mainResult && typeof mainResult === "object") {
|
|
16054
16128
|
currentPasses = { ...currentPasses, ...mainResult };
|
|
16055
16129
|
set({ passes: currentPasses });
|
|
16056
16130
|
}
|
|
16057
16131
|
}
|
|
16132
|
+
outputNodeChanged = true;
|
|
16058
16133
|
callbacksRanRef.current = true;
|
|
16059
16134
|
}
|
|
16135
|
+
if (outputNodeChanged) pipeline.needsUpdate = true;
|
|
16136
|
+
if (outgoingScenePass && outgoingScenePass !== scenePass) outgoingScenePass.dispose?.();
|
|
16060
16137
|
} catch (error) {
|
|
16061
16138
|
console.warn("[useRenderPipeline] Setup failed; the render pipeline was not configured:", error);
|
|
16062
16139
|
}
|
|
16063
16140
|
}, [store, renderer, scene, camera, isLegacy, rebuildVersion]);
|
|
16064
|
-
const passes = useThree((s) => s.passes);
|
|
16065
|
-
const renderPipeline = useThree((s) => s.renderPipeline);
|
|
16141
|
+
const passes = useThree$1((s) => s.passes);
|
|
16142
|
+
const renderPipeline = useThree$1((s) => s.renderPipeline);
|
|
16066
16143
|
return {
|
|
16067
16144
|
passes,
|
|
16068
16145
|
renderPipeline,
|
|
@@ -16075,6 +16152,8 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16075
16152
|
}
|
|
16076
16153
|
|
|
16077
16154
|
extend(THREE);
|
|
16155
|
+
const useThree = useThree$1;
|
|
16156
|
+
const useFrame = useFrame$1;
|
|
16078
16157
|
|
|
16079
16158
|
exports.Scheduler = scheduler.Scheduler;
|
|
16080
16159
|
exports.getScheduler = scheduler.getScheduler;
|