@react-three/fiber 10.0.0-canary.ac30da2 → 10.0.0-canary.af75fd4
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 +72 -30
- package/dist/index.d.cts +162 -25
- package/dist/index.d.mts +162 -25
- package/dist/index.d.ts +162 -25
- package/dist/index.mjs +72 -30
- package/dist/legacy.cjs +69 -26
- package/dist/legacy.d.cts +162 -25
- package/dist/legacy.d.mts +162 -25
- package/dist/legacy.d.ts +162 -25
- package/dist/legacy.mjs +69 -26
- package/dist/webgpu/index.cjs +92 -43
- package/dist/webgpu/index.d.cts +165 -40
- package/dist/webgpu/index.d.mts +165 -40
- package/dist/webgpu/index.d.ts +165 -40
- package/dist/webgpu/index.mjs +92 -43
- package/package.json +2 -2
package/dist/webgpu/index.mjs
CHANGED
|
@@ -915,7 +915,7 @@ const createStore = (invalidate, advance) => {
|
|
|
915
915
|
size: newSize,
|
|
916
916
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
917
917
|
}));
|
|
918
|
-
|
|
918
|
+
get().invalidate();
|
|
919
919
|
}
|
|
920
920
|
}
|
|
921
921
|
return;
|
|
@@ -930,15 +930,16 @@ const createStore = (invalidate, advance) => {
|
|
|
930
930
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
931
931
|
_sizeImperative: true
|
|
932
932
|
}));
|
|
933
|
-
|
|
933
|
+
get().invalidate();
|
|
934
934
|
},
|
|
935
935
|
setDpr: (dpr) => set((state2) => {
|
|
936
936
|
const resolved = calculateDpr(dpr);
|
|
937
937
|
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
938
938
|
}),
|
|
939
939
|
setFrameloop: (frameloop = "always") => {
|
|
940
|
+
const rootId = get().internal.rootId;
|
|
941
|
+
if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
|
|
940
942
|
set(() => ({ frameloop }));
|
|
941
|
-
getScheduler().frameloop = frameloop;
|
|
942
943
|
},
|
|
943
944
|
setError: (error) => set(() => ({ error })),
|
|
944
945
|
error: null,
|
|
@@ -1057,7 +1058,8 @@ const createStore = (invalidate, advance) => {
|
|
|
1057
1058
|
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
1058
1059
|
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
1059
1060
|
resizeTarget.setSize(size.width, size.height, false);
|
|
1060
|
-
|
|
1061
|
+
const activeTarget = actualRenderer.getCanvasTarget?.();
|
|
1062
|
+
if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
|
|
1061
1063
|
}
|
|
1062
1064
|
if (camera !== oldCamera) {
|
|
1063
1065
|
oldCamera = camera;
|
|
@@ -1243,6 +1245,13 @@ function useFrame$1(callback, priorityOrOptions) {
|
|
|
1243
1245
|
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1244
1246
|
*/
|
|
1245
1247
|
scheduler: scheduler2,
|
|
1248
|
+
/**
|
|
1249
|
+
* The root that currently owns this job. Resolve on access because ambient
|
|
1250
|
+
* jobs can be adopted by a Canvas after the controls object is created.
|
|
1251
|
+
*/
|
|
1252
|
+
get rootId() {
|
|
1253
|
+
return getScheduler().getJobRootId(id);
|
|
1254
|
+
},
|
|
1246
1255
|
/**
|
|
1247
1256
|
* Manually step this job only.
|
|
1248
1257
|
* Bypasses FPS limiting - always runs.
|
|
@@ -1259,6 +1268,14 @@ function useFrame$1(callback, priorityOrOptions) {
|
|
|
1259
1268
|
stepAll: (timestamp) => {
|
|
1260
1269
|
getScheduler().step(timestamp);
|
|
1261
1270
|
},
|
|
1271
|
+
/**
|
|
1272
|
+
* Request frames for this job's owning root without waking sibling roots.
|
|
1273
|
+
*/
|
|
1274
|
+
invalidate: (frames, stackFrames) => {
|
|
1275
|
+
const scheduler3 = getScheduler();
|
|
1276
|
+
const rootId = scheduler3.getJobRootId(id);
|
|
1277
|
+
if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
|
|
1278
|
+
},
|
|
1262
1279
|
/**
|
|
1263
1280
|
* Pause this job (set enabled=false).
|
|
1264
1281
|
* Job remains registered but won't run.
|
|
@@ -1676,13 +1693,19 @@ function addTail(callback) {
|
|
|
1676
1693
|
return getScheduler().onIdle(callback);
|
|
1677
1694
|
}
|
|
1678
1695
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1679
|
-
|
|
1696
|
+
const rootId = state?.internal?.rootId;
|
|
1697
|
+
const scheduler = getScheduler();
|
|
1698
|
+
if (rootId) scheduler.invalidateRoot(rootId, frames, stackFrames);
|
|
1699
|
+
else scheduler.invalidate(frames, stackFrames);
|
|
1680
1700
|
}
|
|
1681
|
-
function advance(timestamp) {
|
|
1682
|
-
|
|
1701
|
+
function advance(timestamp, runGlobalEffects, state) {
|
|
1702
|
+
const rootId = state?.internal?.rootId;
|
|
1703
|
+
const scheduler = getScheduler();
|
|
1704
|
+
if (rootId) scheduler.stepRoot(rootId, timestamp);
|
|
1705
|
+
else scheduler.step(timestamp);
|
|
1683
1706
|
}
|
|
1684
1707
|
|
|
1685
|
-
const version = "10.0.0-alpha.
|
|
1708
|
+
const version = "10.0.0-alpha.4";
|
|
1686
1709
|
const packageData = {
|
|
1687
1710
|
version: version};
|
|
1688
1711
|
|
|
@@ -14198,9 +14221,8 @@ function createRoot(canvas) {
|
|
|
14198
14221
|
if (!renderer.hasInitialized?.()) {
|
|
14199
14222
|
const size2 = computeInitialSize(canvas, propsSize);
|
|
14200
14223
|
if (size2.width > 0 && size2.height > 0) {
|
|
14201
|
-
|
|
14202
|
-
|
|
14203
|
-
canvas.height = size2.height * pixelRatio;
|
|
14224
|
+
renderer.setPixelRatio(calculateDpr(dpr));
|
|
14225
|
+
renderer.setSize(size2.width, size2.height, false);
|
|
14204
14226
|
}
|
|
14205
14227
|
await renderer.init();
|
|
14206
14228
|
}
|
|
@@ -14209,7 +14231,7 @@ function createRoot(canvas) {
|
|
|
14209
14231
|
state.internal.actualRenderer = renderer;
|
|
14210
14232
|
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
14211
14233
|
if (canvasId && !state.internal.isSecondary) {
|
|
14212
|
-
const canvasTarget =
|
|
14234
|
+
const canvasTarget = renderer.getCanvasTarget?.();
|
|
14213
14235
|
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
14214
14236
|
state.set((prev) => ({
|
|
14215
14237
|
internal: {
|
|
@@ -14323,7 +14345,7 @@ function createRoot(canvas) {
|
|
|
14323
14345
|
const handleXRFrame = (timestamp, _frame) => {
|
|
14324
14346
|
const state2 = store.getState();
|
|
14325
14347
|
if (state2.frameloop === "never") return;
|
|
14326
|
-
advance(timestamp);
|
|
14348
|
+
advance(timestamp, true, state2);
|
|
14327
14349
|
};
|
|
14328
14350
|
const actualRenderer = state.internal.actualRenderer;
|
|
14329
14351
|
const handleSessionChange = () => {
|
|
@@ -14331,7 +14353,7 @@ function createRoot(canvas) {
|
|
|
14331
14353
|
const renderer2 = state2.internal.actualRenderer;
|
|
14332
14354
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
14333
14355
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
14334
|
-
if (!renderer2.xr.isPresenting) invalidate();
|
|
14356
|
+
if (!renderer2.xr.isPresenting) invalidate(state2);
|
|
14335
14357
|
};
|
|
14336
14358
|
const xr = {
|
|
14337
14359
|
connect() {
|
|
@@ -14413,14 +14435,19 @@ function createRoot(canvas) {
|
|
|
14413
14435
|
const newRootId = canvasId || scheduler.generateRootId();
|
|
14414
14436
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14415
14437
|
getState: () => store.getState(),
|
|
14416
|
-
onError: (err) => store.getState().setError(err)
|
|
14438
|
+
onError: (err) => store.getState().setError(err),
|
|
14439
|
+
frameloop: store.getState().frameloop,
|
|
14440
|
+
before: schedulerConfig?.before,
|
|
14441
|
+
after: schedulerConfig?.after,
|
|
14442
|
+
order: schedulerConfig?.order
|
|
14417
14443
|
});
|
|
14418
14444
|
const unregisterCanvasTarget = scheduler.register(
|
|
14419
14445
|
() => {
|
|
14420
14446
|
const state2 = store.getState();
|
|
14421
|
-
|
|
14447
|
+
const canvasTarget = state2.internal.canvasTarget;
|
|
14448
|
+
if (canvasTarget) {
|
|
14422
14449
|
const renderer2 = state2.internal.actualRenderer;
|
|
14423
|
-
renderer2.setCanvasTarget(
|
|
14450
|
+
if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
|
|
14424
14451
|
if (state2.internal.canvasTargetSizeDirty) {
|
|
14425
14452
|
state2.internal.canvasTargetSizeDirty = false;
|
|
14426
14453
|
renderer2.backend?.updateSize?.();
|
|
@@ -14493,8 +14520,7 @@ function createRoot(canvas) {
|
|
|
14493
14520
|
phase: "render",
|
|
14494
14521
|
system: true,
|
|
14495
14522
|
// Internal flag: this is a system job, not user-controlled
|
|
14496
|
-
//
|
|
14497
|
-
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
14523
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
14498
14524
|
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14499
14525
|
}
|
|
14500
14526
|
);
|
|
@@ -14513,8 +14539,21 @@ function createRoot(canvas) {
|
|
|
14513
14539
|
scheduler
|
|
14514
14540
|
}
|
|
14515
14541
|
}));
|
|
14542
|
+
} else {
|
|
14543
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
|
|
14544
|
+
if (constraintsChanged) {
|
|
14545
|
+
scheduler.setRootConstraints(rootId, {
|
|
14546
|
+
before: schedulerConfig?.before,
|
|
14547
|
+
after: schedulerConfig?.after
|
|
14548
|
+
});
|
|
14549
|
+
}
|
|
14550
|
+
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
14551
|
+
scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
14552
|
+
}
|
|
14516
14553
|
}
|
|
14517
|
-
|
|
14554
|
+
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
14555
|
+
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
14556
|
+
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
14518
14557
|
onCreated = onCreatedCallback;
|
|
14519
14558
|
configured = true;
|
|
14520
14559
|
resolve();
|
|
@@ -14556,18 +14595,23 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14556
14595
|
const fiber = root?.fiber;
|
|
14557
14596
|
if (fiber) {
|
|
14558
14597
|
const state = root?.store.getState();
|
|
14559
|
-
if (state)
|
|
14598
|
+
if (state) {
|
|
14599
|
+
state.internal.active = false;
|
|
14600
|
+
const unregisterRoot = state.internal.unregisterRoot;
|
|
14601
|
+
if (unregisterRoot) {
|
|
14602
|
+
unregisterRoot();
|
|
14603
|
+
state.internal.unregisterRoot = void 0;
|
|
14604
|
+
}
|
|
14605
|
+
}
|
|
14560
14606
|
reconciler.updateContainer(null, fiber, null, () => {
|
|
14561
14607
|
if (state) {
|
|
14562
14608
|
setTimeout(() => {
|
|
14563
14609
|
try {
|
|
14564
14610
|
const renderer = state.internal.actualRenderer;
|
|
14565
|
-
const unregisterRoot = state.internal.unregisterRoot;
|
|
14566
|
-
if (unregisterRoot) unregisterRoot();
|
|
14567
14611
|
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
14568
14612
|
if (unregisterPrimary) unregisterPrimary();
|
|
14569
14613
|
const canvasTarget = state.internal.canvasTarget;
|
|
14570
|
-
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14614
|
+
if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
|
|
14571
14615
|
state.events.disconnect?.();
|
|
14572
14616
|
cleanupHelperGroup(root.store);
|
|
14573
14617
|
if (state.isLegacy && renderer) {
|
|
@@ -15108,9 +15152,9 @@ function CanvasImpl({
|
|
|
15108
15152
|
React.useMemo(() => extend(THREE), []);
|
|
15109
15153
|
const Bridge = useBridge();
|
|
15110
15154
|
const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
|
|
15111
|
-
const
|
|
15155
|
+
const [hasInitialSize, setHasInitialSize] = React.useState(false);
|
|
15112
15156
|
const measureConfig = React.useMemo(() => {
|
|
15113
|
-
if (!
|
|
15157
|
+
if (!hasInitialSize) {
|
|
15114
15158
|
return {
|
|
15115
15159
|
...resize,
|
|
15116
15160
|
scroll: resize?.scroll ?? true,
|
|
@@ -15122,7 +15166,7 @@ function CanvasImpl({
|
|
|
15122
15166
|
debounce: { scroll: 50, resize: 0 },
|
|
15123
15167
|
...resize
|
|
15124
15168
|
};
|
|
15125
|
-
}, [
|
|
15169
|
+
}, [hasInitialSize, resize]);
|
|
15126
15170
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
15127
15171
|
const effectiveSize = React.useMemo(() => {
|
|
15128
15172
|
let w = width ?? containerRect.width;
|
|
@@ -15138,9 +15182,7 @@ function CanvasImpl({
|
|
|
15138
15182
|
left: containerRect.left
|
|
15139
15183
|
};
|
|
15140
15184
|
}, [width, height, containerRect, forceEven]);
|
|
15141
|
-
if (!
|
|
15142
|
-
hasInitialSizeRef.current = true;
|
|
15143
|
-
}
|
|
15185
|
+
if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
|
|
15144
15186
|
const canvasRef = React.useRef(null);
|
|
15145
15187
|
const divRef = React.useRef(null);
|
|
15146
15188
|
React.useImperativeHandle(ref, () => canvasRef.current);
|
|
@@ -15999,7 +16041,7 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
15999
16041
|
renderPipeline: null,
|
|
16000
16042
|
passes: {}
|
|
16001
16043
|
});
|
|
16002
|
-
scenePassCacheRef.current?.scenePass
|
|
16044
|
+
scenePassCacheRef.current?.scenePass.dispose();
|
|
16003
16045
|
callbacksRanRef.current = false;
|
|
16004
16046
|
scenePassCacheRef.current = null;
|
|
16005
16047
|
forceScenePassRebuildRef.current = false;
|
|
@@ -16014,6 +16056,9 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16014
16056
|
throw new Error("useRenderPipeline is only available with WebGPU renderer. Set renderer prop on Canvas.");
|
|
16015
16057
|
}
|
|
16016
16058
|
if (!renderer || !scene || !camera) return;
|
|
16059
|
+
if (!("isWebGPURenderer" in renderer)) {
|
|
16060
|
+
throw new Error("useRenderPipeline: renderer is not a WebGPURenderer but isLegacy is false.");
|
|
16061
|
+
}
|
|
16017
16062
|
const state = store.getState();
|
|
16018
16063
|
const set = store.setState;
|
|
16019
16064
|
try {
|
|
@@ -16045,7 +16090,12 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16045
16090
|
const shouldRunCallbacks = justCreatedPipeline || !callbacksRanRef.current || !cacheValid;
|
|
16046
16091
|
if (shouldRunCallbacks) {
|
|
16047
16092
|
if (setupCBRef.current) {
|
|
16048
|
-
const freshState = store.getState()
|
|
16093
|
+
const freshState = Object.assign({}, store.getState(), {
|
|
16094
|
+
renderPipeline: pipeline,
|
|
16095
|
+
passes: { ...currentPasses, scenePass },
|
|
16096
|
+
renderer,
|
|
16097
|
+
isLegacy: false
|
|
16098
|
+
});
|
|
16049
16099
|
const setupResult = setupCBRef.current(freshState);
|
|
16050
16100
|
if (setupResult && typeof setupResult === "object") {
|
|
16051
16101
|
currentPasses = { ...currentPasses, ...setupResult };
|
|
@@ -16053,7 +16103,12 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16053
16103
|
}
|
|
16054
16104
|
}
|
|
16055
16105
|
if (mainCBRef.current) {
|
|
16056
|
-
const freshState = store.getState()
|
|
16106
|
+
const freshState = Object.assign({}, store.getState(), {
|
|
16107
|
+
renderPipeline: pipeline,
|
|
16108
|
+
passes: { ...currentPasses, scenePass },
|
|
16109
|
+
renderer,
|
|
16110
|
+
isLegacy: false
|
|
16111
|
+
});
|
|
16057
16112
|
const mainResult = mainCBRef.current(freshState);
|
|
16058
16113
|
if (mainResult && typeof mainResult === "object") {
|
|
16059
16114
|
currentPasses = { ...currentPasses, ...mainResult };
|
|
@@ -16064,22 +16119,16 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16064
16119
|
callbacksRanRef.current = true;
|
|
16065
16120
|
}
|
|
16066
16121
|
if (outputNodeChanged) pipeline.needsUpdate = true;
|
|
16067
|
-
if (outgoingScenePass && outgoingScenePass !== scenePass) outgoingScenePass.dispose
|
|
16122
|
+
if (outgoingScenePass && outgoingScenePass !== scenePass) outgoingScenePass.dispose();
|
|
16068
16123
|
} catch (error) {
|
|
16069
16124
|
console.warn("[useRenderPipeline] Setup failed; the render pipeline was not configured:", error);
|
|
16070
16125
|
}
|
|
16071
16126
|
}, [store, renderer, scene, camera, isLegacy, rebuildVersion]);
|
|
16072
16127
|
const passes = useThree$1((s) => s.passes);
|
|
16073
16128
|
const renderPipeline = useThree$1((s) => s.renderPipeline);
|
|
16074
|
-
|
|
16075
|
-
|
|
16076
|
-
|
|
16077
|
-
clearPasses,
|
|
16078
|
-
reset,
|
|
16079
|
-
rebuild,
|
|
16080
|
-
// isReady indicates if RenderPipeline is configured and ready for rendering
|
|
16081
|
-
isReady: renderPipeline !== null
|
|
16082
|
-
};
|
|
16129
|
+
const actions = { passes, clearPasses, reset, rebuild };
|
|
16130
|
+
if (renderPipeline) return { ...actions, isReady: true, renderPipeline };
|
|
16131
|
+
return { ...actions, isReady: false, renderPipeline: null };
|
|
16083
16132
|
}
|
|
16084
16133
|
|
|
16085
16134
|
extend(THREE);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-three/fiber",
|
|
3
|
-
"version": "10.0.0-canary.
|
|
3
|
+
"version": "10.0.0-canary.af75fd4",
|
|
4
4
|
"description": "A React renderer for Threejs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@babel/runtime": "^7.28.6",
|
|
60
60
|
"@monogrid/gainmap-js": "^3.4.0",
|
|
61
|
-
"@pmndrs/scheduler": "^0.
|
|
61
|
+
"@pmndrs/scheduler": "^0.2.0",
|
|
62
62
|
"dequal": "^2.0.3",
|
|
63
63
|
"its-fine": "^2.0.0",
|
|
64
64
|
"react-use-measure": "^2.1.7",
|