diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz
index 823302577..864caffcf 100644
Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ
diff --git a/README.md b/README.md
index be0cbec95..dfcae1a00 100644
--- a/README.md
+++ b/README.md
@@ -3449,6 +3449,30 @@ You can define events on them!
```
+If you need nested, multiple instances in the same parent graph, it would normally not work because an `` is directly paired to its nearest `` provider. You can use the global `createInstances` helper for such cases, it creates dedicated instances-instance pairs. The first return value is the provider, the second the instance component. Both take the same properties as `` and ``.
+
+```jsx
+const [CubeInstances, Cube] = createInstances()
+const [SphereInstances, Sphere] = createInstances()
+
+function App() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
+```
+
👉 Note: While creating instances declaratively keeps all the power of components with reduced draw calls, it comes at the cost of CPU overhead. For cases like foliage where you want no CPU overhead with thousands of intances you should use THREE.InstancedMesh such as in this [example](https://codesandbox.io/s/grass-shader-5xho4?file=/src/Grass.js).
#### Merged
diff --git a/src/core/Instances.tsx b/src/core/Instances.tsx
index bfe7b2c9e..82c5fb674 100644
--- a/src/core/Instances.tsx
+++ b/src/core/Instances.tsx
@@ -19,6 +19,7 @@ type Api = {
}
export type InstancesProps = JSX.IntrinsicElements['instancedMesh'] & {
+ context?: React.Context
range?: number
limit?: number
frames?: number
@@ -113,15 +114,17 @@ export const Instance = /* @__PURE__ */ React.forwardRef(({ context, children, .
)
})
-export const Instances: ForwardRefComponent = /* @__PURE__ */ React.forwardRef<
- InstancedMesh,
+export const Instances: ForwardRefComponent = /* @__PURE__ */ React.forwardRef<
+ THREE.InstancedMesh,
InstancesProps
->(({ children, range, limit = 1000, frames = Infinity, ...props }, ref) => {
- const [{ context, instance }] = React.useState(() => {
- const context = React.createContext(null!)
+>(({ context, children, range, limit = 1000, frames = Infinity, ...props }, ref) => {
+ const [{ localContext, instance }] = React.useState(() => {
+ const localContext = React.createContext(null!)
return {
- context,
- instance: React.forwardRef((props: InstanceProps, ref) => ),
+ localContext,
+ instance: React.forwardRef((props: InstanceProps, ref) => (
+
+ )),
}
})
@@ -202,7 +205,9 @@ export const Instances: ForwardRefComponent = /*
usage={THREE.DynamicDrawUsage}
/>
{isFunctionChild(children) ? (
- {children(instance)}
+ {children(instance)}
+ ) : context ? (
+ {children}
) : (
{children}
)}
@@ -241,3 +246,15 @@ export const Merged: ForwardRefComponent = /* @__PURE__ */ Rea
)
}
)
+
+export function createInstances() {
+ const context = React.createContext(null!)
+ return [
+ React.forwardRef((props, fref) => (
+
+ )),
+ React.forwardRef((props, fref) => (
+
+ )),
+ ]
+}