From 5cf91329f1053401a57e3174aa168d6d400391b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Fri, 16 Aug 2024 10:04:50 +0200 Subject: [PATCH] feat: createInstances --- .yarn/install-state.gz | Bin 1740390 -> 1740390 bytes README.md | 24 ++++++++++++++++++++++++ src/core/Instances.tsx | 33 +++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz index 823302577796f7521f72a123e9e60f1f0ec13e9f..864caffcf816c3215a9f4fabace065089ed6246f 100644 GIT binary patch delta 793 zcmV+!1LpkZoNDHrYJh|RgaU*Egam{Iga(8Mgb0KQgbIWUgbaiYgbsucgb;)ggc5`k zgcO7ogcgJsgcyVwv>K3$f3G7}5kp}LI)s!bpxA~6A&))d@uUPPFF?7{O7_^JtacHR zHmP_m5WG%af*PGm3R0v=iln{W{hK*+Y@d&i_1|+w>h!Fx7FhK(M>m;uW5M0Tf9bC2kwIl`OPA$>oUh5b!Dt$1+PQoC!3coQ{(%0t{SqF~pSK^G zLVNx2cYojh-+_Jp&v!S^9)H^pFYX`f=a;n~p5FZWUk6o(VCIG$7DWo{p`lbkl~Y=V z6rh`uhgty8>4-tsW=b5bw(8*+MjH(1SjA*c8CVIs4LIqUe{J#!u4u(8$;c|Z#*pPV z-#$Iuzj{^q)0_LpeER-}uWp_J+4b(iFR%S|UEc(C2Qc(<0<4bg!~ngCj2PWj5U;Pt zDGr3lS|v=DV=Z%=IC5RMYMx5k+(4ypBA*tJDZ>~7Y<6_tcQ11sUUDLf%Lar6qz~gh zM|sOJJd97Le|_bFp$;#7OKVHO$#m02J1C@-3Q6VemCl0x{MB}2J()Ij&8_0OGq-rh z_JL62sV%N3Gt`XP6yS%Ze7Pws&7iu=`rhfwytiY7R)%T|ul z#zjIAoM>Aul`(T+N+GOlY*Jw3-LS=A)BK3$f2<=`5kpZ5I)s!jpxA~6A&D!q)yKgwZN&TImG((1d$B>0--M= z9BN%z+N4-LICggyF^u~oGT3n1cX0HIqX9pBsdM^K)_bi}?;d=*e?BJ=*x~3Qif3c4 zO4TDdVMve^D*~t4u z=Kqy{J;AIC^?CQ#rHpwFEAcU7>Zxc*YPD`i5@ziSHPOgQyzdx?nR!|txz2{Fj6@7` z7m?}3t#)ZN9SiOze{Oe8Pajm)c9*`qBj;;!ZZMk0nRf2pelP;yvoFvew_m~n{dxP5 zDYVyyzx(_4{|@Z)f4;kU_W0X=cya$&KfkQ~@bu=_|2n7yf|(osuqaZPgoaWDRnFcr zdI7rG^H2)_Ivp|S+DwU~)mA+m!)Sv69jlnkDFY{=*npFsf7vFV;EGnfl8mfUG)7;3 z^X=2a{i|1%KfSqs%%|^v`0C~vkX`Q{{PNmg*Y!=1IDny-6JT}vP7Kgn?<0n|cEs!J zaf$;WvQ~8_%dwWZOdxT?Fu zI~V|a(qScJf0Hm-NVel>GN>~*waqf(Y|XXYy3;u;0xVNTB;5+Li9loA2t7QxqrtJL zcVZO+sxl6aqJ2&870y%PJ=VV56z ``` +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) => ( + + )), + ] +}