@react-three/fiber 10.0.0-canary.8f5b4d3 → 10.0.0-canary.ac30da2
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 +49 -33
- package/dist/index.d.cts +18 -1
- package/dist/index.d.mts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.mjs +49 -33
- package/dist/legacy.cjs +48 -37
- package/dist/legacy.d.cts +17 -4
- package/dist/legacy.d.mts +17 -4
- package/dist/legacy.d.ts +17 -4
- package/dist/legacy.mjs +48 -37
- package/dist/webgpu/index.cjs +94 -59
- package/dist/webgpu/index.d.cts +40 -51
- package/dist/webgpu/index.d.mts +40 -51
- package/dist/webgpu/index.d.ts +40 -51
- package/dist/webgpu/index.mjs +94 -59
- package/package.json +3 -3
- package/readme.md +1 -1
- package/react-reconciler/constants.d.ts +0 -7
- package/react-reconciler/constants.js +0 -1
- package/react-reconciler/index.d.ts +0 -1044
- package/react-reconciler/index.js +0 -208
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();
|
|
@@ -1071,17 +1074,10 @@ const createStore = (invalidate, advance) => {
|
|
|
1071
1074
|
oldSize = size;
|
|
1072
1075
|
oldDpr = viewport.dpr;
|
|
1073
1076
|
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
|
-
}
|
|
1077
|
+
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
1078
|
+
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
1079
|
+
resizeTarget.setSize(size.width, size.height, false);
|
|
1080
|
+
internal.canvasTargetSizeDirty = true;
|
|
1085
1081
|
}
|
|
1086
1082
|
if (camera !== oldCamera) {
|
|
1087
1083
|
oldCamera = camera;
|
|
@@ -1143,7 +1139,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
|
1143
1139
|
const results = cacheKeys.map(
|
|
1144
1140
|
(key, index) => suspendReact.suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1145
1141
|
);
|
|
1146
|
-
|
|
1142
|
+
const stableRef = React.useRef(null);
|
|
1143
|
+
const previous = stableRef.current;
|
|
1144
|
+
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
1145
|
+
stableRef.current = stable;
|
|
1146
|
+
return Array.isArray(input) ? stable : stable[0];
|
|
1147
1147
|
}
|
|
1148
1148
|
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
1149
1149
|
const inputs = Array.isArray(input) ? input : [input];
|
|
@@ -1158,7 +1158,7 @@ useLoader.clear = function(loader, input, cacheKey) {
|
|
|
1158
1158
|
};
|
|
1159
1159
|
useLoader.loader = getLoader$1;
|
|
1160
1160
|
|
|
1161
|
-
function useFrame(callback, priorityOrOptions) {
|
|
1161
|
+
function useFrame$1(callback, priorityOrOptions) {
|
|
1162
1162
|
const store = React__namespace.useContext(context);
|
|
1163
1163
|
const isInsideCanvas = store !== null;
|
|
1164
1164
|
const scheduler$1 = scheduler.getScheduler();
|
|
@@ -1308,6 +1308,11 @@ function getUrls(input) {
|
|
|
1308
1308
|
if (Array.isArray(input)) return input;
|
|
1309
1309
|
return Object.values(input);
|
|
1310
1310
|
}
|
|
1311
|
+
function inputSignature(input) {
|
|
1312
|
+
if (typeof input === "string") return input;
|
|
1313
|
+
if (Array.isArray(input)) return input.join("\0");
|
|
1314
|
+
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
1315
|
+
}
|
|
1311
1316
|
function allUrlsCached(urls, textureCache) {
|
|
1312
1317
|
return urls.every((url) => textureCache.has(url));
|
|
1313
1318
|
}
|
|
@@ -1326,25 +1331,26 @@ function buildFromCache(input, textureCache) {
|
|
|
1326
1331
|
}
|
|
1327
1332
|
}
|
|
1328
1333
|
function useTexture(input, optionsOrOnLoad) {
|
|
1329
|
-
const renderer = useThree((state) => state.internal.actualRenderer);
|
|
1334
|
+
const renderer = useThree$1((state) => state.internal.actualRenderer);
|
|
1330
1335
|
const store = useStore();
|
|
1331
1336
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
1332
1337
|
const { onLoad, cache = true } = options;
|
|
1333
1338
|
const onLoadRef = React.useRef(onLoad);
|
|
1334
1339
|
onLoadRef.current = onLoad;
|
|
1335
1340
|
const onLoadCalledForRef = React.useRef(null);
|
|
1336
|
-
const
|
|
1341
|
+
const inputKey = React.useMemo(() => inputSignature(input), [input]);
|
|
1342
|
+
const stableInput = React.useMemo(() => input, [inputKey]);
|
|
1343
|
+
const urls = React.useMemo(() => getUrls(stableInput), [stableInput]);
|
|
1337
1344
|
const cachedResult = React.useMemo(() => {
|
|
1338
1345
|
if (!cache) return null;
|
|
1339
1346
|
const textures = store.getState().textures;
|
|
1340
1347
|
if (!allUrlsCached(urls, textures)) return null;
|
|
1341
|
-
return buildFromCache(
|
|
1342
|
-
}, [cache, urls,
|
|
1348
|
+
return buildFromCache(stableInput, textures);
|
|
1349
|
+
}, [cache, urls, stableInput, store]);
|
|
1343
1350
|
const loadedTextures = useLoader(
|
|
1344
1351
|
webgpu.TextureLoader,
|
|
1345
|
-
IsObject(
|
|
1352
|
+
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
1346
1353
|
);
|
|
1347
|
-
const inputKey = urls.join("\0");
|
|
1348
1354
|
React.useLayoutEffect(() => {
|
|
1349
1355
|
if (cachedResult) return;
|
|
1350
1356
|
if (onLoadCalledForRef.current === inputKey) return;
|
|
@@ -1371,28 +1377,28 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1371
1377
|
}, [renderer, loadedTextures, cachedResult]);
|
|
1372
1378
|
const mappedTextures = React.useMemo(() => {
|
|
1373
1379
|
if (cachedResult) return cachedResult;
|
|
1374
|
-
if (IsObject(
|
|
1380
|
+
if (IsObject(stableInput)) {
|
|
1375
1381
|
const keyed = {};
|
|
1376
1382
|
const textureArray = loadedTextures;
|
|
1377
1383
|
let i = 0;
|
|
1378
|
-
for (const key in
|
|
1384
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1379
1385
|
return keyed;
|
|
1380
1386
|
} else {
|
|
1381
1387
|
return loadedTextures;
|
|
1382
1388
|
}
|
|
1383
|
-
}, [
|
|
1389
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
1384
1390
|
React.useEffect(() => {
|
|
1385
1391
|
if (!cache) return;
|
|
1386
1392
|
const urlTextureMap = [];
|
|
1387
|
-
if (typeof
|
|
1388
|
-
urlTextureMap.push([
|
|
1389
|
-
} else if (Array.isArray(
|
|
1393
|
+
if (typeof stableInput === "string") {
|
|
1394
|
+
urlTextureMap.push([stableInput, mappedTextures]);
|
|
1395
|
+
} else if (Array.isArray(stableInput)) {
|
|
1390
1396
|
const textureArray = mappedTextures;
|
|
1391
|
-
|
|
1392
|
-
} else if (IsObject(
|
|
1397
|
+
stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1398
|
+
} else if (IsObject(stableInput)) {
|
|
1393
1399
|
const textureRecord = mappedTextures;
|
|
1394
|
-
for (const key in
|
|
1395
|
-
const url =
|
|
1400
|
+
for (const key in stableInput) {
|
|
1401
|
+
const url = stableInput[key];
|
|
1396
1402
|
urlTextureMap.push([url, textureRecord[key]]);
|
|
1397
1403
|
}
|
|
1398
1404
|
}
|
|
@@ -1421,7 +1427,7 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1421
1427
|
}
|
|
1422
1428
|
return { _textureRefs: refs };
|
|
1423
1429
|
});
|
|
1424
|
-
}, [cache,
|
|
1430
|
+
}, [cache, stableInput, mappedTextures, store]);
|
|
1425
1431
|
return mappedTextures;
|
|
1426
1432
|
}
|
|
1427
1433
|
useTexture.preload = (url) => useLoader.preload(webgpu.TextureLoader, url);
|
|
@@ -1492,13 +1498,13 @@ function useTextures(selector) {
|
|
|
1492
1498
|
};
|
|
1493
1499
|
}, [store]);
|
|
1494
1500
|
const subscribe = selector ? () => selector(registry) : (state) => state.textures;
|
|
1495
|
-
const selected = useThree(subscribe);
|
|
1501
|
+
const selected = useThree$1(subscribe);
|
|
1496
1502
|
return selector ? selected : registry;
|
|
1497
1503
|
}
|
|
1498
1504
|
|
|
1499
1505
|
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
1500
|
-
const isLegacy = useThree((s) => s.isLegacy);
|
|
1501
|
-
const size = useThree((s) => s.size);
|
|
1506
|
+
const isLegacy = useThree$1((s) => s.isLegacy);
|
|
1507
|
+
const size = useThree$1((s) => s.size);
|
|
1502
1508
|
let width;
|
|
1503
1509
|
let height;
|
|
1504
1510
|
let opts;
|
|
@@ -1555,7 +1561,7 @@ function useEnvironment({
|
|
|
1555
1561
|
const { extension, isCubemap } = getExtension(files);
|
|
1556
1562
|
const loader = getLoader(extension);
|
|
1557
1563
|
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1558
|
-
const renderer = useThree((state) => state.renderer);
|
|
1564
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
1559
1565
|
React.useLayoutEffect(() => {
|
|
1560
1566
|
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
1561
1567
|
function clearGainmapTexture() {
|
|
@@ -1648,7 +1654,7 @@ function useStore() {
|
|
|
1648
1654
|
if (!store) throw new Error("R3F: Hooks can only be used within the Canvas component!");
|
|
1649
1655
|
return store;
|
|
1650
1656
|
}
|
|
1651
|
-
function useThree(selector = (state) => state, equalityFn) {
|
|
1657
|
+
function useThree$1(selector = (state) => state, equalityFn) {
|
|
1652
1658
|
return useStore()(selector, equalityFn);
|
|
1653
1659
|
}
|
|
1654
1660
|
function useInstanceHandle(ref) {
|
|
@@ -12979,7 +12985,10 @@ function releaseInternalPointerCapture(internal, obj, pointerId) {
|
|
|
12979
12985
|
const captureData = pointerState.captured.get(obj);
|
|
12980
12986
|
if (captureData) {
|
|
12981
12987
|
pointerState.captured.delete(obj);
|
|
12982
|
-
|
|
12988
|
+
try {
|
|
12989
|
+
captureData.target.releasePointerCapture?.(pointerId);
|
|
12990
|
+
} catch {
|
|
12991
|
+
}
|
|
12983
12992
|
}
|
|
12984
12993
|
}
|
|
12985
12994
|
function swapInteractivity(store, object, newObject) {
|
|
@@ -13073,7 +13082,9 @@ function createEvents(store) {
|
|
|
13073
13082
|
state2.events.compute?.(event, state2, state2.previousRoot?.getState());
|
|
13074
13083
|
if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
|
|
13075
13084
|
}
|
|
13076
|
-
|
|
13085
|
+
if (!state2.raycaster.camera) return [];
|
|
13086
|
+
obj.updateWorldMatrix(true, true);
|
|
13087
|
+
return state2.raycaster.intersectObject(obj, true);
|
|
13077
13088
|
}
|
|
13078
13089
|
let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
|
|
13079
13090
|
const aInteractivePriority = a.object.userData?.interactivePriority;
|
|
@@ -14430,6 +14441,10 @@ function createRoot(canvas) {
|
|
|
14430
14441
|
if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
|
|
14431
14442
|
const renderer2 = state2.internal.actualRenderer;
|
|
14432
14443
|
renderer2.setCanvasTarget(state2.internal.canvasTarget);
|
|
14444
|
+
if (state2.internal.canvasTargetSizeDirty) {
|
|
14445
|
+
state2.internal.canvasTargetSizeDirty = false;
|
|
14446
|
+
renderer2.backend?.updateSize?.();
|
|
14447
|
+
}
|
|
14433
14448
|
}
|
|
14434
14449
|
},
|
|
14435
14450
|
{
|
|
@@ -14734,7 +14749,7 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
|
|
|
14734
14749
|
};
|
|
14735
14750
|
}
|
|
14736
14751
|
function EnvironmentMap({ scene, background = false, map, ...config }) {
|
|
14737
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14752
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14738
14753
|
React__namespace.useLayoutEffect(() => {
|
|
14739
14754
|
if (map) return setEnvProps(background, scene, defaultScene, map, config);
|
|
14740
14755
|
});
|
|
@@ -14752,7 +14767,7 @@ function EnvironmentCube({
|
|
|
14752
14767
|
...rest
|
|
14753
14768
|
}) {
|
|
14754
14769
|
const texture = useEnvironment(rest);
|
|
14755
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14770
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14756
14771
|
React__namespace.useLayoutEffect(() => {
|
|
14757
14772
|
return setEnvProps(background, scene, defaultScene, texture, {
|
|
14758
14773
|
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
@@ -14789,9 +14804,9 @@ function EnvironmentPortal({
|
|
|
14789
14804
|
preset = void 0,
|
|
14790
14805
|
extensions
|
|
14791
14806
|
}) {
|
|
14792
|
-
const renderer = useThree((state) => state.renderer);
|
|
14793
|
-
const isLegacy = useThree((state) => state.isLegacy);
|
|
14794
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14807
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
14808
|
+
const isLegacy = useThree$1((state) => state.isLegacy);
|
|
14809
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14795
14810
|
const camera = React__namespace.useRef(null);
|
|
14796
14811
|
const [virtualScene] = React__namespace.useState(() => new webgpu.Scene());
|
|
14797
14812
|
const fbo = React__namespace.useMemo(() => {
|
|
@@ -14835,7 +14850,7 @@ function EnvironmentPortal({
|
|
|
14835
14850
|
environmentRotation
|
|
14836
14851
|
]);
|
|
14837
14852
|
let count = 1;
|
|
14838
|
-
useFrame(() => {
|
|
14853
|
+
useFrame$1(() => {
|
|
14839
14854
|
if (frames === Infinity || count < frames) {
|
|
14840
14855
|
const autoClear = renderer.autoClear;
|
|
14841
14856
|
renderer.autoClear = true;
|
|
@@ -14875,7 +14890,7 @@ function EnvironmentGround(props) {
|
|
|
14875
14890
|
] });
|
|
14876
14891
|
}
|
|
14877
14892
|
function EnvironmentColor({ color, scene }) {
|
|
14878
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14893
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14879
14894
|
React__namespace.useLayoutEffect(() => {
|
|
14880
14895
|
if (color === void 0) return;
|
|
14881
14896
|
const target = resolveScene(scene || defaultScene);
|
|
@@ -15259,6 +15274,7 @@ function CanvasImpl({
|
|
|
15259
15274
|
const canvas = canvasRef.current;
|
|
15260
15275
|
if (canvas) {
|
|
15261
15276
|
return () => {
|
|
15277
|
+
if (canvas.isConnected) return;
|
|
15262
15278
|
unmountComponentAtNode(canvas);
|
|
15263
15279
|
root.current = null;
|
|
15264
15280
|
};
|
|
@@ -15469,6 +15485,11 @@ function createTextureOperations(set) {
|
|
|
15469
15485
|
removeMultiple: (keys) => removeTextures(set, keys)
|
|
15470
15486
|
};
|
|
15471
15487
|
}
|
|
15488
|
+
function scopedNodeName(scope, name) {
|
|
15489
|
+
const raw = scope ? `${scope}_${name}` : name;
|
|
15490
|
+
const safe = raw.replace(/[^A-Za-z0-9_]/g, "_");
|
|
15491
|
+
return /^[A-Za-z_]/.test(safe) ? safe : `_${safe}`;
|
|
15492
|
+
}
|
|
15472
15493
|
function extractTSLValue(value) {
|
|
15473
15494
|
if (value === null || value === void 0) return value;
|
|
15474
15495
|
if (typeof value !== "object") return value;
|
|
@@ -15667,8 +15688,7 @@ function createUniform(inName, node, scope) {
|
|
|
15667
15688
|
const inValue = vectorize(node);
|
|
15668
15689
|
const newUniform = tsl.uniform(inValue);
|
|
15669
15690
|
if (typeof newUniform.setName === "function") {
|
|
15670
|
-
|
|
15671
|
-
newUniform.setName(name);
|
|
15691
|
+
newUniform.setName(scopedNodeName(scope, inName));
|
|
15672
15692
|
}
|
|
15673
15693
|
return newUniform;
|
|
15674
15694
|
}
|
|
@@ -15767,7 +15787,7 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15767
15787
|
return creatorOrScope(createLazyCreatorState(store.getState(), store));
|
|
15768
15788
|
},
|
|
15769
15789
|
prepare: (name, node) => {
|
|
15770
|
-
node.setName?.(scope
|
|
15790
|
+
node.setName?.(scopedNodeName(scope, name));
|
|
15771
15791
|
return node;
|
|
15772
15792
|
}
|
|
15773
15793
|
});
|
|
@@ -15876,7 +15896,7 @@ function useBuffers(creatorOrScope, scope) {
|
|
|
15876
15896
|
},
|
|
15877
15897
|
prepare: (name, buffer) => {
|
|
15878
15898
|
if ("setName" in buffer && typeof buffer.setName === "function") {
|
|
15879
|
-
buffer.setName(scope
|
|
15899
|
+
buffer.setName(scopedNodeName(scope, name));
|
|
15880
15900
|
}
|
|
15881
15901
|
return buffer;
|
|
15882
15902
|
}
|
|
@@ -15947,7 +15967,7 @@ function useGPUStorage(creatorOrScope, scope) {
|
|
|
15947
15967
|
return creatorOrScope(createLazyCreatorState(store.getState(), store));
|
|
15948
15968
|
},
|
|
15949
15969
|
prepare: (name, storage) => {
|
|
15950
|
-
const label = scope
|
|
15970
|
+
const label = scopedNodeName(scope, name);
|
|
15951
15971
|
if ("setName" in storage && typeof storage.setName === "function") {
|
|
15952
15972
|
storage.setName(label);
|
|
15953
15973
|
}
|
|
@@ -15978,9 +15998,10 @@ function rebuildAllStorage(store, scope) {
|
|
|
15978
15998
|
|
|
15979
15999
|
function useRenderPipeline(mainCB, setupCB) {
|
|
15980
16000
|
const store = useStore();
|
|
15981
|
-
const { scene, camera, renderer, isLegacy } = useThree();
|
|
16001
|
+
const { scene, camera, renderer, isLegacy } = useThree$1();
|
|
15982
16002
|
const callbacksRanRef = React.useRef(false);
|
|
15983
16003
|
const scenePassCacheRef = React.useRef(null);
|
|
16004
|
+
const forceScenePassRebuildRef = React.useRef(false);
|
|
15984
16005
|
const mainCBRef = React.useRef(mainCB);
|
|
15985
16006
|
const setupCBRef = React.useRef(setupCB);
|
|
15986
16007
|
mainCBRef.current = mainCB;
|
|
@@ -15988,7 +16009,7 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
15988
16009
|
const [rebuildVersion, setRebuildVersion] = React.useState(0);
|
|
15989
16010
|
React.useEffect(() => {
|
|
15990
16011
|
callbacksRanRef.current = false;
|
|
15991
|
-
|
|
16012
|
+
forceScenePassRebuildRef.current = true;
|
|
15992
16013
|
}, []);
|
|
15993
16014
|
const clearPasses = React.useCallback(() => {
|
|
15994
16015
|
store.setState({ passes: {} });
|
|
@@ -15998,12 +16019,14 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
15998
16019
|
renderPipeline: null,
|
|
15999
16020
|
passes: {}
|
|
16000
16021
|
});
|
|
16022
|
+
scenePassCacheRef.current?.scenePass?.dispose?.();
|
|
16001
16023
|
callbacksRanRef.current = false;
|
|
16002
16024
|
scenePassCacheRef.current = null;
|
|
16025
|
+
forceScenePassRebuildRef.current = false;
|
|
16003
16026
|
}, [store]);
|
|
16004
16027
|
const rebuild = React.useCallback(() => {
|
|
16005
16028
|
callbacksRanRef.current = false;
|
|
16006
|
-
|
|
16029
|
+
forceScenePassRebuildRef.current = true;
|
|
16007
16030
|
setRebuildVersion((v) => v + 1);
|
|
16008
16031
|
}, []);
|
|
16009
16032
|
React.useLayoutEffect(() => {
|
|
@@ -16021,16 +16044,23 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16021
16044
|
pipeline = new webgpu.RenderPipeline(renderer);
|
|
16022
16045
|
justCreatedPipeline = true;
|
|
16023
16046
|
}
|
|
16024
|
-
const cacheValid = scenePassCacheRef.current && scenePassCacheRef.current.sceneUuid === scene.uuid && scenePassCacheRef.current.cameraUuid === camera.uuid;
|
|
16047
|
+
const cacheValid = !forceScenePassRebuildRef.current && scenePassCacheRef.current && scenePassCacheRef.current.sceneUuid === scene.uuid && scenePassCacheRef.current.cameraUuid === camera.uuid;
|
|
16048
|
+
let outgoingScenePass = null;
|
|
16025
16049
|
let scenePass;
|
|
16026
16050
|
if (cacheValid) {
|
|
16027
16051
|
scenePass = scenePassCacheRef.current.scenePass;
|
|
16028
16052
|
} else {
|
|
16053
|
+
outgoingScenePass = scenePassCacheRef.current?.scenePass ?? null;
|
|
16029
16054
|
scenePass = tsl.pass(scene, camera);
|
|
16030
16055
|
scenePassCacheRef.current = { sceneUuid: scene.uuid, cameraUuid: camera.uuid, scenePass };
|
|
16056
|
+
forceScenePassRebuildRef.current = false;
|
|
16031
16057
|
}
|
|
16032
16058
|
currentPasses.scenePass = scenePass;
|
|
16033
|
-
|
|
16059
|
+
let outputNodeChanged = false;
|
|
16060
|
+
if (!pipeline.outputNode || justCreatedPipeline || pipeline.outputNode === outgoingScenePass) {
|
|
16061
|
+
pipeline.outputNode = scenePass;
|
|
16062
|
+
outputNodeChanged = true;
|
|
16063
|
+
}
|
|
16034
16064
|
set({ renderPipeline: pipeline, passes: currentPasses });
|
|
16035
16065
|
const shouldRunCallbacks = justCreatedPipeline || !callbacksRanRef.current || !cacheValid;
|
|
16036
16066
|
if (shouldRunCallbacks) {
|
|
@@ -16050,14 +16080,17 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16050
16080
|
set({ passes: currentPasses });
|
|
16051
16081
|
}
|
|
16052
16082
|
}
|
|
16083
|
+
outputNodeChanged = true;
|
|
16053
16084
|
callbacksRanRef.current = true;
|
|
16054
16085
|
}
|
|
16086
|
+
if (outputNodeChanged) pipeline.needsUpdate = true;
|
|
16087
|
+
if (outgoingScenePass && outgoingScenePass !== scenePass) outgoingScenePass.dispose?.();
|
|
16055
16088
|
} catch (error) {
|
|
16056
16089
|
console.warn("[useRenderPipeline] Setup failed; the render pipeline was not configured:", error);
|
|
16057
16090
|
}
|
|
16058
16091
|
}, [store, renderer, scene, camera, isLegacy, rebuildVersion]);
|
|
16059
|
-
const passes = useThree((s) => s.passes);
|
|
16060
|
-
const renderPipeline = useThree((s) => s.renderPipeline);
|
|
16092
|
+
const passes = useThree$1((s) => s.passes);
|
|
16093
|
+
const renderPipeline = useThree$1((s) => s.renderPipeline);
|
|
16061
16094
|
return {
|
|
16062
16095
|
passes,
|
|
16063
16096
|
renderPipeline,
|
|
@@ -16070,6 +16103,8 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16070
16103
|
}
|
|
16071
16104
|
|
|
16072
16105
|
extend(THREE);
|
|
16106
|
+
const useThree = useThree$1;
|
|
16107
|
+
const useFrame = useFrame$1;
|
|
16073
16108
|
|
|
16074
16109
|
exports.Scheduler = scheduler.Scheduler;
|
|
16075
16110
|
exports.getScheduler = scheduler.getScheduler;
|
package/dist/webgpu/index.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as three_examples_jsm_inspector_Inspector_js from 'three/examples/jsm/inspector/Inspector.js';
|
|
1
2
|
import * as three_webgpu from 'three/webgpu';
|
|
2
3
|
import { CubeRenderTarget, RenderTarget, WebGPURenderer, Node, StorageTexture, Data3DTexture, CanvasTarget, ShaderNodeObject, Euler as Euler$2, Color as Color$2, ColorRepresentation as ColorRepresentation$1, Layers as Layers$1, Raycaster, Intersection as Intersection$1, BufferGeometry, Matrix4 as Matrix4$1, Quaternion as Quaternion$1, Vector2 as Vector2$1, Vector3 as Vector3$1, Vector4 as Vector4$1, Matrix3 as Matrix3$1, Loader as Loader$1, ColorSpace, Texture as Texture$1, CubeTexture, Scene, Object3D, Frustum, OrthographicCamera, WebGPURendererParameters } from 'three/webgpu';
|
|
3
4
|
import { Inspector } from 'three/addons/inspector/Inspector.js';
|
|
@@ -40,6 +41,8 @@ function _mergeNamespaces(n, m) {
|
|
|
40
41
|
declare const R3F_BUILD_LEGACY = false;
|
|
41
42
|
declare const R3F_BUILD_WEBGPU = true;
|
|
42
43
|
|
|
44
|
+
/** Lazily load the three Inspector. Keeps it out of the eager module graph — see note above. */
|
|
45
|
+
declare function loadInspector(): Promise<typeof three_examples_jsm_inspector_Inspector_js.Inspector>;
|
|
43
46
|
declare const WebGLRenderer: {
|
|
44
47
|
new (): {};
|
|
45
48
|
};
|
|
@@ -61,7 +64,8 @@ var THREE = /*#__PURE__*/_mergeNamespaces({
|
|
|
61
64
|
WebGLRenderTarget: WebGLRenderTarget,
|
|
62
65
|
WebGLRenderer: WebGLRenderer,
|
|
63
66
|
WebGLRendererParameters: WebGLRendererParameters,
|
|
64
|
-
WebGLShadowMap: WebGLShadowMap
|
|
67
|
+
WebGLShadowMap: WebGLShadowMap,
|
|
68
|
+
loadInspector: loadInspector
|
|
65
69
|
}, [three_webgpu]);
|
|
66
70
|
|
|
67
71
|
//* Utility Types ==============================
|
|
@@ -499,6 +503,18 @@ interface InternalState {
|
|
|
499
503
|
* @see https://threejs.org/docs/#api/en/renderers/common/CanvasTarget
|
|
500
504
|
*/
|
|
501
505
|
canvasTarget?: CanvasTarget
|
|
506
|
+
/**
|
|
507
|
+
* Set when this root's canvas target has been resized and the backend's cached render pass
|
|
508
|
+
* descriptor (which holds a depth-stencil view built once per canvas) is therefore stale.
|
|
509
|
+
*
|
|
510
|
+
* Flushed by the canvas-target job in the `start` phase, which is the only place this root's
|
|
511
|
+
* target is guaranteed to be the renderer's active one — `backend.updateSize()` operates on
|
|
512
|
+
* whatever `getCanvasTarget()` returns, so calling it from the resize subscription would
|
|
513
|
+
* invalidate some other canvas's descriptor instead.
|
|
514
|
+
*
|
|
515
|
+
* @see https://github.com/pmndrs/react-three-fiber/issues/3847
|
|
516
|
+
*/
|
|
517
|
+
canvasTargetSizeDirty?: boolean
|
|
502
518
|
/**
|
|
503
519
|
* Whether multi-canvas rendering is active.
|
|
504
520
|
* True when any canvas uses `renderer={{ primaryCanvas: 'id' }}` to share a renderer.
|
|
@@ -1868,50 +1884,6 @@ declare namespace useLoader {
|
|
|
1868
1884
|
var loader: typeof getLoader;
|
|
1869
1885
|
}
|
|
1870
1886
|
|
|
1871
|
-
/**
|
|
1872
|
-
* Frame hook with phase-based ordering, priority, and FPS throttling.
|
|
1873
|
-
*
|
|
1874
|
-
* Always delivers full RootState — works both inside and outside Canvas context:
|
|
1875
|
-
* - Inside Canvas: Full RootState (renderer, scene, camera, etc.)
|
|
1876
|
-
* - Outside Canvas: The job registers immediately but the callback is held until a
|
|
1877
|
-
* Canvas adopts it, then runs with full RootState. For hostless / standalone
|
|
1878
|
-
* frame loops with no Canvas, use `@pmndrs/scheduler` directly.
|
|
1879
|
-
*
|
|
1880
|
-
* Returns a controls object for manual stepping, pausing, and resuming.
|
|
1881
|
-
*
|
|
1882
|
-
* @param callback - Function called each frame with (state, delta). Optional if you only need scheduler access.
|
|
1883
|
-
* @param priorityOrOptions - Either a priority number (backwards compat) or options object
|
|
1884
|
-
* @returns Controls object with step(), stepAll(), pause(), resume(), isPaused, id, scheduler
|
|
1885
|
-
*
|
|
1886
|
-
* @example
|
|
1887
|
-
* // Simple priority (backwards compat)
|
|
1888
|
-
* useFrame((state, delta) => { ... }, 5)
|
|
1889
|
-
*
|
|
1890
|
-
* @example
|
|
1891
|
-
* // With phase-based ordering
|
|
1892
|
-
* useFrame((state, delta) => { ... }, { phase: 'physics' })
|
|
1893
|
-
*
|
|
1894
|
-
* @example
|
|
1895
|
-
* // Outside Canvas - callback waits for a Canvas, then always has full state
|
|
1896
|
-
* function UI() {
|
|
1897
|
-
* useFrame((state, delta) => { syncUI(state.camera) });
|
|
1898
|
-
* return <button>...</button>;
|
|
1899
|
-
* }
|
|
1900
|
-
*
|
|
1901
|
-
* @example
|
|
1902
|
-
* // Hostless / standalone loop (no Canvas) - use @pmndrs/scheduler directly
|
|
1903
|
-
* import { getScheduler } from '@pmndrs/scheduler'
|
|
1904
|
-
* getScheduler().register((state, delta) => { updateGame(delta) })
|
|
1905
|
-
*
|
|
1906
|
-
* @example
|
|
1907
|
-
* // Scheduler-only access (no callback)
|
|
1908
|
-
* const { scheduler } = useFrame()
|
|
1909
|
-
* scheduler.pauseJob('some-job-id')
|
|
1910
|
-
*
|
|
1911
|
-
* @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
|
|
1912
|
-
*/
|
|
1913
|
-
declare function useFrame(callback?: FrameNextCallback, priorityOrOptions?: number | UseFrameNextOptions): FrameNextControls;
|
|
1914
|
-
|
|
1915
1887
|
declare const IsObject: (url: unknown) => url is Record<string, string>;
|
|
1916
1888
|
type TextureArray<T> = T extends string[] ? Texture$1[] : never;
|
|
1917
1889
|
type TextureRecord<T> = T extends Record<string, string> ? {
|
|
@@ -2097,11 +2069,6 @@ declare function useRenderTarget(width: number, height: number, options?: Render
|
|
|
2097
2069
|
* @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
|
|
2098
2070
|
*/
|
|
2099
2071
|
declare function useStore(): RootStore;
|
|
2100
|
-
/**
|
|
2101
|
-
* Accesses R3F's internal state, containing renderer, canvas, scene, etc.
|
|
2102
|
-
* @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
|
|
2103
|
-
*/
|
|
2104
|
-
declare function useThree<T = RootState>(selector?: (state: RootState) => T, equalityFn?: <T>(state: T, newState: T) => boolean): T;
|
|
2105
2072
|
/**
|
|
2106
2073
|
* Exposes an object's {@link Instance}.
|
|
2107
2074
|
* @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
|
|
@@ -4086,6 +4053,10 @@ declare function createTextureOperations(set: StoreApi<RootState>['setState']):
|
|
|
4086
4053
|
* - Callbacks receive full RootState for flexibility
|
|
4087
4054
|
* - No auto-cleanup on unmount - use reset() for explicit cleanup
|
|
4088
4055
|
* - Scene/camera changes trigger scenePass recreation
|
|
4056
|
+
* - A replaced scenePass is disposed once the new graph is installed, so rebuild() does not
|
|
4057
|
+
* strand its render target (and MRT attachments) on the GPU
|
|
4058
|
+
* - Any run that changes the output node sets RenderPipeline.needsUpdate, so rebuild() actually
|
|
4059
|
+
* recompiles instead of silently keeping the first compiled graph
|
|
4089
4060
|
*
|
|
4090
4061
|
* @param mainCB - Main callback to configure outputNode and create effect passes
|
|
4091
4062
|
* @param setupCB - Optional setup callback to configure MRT on scenePass
|
|
@@ -4163,5 +4134,23 @@ interface WebGPURootState extends Omit<RootState, 'renderer' | 'gl' | 'internal'
|
|
|
4163
4134
|
internal: WebGPUInternalState
|
|
4164
4135
|
}
|
|
4165
4136
|
|
|
4137
|
+
/**
|
|
4138
|
+
* @fileoverview WebGPU entry point - WebGPU only, no legacy WebGL
|
|
4139
|
+
*
|
|
4140
|
+
* This entry point is for apps that want to use ONLY WebGPURenderer.
|
|
4141
|
+
* Includes WebGPU-specific hooks (useUniforms, useNodes, useTextures).
|
|
4142
|
+
* Auto-extends THREE with WebGPU node materials (MeshBasicNodeMaterial, etc.)
|
|
4143
|
+
*
|
|
4144
|
+
* Usage:
|
|
4145
|
+
* import { Canvas, useFrame, useUniforms } from '@react-three/fiber/webgpu'
|
|
4146
|
+
*/
|
|
4147
|
+
|
|
4148
|
+
/** `useThree` narrowed to WebGPU state — `state.renderer` is a `WebGPURenderer`. */
|
|
4149
|
+
type UseThreeWebGPU = <T = WebGPURootState>(selector?: (state: WebGPURootState) => T, equalityFn?: <U>(state: U, newState: U) => boolean) => T;
|
|
4150
|
+
/** `useFrame` narrowed to WebGPU state — the callback's `state.renderer` is a `WebGPURenderer`. */
|
|
4151
|
+
type UseFrameWebGPU = (callback?: FrameCallback$1<WebGPURootState>, priorityOrOptions?: number | UseFrameNextOptions) => FrameNextControls;
|
|
4152
|
+
declare const useThree: UseThreeWebGPU;
|
|
4153
|
+
declare const useFrame: UseFrameWebGPU;
|
|
4154
|
+
|
|
4166
4155
|
export { Block, Canvas, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, ErrorBoundary, FROM_REF, IsObject, ONCE, Portal, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, three_d as ReactThreeFiber, Texture, _roots, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, clearNodeScope, clearRootNodes, clearRootUniforms, clearScope, context, createEvents, createPointerEvents, createPortal, createRoot, createScopedStore, createStore, createTextureOperations, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, fromRef, getInstanceProps, getPrimary, getPrimaryIds, getRootState, getUuidPrefix, hasConstructor, hasPrimary, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isFromRef, isObject3D, isOnce, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, once, prepare, presetsObj, rebuildAllBuffers, rebuildAllNodes, rebuildAllStorage, rebuildAllUniforms, reconciler, registerPrimary, removeInteractivity, removeNodes, removeUniforms, resolve, swapInteractivity, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useBuffers, useEnvironment, useFrame, useGPUStorage, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes, useRenderPipeline, useRenderTarget, useStore, useTexture, useTextures, useThree, useUniform, useUniforms, waitForPrimary };
|
|
4167
|
-
export type { Act, Args, ArgsProp, AttachFnType, AttachType, BackgroundConfig, BackgroundProp, BaseRendererProps, Bridge, BufferCreator, BufferLike, BufferRecord, BufferStore, BuffersWithUtils, Camera, CameraProps, CanvasProps, CanvasSchedulerConfig, Catalogue, ClearBuffersFn, ClearNodesFn, ClearStorageFn, ClearUniformsFn, Color, ColorManagementConfig, ComputeFunction, ConstructorRepresentation, CreatorState, DefaultGLProps, DefaultRendererProps, Disposable, DisposeBuffersFn, DisposeOptions, DisposeStorageFn, DomEvent, Dpr, ElementProps, EnvironmentLoaderProps, EnvironmentProps, EquConfig, Euler, EventHandlers, EventManager, EventProps, Events, Extensions, FiberRoot, FilterFunction, FrameCallback, FrameNextCallback, FrameNextState, FrameState, Frameloop, GLProps, GLTFLike, GeometryProps, GeometryTransformProps, GlobalEffectType, GlobalRenderCallback, HostConfig, InferLoadResult, InjectState, InputLike, Instance, InstanceProps, WebGPUInternalState as InternalState, Intersection, IntersectionEvent, IsAllOptional, IsOptional, Layers, LegacyInternalState, LegacyRenderer, LegacyRootState, LoaderInstance, LoaderLike, LoaderResult, LocalNodeCreator, MappedTextureType, MathProps, MathRepresentation, MathType, MathTypes, Matrix3, Matrix4, Mutable, MutableOrReadonlyParameters, NodeCreator, NodeProps, NodeRecord, NodesWithUtils, NonFunctionKeys, ObjectMap, OffscreenCanvas$1 as OffscreenCanvas, Overwrite, Performance, PointerCaptureTarget, PointerState, PresetsType, PrimaryCanvasEntry, Properties, Quaternion, WebGPUR3FRenderer as R3FRenderer, RaycastableRepresentation, ReactProps, RebuildBuffersFn, RebuildNodesFn, RebuildStorageFn, RebuildUniformsFn, ReconcilerRoot, RemoveBuffersFn, RemoveNodesFn, RemoveStorageFn, RemoveUniformsFn, RenderCallback, RenderProps, RenderTargetOptions, Renderer, RendererConfigExtended, RendererFactory, RendererProps, Root, WebGPURootState as RootState, RootStore, ScopedStoreType, SetBlock, Size, StorageCreator, StorageLike, StorageRecord, StorageStore, StorageWithUtils, Subscription, TSLNode, TSLNodeInput, TextureEntry, TextureInput, TextureNode, TextureOperations, TextureResult, ThreeCamera, ThreeElement, ThreeElements, ThreeElementsImpl, ThreeEvent, ThreeExports, ThreeToJSXElements, UnblockProps, UniformCreator, UniformValue, UniformsWithUtils, UseTextureOptions, UseTexturesReturn, Vector2, Vector3, Vector4, VectorRepresentation, Viewport, VisibilityEntry, WebGLDefaultProps, WebGLProps, WebGLShadowConfig, WebGPUDefaultProps, WebGPUProps, WebGPUShadowConfig, XRManager, XRPointerConfig };
|
|
4156
|
+
export type { Act, Args, ArgsProp, AttachFnType, AttachType, BackgroundConfig, BackgroundProp, BaseRendererProps, Bridge, BufferCreator, BufferLike, BufferRecord, BufferStore, BuffersWithUtils, Camera, CameraProps, CanvasProps, CanvasSchedulerConfig, Catalogue, ClearBuffersFn, ClearNodesFn, ClearStorageFn, ClearUniformsFn, Color, ColorManagementConfig, ComputeFunction, ConstructorRepresentation, CreatorState, DefaultGLProps, DefaultRendererProps, Disposable, DisposeBuffersFn, DisposeOptions, DisposeStorageFn, DomEvent, Dpr, ElementProps, EnvironmentLoaderProps, EnvironmentProps, EquConfig, Euler, EventHandlers, EventManager, EventProps, Events, Extensions, FiberRoot, FilterFunction, FrameCallback, FrameNextCallback, FrameNextState, FrameState, Frameloop, GLProps, GLTFLike, GeometryProps, GeometryTransformProps, GlobalEffectType, GlobalRenderCallback, HostConfig, InferLoadResult, InjectState, InputLike, Instance, InstanceProps, WebGPUInternalState as InternalState, Intersection, IntersectionEvent, IsAllOptional, IsOptional, Layers, LegacyInternalState, LegacyRenderer, LegacyRootState, LoaderInstance, LoaderLike, LoaderResult, LocalNodeCreator, MappedTextureType, MathProps, MathRepresentation, MathType, MathTypes, Matrix3, Matrix4, Mutable, MutableOrReadonlyParameters, NodeCreator, NodeProps, NodeRecord, NodesWithUtils, NonFunctionKeys, ObjectMap, OffscreenCanvas$1 as OffscreenCanvas, Overwrite, Performance, PointerCaptureTarget, PointerState, PresetsType, PrimaryCanvasEntry, Properties, Quaternion, WebGPUR3FRenderer as R3FRenderer, RaycastableRepresentation, ReactProps, RebuildBuffersFn, RebuildNodesFn, RebuildStorageFn, RebuildUniformsFn, ReconcilerRoot, RemoveBuffersFn, RemoveNodesFn, RemoveStorageFn, RemoveUniformsFn, RenderCallback, RenderProps, RenderTargetOptions, Renderer, RendererConfigExtended, RendererFactory, RendererProps, Root, WebGPURootState as RootState, RootStore, ScopedStoreType, SetBlock, Size, StorageCreator, StorageLike, StorageRecord, StorageStore, StorageWithUtils, Subscription, TSLNode, TSLNodeInput, TextureEntry, TextureInput, TextureNode, TextureOperations, TextureResult, ThreeCamera, ThreeElement, ThreeElements, ThreeElementsImpl, ThreeEvent, ThreeExports, ThreeToJSXElements, UnblockProps, UniformCreator, UniformValue, UniformsWithUtils, UseFrameWebGPU, UseTextureOptions, UseTexturesReturn, UseThreeWebGPU, Vector2, Vector3, Vector4, VectorRepresentation, Viewport, VisibilityEntry, WebGLDefaultProps, WebGLProps, WebGLShadowConfig, WebGPUDefaultProps, WebGPUProps, WebGPUShadowConfig, XRManager, XRPointerConfig };
|